Commit Graph

38742 Commits

Author SHA1 Message Date
Peter Steinberger
3f25f4b5fc fix(doctor): stop duplicating state schema migration labels (#108947)
* fix(doctor): distinguish state schema migrations

* fix(doctor): enforce migration formatter exhaustiveness

* docs(changelog): note state schema reporting fix

* docs(changelog): keep release note in PR body
2026-07-16 04:37:36 -07:00
Peter Steinberger
7c262eaae7 refactor(agents): simplify provider key normalization (#108950)
Co-authored-by: Pick-cat <huang.ting3@xydigit.com>
2026-07-16 04:36:15 -07:00
Peter Steinberger
990e8d24b0 feat(presentation): hosted-widget launch via typed web-app actions (#108927)
* feat(presentation): support hosted widget actions

* refactor(discord): route widget launches through presentation

* chore: keep changelog release-owned

* test(interactive): type the invalid web-app boundary case explicitly

* test: type web-app action fixtures against the split union

The two-member web-app union no longer accepts a distributed
type: "url" | "web-app" literal or an empty receipt in typed
callbacks; use explicit action casts and the Discord receipt factory.
2026-07-16 04:35:31 -07:00
krissding
eb8cdf6419 fix(cli): add 10s timeout to port-inspection subprocess calls (#108706)
* fix(cli): add 10s timeout to port-inspection subprocess calls

fuser, netstat, and lsof can hang on a busy or misbehaving system.
Node.js execFileSync already supports a timeout option; use 10s to
match the existing convention in debug-claude-usage.ts.

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

* fix(cli): harden port subprocess deadlines

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:33:58 -07:00
sunlit-deng
c4e696d1ba fix(vydra): ignore blank environment API key (#108757)
* fix(vydra): ignore blank environment API key

* refactor(tts): centralize speech API key resolution

* chore(plugin-sdk): refresh speech API baseline

* chore(plugin-sdk): pin speech resolver surface

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:33:25 -07:00
sunlit-deng
7b1f378720 fix(agents): decode only read bytes in bounded CLI session tails (#108072)
* fix(agents): decode only read bytes in bounded CLI session tails

* test(agents): keep Stats prototype in oversized-shrink stat mock

* fix(agents): import bounded file window reader for CLI history

* test(agents): reuse oversized CLI transcript fixture

* fix(agents): derive session tail offset from open file

* test(agents): track transcript race temp directory

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:32:26 -07:00
Peter Steinberger
203b8dbf0c fix(sessions): complete bounded positional read windows (#108941) 2026-07-16 04:30:06 -07:00
Peter Steinberger
68694599af fix(exec): resolve no-route approvals immediately (#108935)
Fixes #104413. Supersedes the implementation direction in #104923 after preserving its contributor work and extending route detection across approval clients.

Co-authored-by: RickLin <83101411+ObliviateRickLin@users.noreply.github.com>
2026-07-16 04:26:38 -07:00
Wynne668
f1f4b8ae8d fix: keep image attachments when steering active runs (#107657)
* fix: preserve images during active-run steering

* fix(codex): preserve steering fallback order

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* test(codex): satisfy strict steering assertions

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:23:03 -07:00
Peter Steinberger
122c6e4439 refactor(message): keep read fallback policy at call site (#108930) 2026-07-16 04:21:40 -07:00
qingminlong
71bea81669 fix(cli-runner): keep output tails utf8 safe (#108355)
* fix(cli-runner): keep output tails utf8 safe

* fix(cli-runner): satisfy output tail byte narrowing

* test(cli-runner): format utf8 tail regression

* refactor(cli-runner): reuse UTF-8 tail helper

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:20:38 -07:00
Peter Steinberger
f76a0158c8 refactor(gateway): centralize node pairing ownership checks (#108929) 2026-07-16 04:18:55 -07:00
Peter Steinberger
0d31fbf5f0 fix(skills): canonical frontmatter parser + per-file diagnostics (#108926)
* fix(skills): load JSON5-style metadata frontmatter

* fix(skills): diagnose invalid frontmatter

* test(skills): adapt session loader coverage

* ci: refresh merge ref

---------

Co-authored-by: jincheng-xydt <xu.jincheng@xydigit.com>
2026-07-16 04:18:06 -07:00
Vito Cappello
92075dd72a fix(secrets): inactive web refs no longer block agent turns (#108485)
* fix(secrets): accept inactive refs from partial fallback

* fix(secrets): fail closed on unknown web provider owners

* test(gateway): isolate web secret startup fixtures

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:13:40 -07:00
Peter Steinberger
d5eebf02e2 fix(workboard): record resolved runtime metadata instead of hardcoded codex engine (#108887)
* fix(workboard): record resolved runtime metadata instead of hardcoded codex engine

Workboard executions labeled every dispatched run engine=codex, model=default,
and id suffix :codex even for Claude/other harness agents. The gateway agent
admission phase now returns the resolved {harness, provider, model} for plugin
subagent runs; the dispatcher records it verbatim and omits engine/model when
unresolved. Engine becomes an open runtime identifier in the workboard
contract (built-in launch choices stay a closed list), store/UI normalizers
preserve historical labels as written instead of inventing codex, and new
execution ids use an :agent-session suffix. Fixes #108362

* fix(workboard): accept undefined engine in ui engineModel helper
2026-07-16 04:10:27 -07:00
Alix-007
0ca1d23517 fix(sandbox): keep CDP probes within startup deadline (#108670)
* fix(sandbox): bound CDP probes to startup deadline

* test(sandbox): prove stalled CDP deadline

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:05:18 -07:00
Peter Steinberger
66604df9b6 refactor(channels): share retry helpers and remove dead state probes (#108903)
* refactor(channels): generalize channel retry runner and retry-after parsing; drop dead configured-state probes

* fix(channels): align retry and metadata contracts
2026-07-16 04:03:15 -07:00
Yuval Dinodia
d15d3e17ec fix(gateway): scope node pairing management to caller device (#104989)
Apply the existing device-token ownership rule to node pairing list, approve, reject, and rename. Preserve shared-auth, admin, and self-service management while preventing cross-device enumeration and mutation.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:58:11 -07:00
Peter Steinberger
6f8c759b4c refactor(cron): share task history timestamp (#108914) 2026-07-16 03:55:39 -07:00
qingminlong
b1e814f57a fix(docs): report malformed search JSON with CLI context (#108364)
* fix(docs): report malformed search JSON with CLI context

* test(docs): tighten malformed response assertion

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:51:52 -07:00
Wynne668
b7e099d36e fix(gateway): agent model overrides cannot be cleared (#108734)
* fix(gateway): allow clearing agent model overrides

* fix(protocol): preserve Swift agent model compatibility

* fix(protocol): preserve null when Swift decodes agent updates

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:46:37 -07:00
Peter Steinberger
f180638e87 test(docker): extract setup harness (#108797) 2026-07-16 03:44:17 -07:00
Alix-007
1ae12955f3 fix(docker): bound Docker GPG key download (#108894) 2026-07-16 03:42:07 -07:00
Eden
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
Eden
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
Nik
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
Hosan
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 Steinberger
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
xingzhou
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
Shubhankar Tripathy
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
wuqxuan
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
Jason (Json)
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
mushuiyu886
4b9c78a674 fix(cron): preserve same-id history across stores (#108730) 2026-07-16 03:28:11 -07:00
Monkey-wusky
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 Steinberger
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
pick-cat
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
dongdong
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
Alix-007
00be90dae7 fix(sandbox): bound common installer downloads (#108805) 2026-07-16 03:18:02 -07:00
Peter Steinberger
49f7749223 fix(sandbox): stabilize remote hardlink checks (#108879) 2026-07-16 03:17:41 -07:00
Peter Steinberger
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
Peter Steinberger
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
zhanxingxin1998
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
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
Josh Avant
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
Abner Shang
5ad0d4d6c0 fix: avoid false restart failure during startup migrations (#105544)
* fix: wait for startup migrations on restart

* fix: honor restart readiness caller context

* fix: preserve restart service identity

* fix: refresh readiness context after repair

* fix: bound migration restart wait by wall clock

Co-authored-by: Abner Shang <abner.shang@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:04:49 -07:00
RileyJJY
b5377757d7 fix(agents): cap aggregate pressure warning dedupe cache with LRU eviction (#108667)
* fix(agents): cap aggregate pressure warning dedupe cache with LRU eviction

* fix(agents): bound tool-result warning dedupe

* fix(agents): keep warning cache limit internal

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:02:52 -07:00
loong954
804de49dda fix: prevent stale plugin installs from blocking lifecycle commands (#107691)
* fix(plugins): handle ENOTDIR gracefully in npm-project-roots

The listManagedPluginNpmProjectRootsSync and listManagedPluginNpmProjectRoots
functions only caught ENOENT errors when reading the projects directory,
but an ENOTDIR error (when a file path is mistakenly used as a directory)
would propagate unhandled and crash the CLI.

Replace the local isMissing helper with the shared isNotFoundPathError from
infra/path-guards.ts, which already covers both ENOENT and ENOTDIR.

Fixes #107467

* test(plugins): use managed temp directory fixture

* chore: keep release notes out of contributor PR

* fix(plugins): restore not-found path guard export

* fix(plugins): normalize Windows managed install paths

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-16 01:59:48 -07:00
Peter Steinberger
723d12fd4c refactor(apns): move registrations to shared SQLite (#108543)
* refactor(apns): move registrations to SQLite

* fix(apns): satisfy strict migration typing

* chore(apns): remove obsolete lint suppression

* chore: prune APNs max-lines baseline

* refactor(apns): keep store internals private

* fix(apns): preserve stored relay origins

* fix(apns): advance versions across deletion

* fix(apns): harden legacy state import

* fix(apns): redact legacy import errors

* fix(apns): reserve version successor

* fix(apns): bound legacy timestamp imports

* refactor(apns): extract payload builders
2026-07-16 01:52:15 -07:00
zengLingbiao
c2b73a0a01 fix(envelope): accept timestamp 0 in formatEnvelopeTimestamp (#106407)
* fix(envelope): accept timestamp 0 in formatEnvelopeTimestamp

formatEnvelopeTimestamp used if (!ts) to check for missing timestamps,
which incorrectly rejected the valid numeric timestamp 0 (Unix epoch).
Replace the falsy check with an explicit undefined/null check so 0 is
treated as a valid timestamp value.

* refactor(auto-reply): tighten epoch timestamp fix

Exercise the public envelope path with an exact epoch result and keep the missing-value guard aligned with its declared input type.

Co-authored-by: zenglingbiao <zeng.lingbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:50:08 -07:00