Commit Graph
69200 Commits
Author SHA1 Message Date
Alix-007andGitHub 1ae12955f3 fix(docker): bound Docker GPG key download (#108894) 2026-07-16 03:42:07 -07:00
60987aa96d fix(qa-channel): bound stalled bus requests (#108684)
* fix(qa-channel): bound stalled bus requests

* test(qa-channel): cover stalled bus response bodies

* test(qa-channel): make stalled-body timeout deterministic

* style(qa-channel): format timeout regression

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:41:51 -07:00
e0ffbd90d9 fix(ci): isolate bounded metadata retries (#108804)
* fix(ci): bound Mantis runner IP retries

* fix(e2e): isolate Windows metadata retries

* fix(ci): validate complete runner IPv4

Co-authored-by: Alix-007 <li.long15@xydigit.com>

---------

Co-authored-by: Alix-007 <li.long15@xydigit.com>
2026-07-16 03:39:31 -07:00
d572c5cb2d fix(line): run post-ack webhook processing on its own admitted work root (#107734)
* fix(line): run post-ack webhook processing on its own admitted work root

LINE acks the webhook and dispatches event processing fire-and-forget on
the same async chain. The HTTP request admission that chain inherited is
released as soon as the route handler returns, and a released admission
refuses subordinate queue work - so every LINE inbound agent turn fails
with "GatewayDrainingError: Gateway is draining; new tasks are not
accepted" even though the gateway is healthy. DMs, group mentions, and
postbacks are all affected; the user-visible symptom is the bot replying
"Sorry, I encountered an error processing your message." to everything.

Add runDetachedWebhookWork to the plugin-sdk webhook-request-guards
surface (a thin wrapper over the gateway independent-root continuation,
the same shape core uses in gateway/server/hooks.ts) and route all three
LINE ack-first dispatch sites through it: the gateway monitor handler
(the live path), and the createLineNodeWebhookHandler / Express
middleware handlers (public webhook building blocks an embedder can
register under the gateway). #65375 unified these three into one ack-first
pattern; keeping the detach consistent avoids re-introducing the same
latent defect in the two that are not on the live gateway path today.

The continuation is reserved synchronously while the request is still
admitted, so the detached processing stays accepted and a real restart
drain can wait for it instead of stranding it mid-turn.

Tests pin every layer: the guards suite proves detached post-ack work is
admitted after the request admission is released (and that the inherited
chain without the helper is refused); the monitor lifecycle suite and the
webhook-node suite assert each dispatch site goes through the detached
root. Red/green verified: reverting any dispatch fails its test.

* fix(plugin-sdk): account for runDetachedWebhookWork in public surface budget

* fix(channels): track detached webhook processing

Co-authored-by: 許元豪 <146086744+edenfunf@users.noreply.github.com>

* docs: refresh generated docs map

* chore(plugin-sdk): refresh API baseline

* fix(webhooks): preserve post-ack ordering

* test(plugin-sdk): satisfy detached work lint

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:39:02 -07:00
Peter SteinbergerandGitHub b6b8e59b9e refactor(ci): share Android toolchain setup (#108855)
* refactor(ci): share Android toolchain setup

* fix(ci): preserve frozen Android targets
2026-07-16 03:38:31 -07:00
80de877ed3 fix(line): support /allowlist config edits (#106638)
* feat(line): wire base.allowlist config-edit adapter

LINE was the only DM/group channel without a base.allowlist adapter, so
`openclaw allow line` / the /allowlist command replied "does not support"
instead of editing the LINE allowlist. Reuse buildDmGroupAccountAllowlistAdapter
(DM + group + per-group-override scopes), matching Telegram/Signal; entry
normalization flows through the existing lineConfigAdapter.formatAllowFrom.

* fix(allowlist): preserve inherited account entries

* fix(allowlist): preserve all-scope store edits

Co-authored-by: Eden <146086744+edenfunf@users.noreply.github.com>

* test(allowlist): import config type

Co-authored-by: Eden <146086744+edenfunf@users.noreply.github.com>

* fix(allowlist): preserve empty effective overrides

Co-authored-by: Eden <146086744+edenfunf@users.noreply.github.com>

* fix(allowlist): reject group-only store edits

Co-authored-by: Eden <146086744+edenfunf@users.noreply.github.com>

* fix(allowlist): preserve cleared channel overrides

Co-authored-by: Eden <146086744+edenfunf@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:38:13 -07:00
NikandGitHub 3f819ab0cc fix(embedded-runner): clear tool-search catalog when a run aborts during prep (#108114)
* fix(embedded-runner): clear tool-search catalog when a run aborts during prep

* fix(embedded-runner): point catalog test at relocated tool-search test api
2026-07-16 13:37:32 +03:00
Peter SteinbergerandGitHub 2c7cf8d745 perf(ci): scale Vitest workers with runner class and share serial module cache (#108788)
* perf(ci): scale Vitest workers with runner class and share serial module cache

Compact node-test jobs pinned OPENCLAW_VITEST_MAX_WORKERS=2 regardless of
runner size, so import-bound suites (30-45s of module-graph import per
file) crawled: runner-cli spent 284s on 5s of tests, commands-1 296s on
10s. With serial plans the budget now scales with the class (6 on 8vcpu,
3 on 4vcpu); timing-sensitive groups (tooling, tui-pty, infra-process)
stay pinned to 2 via plan-level env. Serial bins share one Vitest
fs-module-cache path so later plans reuse the first plan's transforms.
The import-bound commands stripes and security suite move to the 8vcpu
class, and packing hints refresh from serial-run measurements (run
29481835688).

* perf(ci): stripe cli-runner suite and pin media-ui worker budget

The agents-core config runs files serially (fileParallelism false guards
shared module state), so raising the worker budget cannot help its
import-heavy cli-runner suite (~35s module import per file, 213s serial).
Stripe it three ways so bins parallelize the imports instead. media-ui
hosts browser locator tests that timed out at 6 workers on the first
validation run; pin it to the proven 2-worker budget. commands-1's hint
drops to its measured 6-worker runtime.
2026-07-16 03:36:37 -07:00
7bc43f50b7 fix(message): reject invalid read targets without fallback (#108637)
* fix(message): fail closed on invalid read targets

* fix(message): scope read channel validation

* fix(message): fail closed on explicit read scope

---------

Co-authored-by: Hosan <200961079+hosanxiv@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:36:32 -07:00
Peter SteinbergerandGitHub e95577ded7 fix(e2e): bound macOS Discord host requests (#108880) 2026-07-16 03:36:20 -07:00
dacf164793 fix(gateway-client): bound websocket opening handshake waits (#108348)
* fix(gateway-client): bound websocket opening handshake waits

* test(gateway-client): harden handshake timeout proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:36:17 -07:00
Peter SteinbergerandGitHub 5d9c114fa6 fix: keep isolated gateways quiet and Codex terminals interactive (#108871)
* fix(gateway): harden session recovery paths

* fix(terminal): normalize padded TERM values

* chore: defer gateway release notes

* test(terminal): type TERM test environments
2026-07-16 03:35:17 -07:00
c7f58f5bed fix(gateway): suppress MCP notification responses (#101730)
* fix(gateway): suppress mcp notification responses

* fix(gateway): MCP clients receive responses for JSON-RPC notifications

* Handle MCP lifecycle notifications before tool resolution

* Filter notification entries from internal-error batches

* fix(gateway): centralize MCP response eligibility

Co-authored-by: 张贵萍0668001030 <zhang.guiping@xydigit.com>

* test(gateway): use public MCP loopback helper

Co-authored-by: 张贵萍0668001030 <zhang.guiping@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:34:01 -07:00
0497148458 fix(acpx): stop creating empty stderr logs (#106799)
* fix(acpx): avoid empty stderr log files

* fix(acpx): clear stale stderr logs before launch

* test(acpx): keep stderr cleanup best effort

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:33:11 -07:00
6390edec25 fix(memory-lancedb): prevent cross-agent memory leakage (#103799)
* fix(memory-lancedb): gate auto-recall and auto-capture on per-agent memorySearch.enabled (#103590)

The before_prompt_build auto-recall hook only checked the plugin-level
autoRecall flag, so agents configured with memorySearch.enabled: false
still received <relevant-memories> injected from the shared LanceDB store
- leaking one agent's private memories into another agent's prompts. Gate
both recall injection and agent_end auto-capture on the current agent's
memorySearch.enabled (per-agent entry wins over agents.defaults; unset
means enabled), mirroring core resolveMemorySearchConfig semantics.

* fix(memory-lancedb): normalize agent ids before the memorySearch gate

Review follow-up on #103799: a configured id like 'XiaoHuo' or one with
surrounding whitespace missed the exact-match per-agent override and
inherited the enabled default, leaving the disclosure path active.
Normalize both the hook agent id and configured entry ids with the SDK
normalizeAgentId before comparing.

* fix(memory-lancedb): resolve the per-agent memorySearch gate via resolveAgentConfig

* fix(memory): isolate LanceDB rows by agent

Co-authored-by: Shubhankar Tripathy <reach2shubhankar@gmail.com>

* fix(memory): isolate LanceDB rows by agent

Co-authored-by: Shubhankar Tripathy <reach2shubhankar@gmail.com>

* refactor(memory): keep LanceDB store types private

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:33:08 -07:00
045a02b7ad fix(codex): make status context freshness truthful (#107813)
* fix(codex): project absolute thread tokenUsage into attemptUsage (#107324)

* fix(codex): keep thread totalUsage off per-attempt fields

* fix(codex): make status context freshness truthful

Co-authored-by: wuqingxuan <wu.qingxuan@xydigit.com>

* fix(codex): preserve usage through timeout recovery

Co-authored-by: wuqingxuan <wu.qingxuan@xydigit.com>

---------

Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:32:08 -07:00
73980e7e42 fix(codex): remove duplicate provider setup choice (#107979)
* fix(codex): stop advertising harness as model provider

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(wizard): keep migration plugins out of optional setup

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:31:11 -07:00
f444dfafc5 fix(line): avoid exposing media URLs in errors (#108657)
* fix(line): avoid exposing media URLs in errors

* test(line): cover media URL redaction paths

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:28:40 -07:00
mushuiyu886andGitHub 4b9c78a674 fix(cron): preserve same-id history across stores (#108730) 2026-07-16 03:28:11 -07:00
Alix-007andGitHub de10d98c81 fix(e2e): bound OpenShell installer fetch (#108810) 2026-07-16 03:27:03 -07:00
Peter SteinbergerandGitHub 2488d794ca feat(ui): expand child sessions in sidebar (#108838)
* feat(ui): expand child sessions in sidebar

* test(ui): type child session list options

* refactor(ui): split child session data helpers

* fix(ui): preserve session link semantics

* fix(ui): retry incomplete child session loads

* chore: keep release changelog owner-only
2026-07-16 03:26:49 -07:00
7a3c26b509 fix(codex): preserve subagent completions after sessions_yield (#105724)
* fix(codex): preserve subagent completions across sessions_yield

* fix(codex): confirm steering delivery before yield

Co-authored-by: Alexis Gallagher <alexis@alexisgallagher.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:26:33 -07:00
8ebb1d2aec fix(sessions): complete tail-read windows despite short positional reads (#108655)
* fix(sessions): complete tail-read windows despite short positional reads

Replace single-shot handle.read() calls in two session tail-read
paths with readFileWindowFully so multibyte-range positional reads
do not silently return incomplete tail data on network filesystems.

- readRecentTranscriptTailLinesAsync: tail-window read for recent
  session messages now loops until the requested window fills
- readLastMessagePreviewFromOpenTranscriptAsync: last-message
  preview tail read now loops until the requested window fills

The same readFileWindowFully helper was introduced in #108253 and
expanded with a sync variant in #108127 (both by sunlit-deng).

* fix(sessions): complete sync title preview reads

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:25:55 -07:00
Peter Steinberger 3280a0df9a test(retry): port negative matrix for provider-wrapped statuses
Ports the unique coverage from #108126 onto the parser landed via #106850:
wrapped 401/403/404 and quota-exhausted 429 stay non-retryable, an
envelope embedded in user text is ignored, and a short-window wrapped
429 retries. Credit @zhanxingxin1998.
2026-07-16 11:22:13 +01:00
Peter SteinbergerandGitHub 76a236da5f fix(ci): harden release validation gates (#108798)
* fix(ci): harden release validation gates

* fix(apns): keep tombstones in strict SQLite schema

* fix(ci): isolate PR publication transport
2026-07-16 03:21:08 -07:00
60040d86b2 fix: normalize provider keys during model config merge (#95722)
* fix: normalize provider keys during model config merge

* fix: normalize source-managed provider keys when reapplying secret markers

Make enforceSourceManagedProviderSecrets canonicalize provider keys with
normalizeProviderId so mixed-case (e.g. "OpenAI") source config still matches
the canonical "openai" generated provider. Without this, the trim-only source
lookup misses, the source SecretRef marker is never reapplied, and resolved
runtime secret values leak into generated models.json.

Adds plan-level regressions in models-config.runtime-source-snapshot.test.ts
covering mixed-case apiKey and header source configs.

* fix: use Array#toSorted in mixed-case provider regression tests

oxlint(no-array-sort) flagged the new test assertions for using
.sort() on Object.keys(...). Switch to .toSorted() to keep the
check-lint shard green.

* style(agents): oxfmt models-config provider merge files

* fix(agents): define provider key collision precedence

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-16 03:20:20 -07:00
Peter Steinberger 8dd204e4fc fix(installer): retry transient Windows npm failures 2026-07-16 11:19:41 +01:00
a88ff7a6ba fix: show config mutations in migrate text previews (#108556)
* fix: show config items in migrate text preview

* test(migrate): protect config preview redaction

Co-authored-by: JasmineZhangHM <277513763+JasmineZhangHM@users.noreply.github.com>

---------

Co-authored-by: JasmineZhangHM <277513763+JasmineZhangHM@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:19:01 -07:00
67699ddd82 fix(browser): do not sticky-adopt policy-blocked openTab targets (#105301)
* fix(browser): do not sticky-adopt policy-blocked openTab targets

* test(browser): narrow sticky redirect proof

Co-authored-by: NIO <hu.genshen@xydigit.com>

* fix(browser): validate tab adoption after navigation

Co-authored-by: NIO <hu.genshen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:18:27 -07:00
Alix-007andGitHub 00be90dae7 fix(sandbox): bound common installer downloads (#108805) 2026-07-16 03:18:02 -07:00
Peter SteinbergerandGitHub f89c624ebb fix(reef): bound inbox WebSocket frames (#108886) 2026-07-16 03:17:52 -07:00
Peter SteinbergerandGitHub 49f7749223 fix(sandbox): stabilize remote hardlink checks (#108879) 2026-07-16 03:17:41 -07:00
8090cb1c64 fix(discord): honor abortSignal during gateway READY retry backoff (#108561)
* fix(discord): honor abortSignal during gateway READY retry backoff

* fix(discord): avoid __testing alias to satisfy Knip production scan

* test(discord): make READY abort proof deterministic

Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>

* fix(retry): support unref abort sleeps

Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:14:46 -07:00
Peter SteinbergerandGitHub 27065a65b7 fix(scripts): survive pr worktree teardown in lock release and self-heal stale registrations (#108870) 2026-07-16 03:13:44 -07:00
Peter SteinbergerandGitHub 05c2701e3d refactor(plugin-sdk): share widget HTML validation helpers (#108807)
* refactor(plugin-sdk): add widget HTML helpers

* refactor(plugins): share widget HTML validation
2026-07-16 03:13:29 -07:00
Alix-007andGitHub e3e071f8c1 fix(installer): bound PowerShell download stalls (#108791) 2026-07-16 03:13:26 -07:00
Peter SteinbergerandGitHub 5bb905caa8 test(state): cover APNs STRICT repair (#108875)
* fix(state): mark APNs tombstones strict

* chore: remove manual changelog entry
2026-07-16 03:04:46 -07:00
Peter Steinberger 8f1760b667 test(discord): restore OpenClawConfig type import in channel.policies.test.ts
The max-lines split dropped the type-only import that two casts still
use, failing check-test-types.
2026-07-16 02:54:06 -07:00
4bc84db398 fix(cron): allow clearing failure alert routing fields (#108578)
* fix(cron): clear failure alert routing fields

Send explicit nulls for cleared Control UI failure-alert overrides and accept those clears only in cron update patches.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cron): satisfy serialized alert patch types

Narrow the serialized failure-alert fixture before asserting its cleared fields.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cron): clear failure alert overrides

Co-authored-by: 詹幸心0668001037 <zhan.xingxin@xydigit.com>

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:52:19 -07:00
df72216580 fix(onepassword): reject oversized service account token files (#108596)
* fix(onepassword): reject oversized service account token files

* fix(onepassword): clarify oversized token errors

Co-authored-by: wahaha1223 <0668001153@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:48:49 -07:00
Peter SteinbergerandGitHub b28070543a test(discord): split channel target resolver tests (#108857) 2026-07-16 02:48:15 -07:00
Peter SteinbergerandGitHub 06795a669b test(discord): extract mock call helpers (#108853) 2026-07-16 02:47:30 -07:00
Peter SteinbergerandGitHub e4f4b93b10 feat(mac): playful hard-hat working mascot during setup and updates (#108735)
* feat(mac): playful hard-hat working mascot during setup and updates

The mascot gets a new .working mood: it dons a safety hard hat, hammers
away with impact sparks while setup work is in flight, and pauses every
few seconds to wipe its brow. Used on the onboarding "Getting things
ready" page and the post-update window instead of the generic thinking
mood. Lives in shared OpenClawKit so iOS can adopt it too.

* chore(i18n): refresh native inventory line for mascot view
2026-07-16 02:45:19 -07:00
Peter Steinberger b8c1ab1979 test(discord): split channel policy describes out of channel.test.ts
channel.test.ts crossed the max-lines lint budget (1002 > 1000) after
#108584; move the mock-free bindings/security/groups describes into
channel.policies.test.ts instead of suppressing.
2026-07-16 02:42:32 -07:00
Peter SteinbergerandGitHub 91f57a3159 fix(clawrouter): normalize Perplexity tool schemas and harden dynamic model cache (#108758) 2026-07-16 02:39:33 -07:00
Peter Steinberger f5bb19e028 fix(state): make apns_registration_tombstones STRICT
The canonical schema gate rejects non-STRICT tables, failing every
gateway-suite shard since #108543 added the tombstones table without
STRICT. Align it with every sibling table and regenerate the schema
mirror.
2026-07-16 02:28:29 -07:00
Peter Steinberger 57ae43a89c fix(ci): harden full release validation 2026-07-16 10:26:29 +01:00
Josh AvantandGitHub e322edccfa fix(discord): resolve named agent delivery targets (#108584)
* fix(discord): resolve agent delivery targets

* fix(outbound): preserve heuristic target fallback

* fix(outbound): keep delivery helpers private
2026-07-16 02:13:10 -07:00
5c1857fc55 fix(android): stop killing long chat runs with hardcoded timeouts (#106863) (#106864)
* fix(android): stop killing long chat runs with hardcoded timeouts

Two independent timeouts made any agent turn longer than ~2 minutes fail
when started from the Android app, while the same turn worked over
Telegram (#106863):

- chat.send hardcoded timeoutMs=30000, which the gateway turns into the
  server-side run expiry; the maintenance sweep then aborts longer runs
  ("CLI run aborted" / "Embedded agent failed before reply"). Omit the
  override so app runs get the configured default like other channels.

- armPendingRunTimeout declared a timeout after 120s even when the
  refreshed history snapshot confirmed the run was still in flight,
  showing a spurious error and dropping the optimistic bubble mid-run.
  Re-arm the timer in that case; terminal events and the server-side
  expiry remain the liveness backstop.

Fixes #106863

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

* chore(i18n): sync native inventory after ChatController line shifts

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

* test(android): run ChatController on backgroundScope in reconnect tests

The pending-run watchdog now re-arms while a run is confirmed in flight,
so reconnect scenarios that end with a restored in-flight run keep a
timer coroutine alive. Launch the controller on runTest's
backgroundScope so that timer is cancelled at test end instead of
failing the suite with UncompletedCoroutinesError.

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

* fix(android): bound pending-run watchdog recovery

Distinguish applied, superseded, and failed history refreshes so recovered runs neither expire during a newer authoritative load nor rearm forever after refresh failure.

Co-authored-by: Léandre Chamberland-Dozois <lchamberland-dozois@hotmail.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:12:45 -07:00
Alix-007andGitHub 47dd90c5ea fix(ci): bound Android SDK downloads (#108723) 2026-07-16 02:12:07 -07:00