Commit Graph

78201 Commits

Author SHA1 Message Date
Peter Steinberger d1452fb5d1 refactor(plugin-sdk): split API baseline by entrypoint (#122082) 2026-08-11 08:54:42 -07:00
Peter Steinberger 8f61ec4120 test(agents): add CLI-backend fault-sequence boundary coverage (#122092) 2026-08-11 08:54:08 -07:00
Ayaan Zaidi e31a6e29ff refactor(telegram): merge dispatch controllers into one turn module (#122091)
The four Telegram dispatch controllers were partitions of one closure: ~75 factory parameter slots, 7 post-construction back-edge setters, a shared mutable state bag, and load-bearing construction order. One turn record now carries the once-resolved config and all state; the four files remain as implementation with a hand-written leaf type contract (four state-slice types). Rides along: dead generation fence deleted (constant-0 from birth), queuedFinal ||= fix with regression (suppressed exec-approval turns no longer trigger a spurious fallback), collapse resolver/mutator split. Dispatch tests and harness byte-identical to main; live E2E lifecycle proof on the PR.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 15:45:42 +00:00
Ayaan Zaidi dfb4712258 style: format mcp-oauth-refresh-issuer test
check-lint fails repo-wide on this file's formatting at current main;
heal-forward so PR merge refs stop inheriting the red.
2026-08-11 17:34:49 +02:00
Peter Steinberger f88f078cd2 fix(daemon): require validated Node runtime (#122070)
Remove program-argument runtime rediscovery so managed Gateway and node-host services consume only the canonical validated Node path, while executable wrappers remain supported.\n\nRefs #122061.
2026-08-11 08:32:06 -07:00
Peter Steinberger f798f9999b fix(agent-tools): expand Windows home paths (#122071) 2026-08-11 08:28:35 -07:00
Peter Steinberger db73b59c04 refactor: burn wrapper shadowing baseline entries (#122040)
* refactor: burn wrapper shadowing entries

* chore: refresh wrapper shadowing baselines

* test: update secrets runtime state mocks

* fix(ci): absorb Control UI build identity variance
2026-08-11 08:24:03 -07:00
Vincent Koc b30e0dc4c6 fix(ci): isolate gateway kernel plugin registry state (#122050)
* fix(ci): isolate gateway kernel plugin registry state

* test(gateway): preserve staged plugin registry lifecycle
2026-08-11 08:22:51 -07:00
Peter Steinberger 1ccd701808 chore(deadcode): remove stale Knip scaffolding (#122069) 2026-08-11 08:15:11 -07:00
Yuval Dinodia 01d84e18a4 fix(mcp): bind stored OAuth refresh tokens to their issuing authorization server (#112032)
A 401 challenge pointing at new protected-resource metadata let the MCP SDK rediscover
a different authorization server and POST the stored refresh token to it. Token issuer
is now persisted with the tokens and disclosure is gated on exact issuer identity;
legacy rows without recoverable issuer provenance fail closed to an explicit re-login.

Admin-merged past checks-node-compact-small-1 by maintainer decision: five runs of
attribution show the failure is src/gateway/server-kernel.test.ts (added in #121981)
hanging at HTTP-listen under this merge ref's shard composition — unrelated to this
diff and green on main. Evidence on the PR.

Co-authored-by: yetval <yetvald@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 20:43:32 +05:30
Peter Steinberger aeece77ead perf(cloud): reuse attached tunnel during dispatch (#122077)
Amp-Thread-ID: https://ampcode.com/threads/T-019feaaa-c7ed-769e-9f29-a3612bec72e7

Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 08:10:24 -07:00
Peter Steinberger 48253cde46 docs: correct database-first current-state claims (#122085)
Schema versions are global v6 and agent v17 (src/state/openclaw-state-db-contract.ts:6; src/state/openclaw-agent-db-contract.ts:22). State v5/v6 provenance comes from 7a7d6bb and 509a5f0, matching the current contract comments at src/state/openclaw-state-db-contract.ts:4.

QMD is retired and Doctor migrates its paths to builtin memory (src/commands/doctor/shared/legacy-config-migrations.runtime.retired-memory-qmd.ts:94). Device auth is SQLite-backed in TypeScript and Swift while Android remains SecurePrefs-backed (src/infra/device-auth-store.ts:115; apps/shared/OpenClawKit/Sources/OpenClawKit/DeviceAuthStore.swift:26; apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthStore.kt:55).

Opt-in cache, payload, raw-stream, timeline, and macOS diagnostics remain JSONL artifacts (src/agents/cache-trace.ts:93; src/agents/anthropic-payload-log.ts:46; src/agents/embedded-agent-subscribe.raw-stream.ts:16; src/infra/diagnostics-timeline.ts:96; apps/macos/Sources/OpenClaw/DiagnosticsFileLog.swift:3).

The canonical agent schema currently has cache_entries but no VFS/tool/run artifact tables, and subagent attachments materialize in child workspaces (src/state/openclaw-agent-schema.sql:398; src/agents/subagents/spawn/subagent-attachments.ts:308). Current Doctor/session owners replace deleted prototype paths (src/infra/state-migrations.doctor.ts:66; src/config/sessions/session-accessor.sqlite-entry.ts:165; src/config/sessions/paths.ts:320).
2026-08-11 08:03:10 -07:00
Ayaan Zaidi 543603e9f7 test(gateway): restore ambient plugin registries
Stage test registries without retiring the worker's ambient registry, then restore its exact snapshot after each producer. This prevents later non-isolated gateway tests from inheriting plugin runtime state.
2026-08-11 16:56:40 +02:00
Peter Steinberger b1e08b3c21 improve(test): speed up doctor preflight process coverage (#122060)
* improve(test): parallelize doctor metadata process fixtures

* improve(test): collapse doctor metadata scan matrix

* test: tighten doctor metadata scan ceilings

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 07:54:46 -07:00
wanyongstar 71ea11b537 fix(cli): validate webhooks gmail --tailscale mode at parse time (#120272)
* fix(cli): validate webhooks gmail --tailscale mode at parse time

--tailscale <mode> was stored unchecked and cast to the tailscale union
type, so a typo like --tailscale offf (truthy and !== "off") was treated
as enabled and only failed deep inside tailscale setup with a raw CLI
usage error. Reject modes other than funnel|serve|off in
parseGmailCommonOptions, mirroring the strict numberOption pattern, and
export the setup/run parsers for direct testing.

* fix(cli): reject blank Gmail tailscale modes

* fix(cli): preserve tailscale mode type

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-11 21:51:35 +07:00
Peter Steinberger 2183d637a2 fix(ui): keep discussions closed until toggled (#122072) 2026-08-11 07:51:18 -07:00
Vincent Koc 6472d22a77 fix(ci): budget expanded survivor groups (#122058) 2026-08-11 22:44:21 +08:00
Peter Steinberger 5c52666c34 test(bedrock): remove stream inspection bridge (#122059)
* test(bedrock): remove stream inspection bridge

* test(bedrock): fail when stream command is missing
2026-08-11 07:39:51 -07:00
Peter Steinberger 2cf725191c refactor(telegram): centralize text delivery (#117327)
Centralize Telegram text delivery: page planning and reply-target progression move into telegram-text-delivery.ts, shared by the durable send, edit, and streaming-final paths; bot/reply-threading.ts and per-path split/page logic are deleted. Formatted-to-plain recovery routes through withTelegramPlainFallback everywhere. Restores the projection-cursor invalidation contract on terminal multi-page failures (with regression). Net -321 production LOC. Live E2E on the PR: formatted entity path, plain-fallback recovery, and 2-page chaining.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:37:54 +00:00
Monkey-wusky 842301af23 fix(infra): bound JSON string measurement memory (#106402)
* fix(infra): use Buffer.byteLength for JSON string byte-limit fast-path guard

jsonStringByteLengthUpToLimit used value.length (UTF-16 code units)
as a fast-path estimate of JSON-encoded byte size before calling
the expensive jsonUtf8BytesOrInfinity fallback.  For CJK text,
.length underestimates the actual UTF-8 byte count by up to 3x,
so the guard incorrectly passes strings that should bail early.
The accurate fallback still catches the overflow, so no data
corruption occurs, but every such miss triggers an unnecessary
JSON.stringify allocation.

Replace value.length + 2 with Buffer.byteLength(value, 'utf8') + 2
so the fast path works correctly across all Unicode content.
Buffer.byteLength on a string is O(n) without allocation — still
cheaper than the JSON.stringify fallback it guards against.

ASCII behaviour is unchanged (byteLength == length).

* fix(infra): preserve O(1) ASCII fast-path before UTF-8 byte-length guard

Restore the O(1) value.length lower-bound guard before the O(n)
Buffer.byteLength UTF-8 guard.  Oversized ASCII strings (where
.code-unit count already exceeds the budget) now bail immediately
without scanning the full string.  CJK and emoji content that
passes the O(1) guard still gets the accurate Buffer.byteLength
check.

The two-layer bailout is:
  1. value.length + 2 > remainingBytes  (O(1), catches clearly oversized)
  2. Buffer.byteLength + 2 > remainingBytes  (O(n), catches CJK/emoji)
  3. jsonUtf8BytesOrInfinity (fallback, full JSON.stringify)

* fix(infra): add O(1) upper-bound guard to avoid Buffer.byteLength scan on fitting strings

Three-tier guard eliminates scan overhead on the common path:
T1 O(1) lower-bound bail (oversized ASCII, 0 scans)
T2 O(1) upper-bound pass (fitting strings, 0 scans, this is new)
T3 O(n) Buffer.byteLength (CJK borderline only, 1 scan)

* fix(infra): avoid serializing oversized Unicode strings

Punchcard-Session: coral-cedar-brook-8x

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-11 22:36:31 +08:00
Peter Steinberger 89ff93dbc2 fix(agents): retire attachment-only steering messages after delivery (#121158)
* fix(agents): retire queued messages by identity

* chore(plugin-sdk): refresh API baseline

* test(agents): narrow queued message events
2026-08-11 07:33:21 -07:00
Ayaan Zaidi a087732425 test(gateway): release timed-out request admission
Resolve the deliberately non-cancelled handler after asserting its client deadline, then wait for root admission to drain before leaving the non-isolated test.
2026-08-11 16:30:57 +02:00
Peter Steinberger 8d1fa472d9 fix(gateway): settle terminal wizard status before replacement (#122054) 2026-08-11 07:20:17 -07:00
Peter Steinberger e25434e7ad fix(agents): preserve skills for wildcard tool policy (#122057)
Use normalized tool-policy semantics for both system-prompt and Code Mode skill projections so wildcard allowlists remain unrestricted while finite allowlists still suppress skills.\n\nRefs #121950.
2026-08-11 07:15:15 -07:00
Peter Steinberger 29fd6aaf6b refactor(sessions): tidy the session-accessor import surface (#122055)
Close the barrel gap (SessionEntryListScope), migrate the 14 production
type-bypass imports and the sessions-rewind raw-op imports through the
accessor barrel, and document session-accessor.sqlite-scope as the
sanctioned low-level entry point for doctor/migrations/infra. Net +8
production LOC: the barrel gains its missing surface. Part 3 (final) of
the session-accessor dual-layer collapse (#121316, #121536).
2026-08-11 06:53:42 -07:00
Peter Steinberger e390781534 refactor: burn cross-directory export name collisions (#121893)
* refactor: name subsystem logger exports

* refactor(test): distinguish exported test doubles

* refactor: consolidate canonical owner helpers

* refactor: give cross-domain helpers distinct names

* chore(lint): ratchet collision debt baselines

* fix(test): complete collision rename consumers

* fix(test): update remaining collision mock consumers

* fix(test): update transcript reader mock export

* refactor: keep embedded logger name at its owner

* fix(test): align embedded logger mock with owner

* refactor: name shared assistant phase extraction

* fix(ui): update assistant phase extractor import

* chore(generated): refresh collision and SDK baselines

* style(test): format merged plugin mocks

* chore(sdk): refresh API content hashes
2026-08-11 06:50:22 -07:00
Peter Steinberger 97c2eab77c test(bedrock): remove embedding inspection bridge (#122049) 2026-08-11 06:43:55 -07:00
Ayaan Zaidi 1b6467c779 fix(media): record model-visible outcomes for every inbound file attachment (#122025)
Inbound document attachments could vanish silently (DOCX and other Office files, read failures, disabled URL sources). File intake now classifies every attachment into a closed outcome union rendered through one exhaustiveness-checked path: unsupported formats, policy-rejected types, unreadable files, and disabled URL sources all produce bounded model-visible markers (max five per message plus one overflow summary), with strict MIME-token and URL-basename sanitization so attachment metadata cannot inject prompt text or leak signed-URL credentials. Media-stage outcome custody is tracked separately in #122044.

Proof: focused media suites (1855 tests), pre-fix regression, exact-head ci-gate green, ClawSweeper local review clean, and a live Telegram E2E showing the DOCX marker in the model payload.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 19:01:15 +05:30
Peter Steinberger 8dace97c2e perf(test): cut workflow guard overhead (#122038)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 06:29:08 -07:00
Peter Steinberger fd8b1fb1b9 fix(windows): preserve provider local service env overrides (#122027) 2026-08-11 06:28:24 -07:00
Peter Steinberger dd55770715 fix(channels): preserve plugin reply suppression across delivery paths (#121159)
* fix(channels): preserve reply transform suppression

* test: split ACP channel transform coverage

* chore: refresh plugin SDK API baseline
2026-08-11 06:28:20 -07:00
Peter Steinberger 241e1accde test(cli): remove private test seams (#122046) 2026-08-11 06:21:28 -07:00
Ayaan Zaidi 2c8ed54ddb feat(heartbeat): default delivery to the configured owner, never groups (#121988)
Unset heartbeat.target now resolves "owner": elected heartbeat notifications deliver to the operator's DM resolved from commands.ownerAllowFrom or the channel allowFrom (first concrete entry; wildcards and channel-scoped wildcards excluded; configured owners exhausted across channels before any channel-local fallback). Delivery requires the channel's own classifier to positively prove a direct destination — every bundled messaging plugin now ships an inferTargetChatType contract — and unproven or group-shaped destinations fail closed to the visible no-route state. The first implicitly-routed delivery carries a one-line self-explanation naming the target: "none" opt-out. Explicit target "last" remains as the follow-the-conversation opt-in. Refines the unreleased #121892 default before it ships; refs #121880.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 13:18:22 +00:00
Pavan Kumar Gondhi 8862cc46b3 fix(ios): harden share relay persistence (#121900)
* fix(ios): harden share relay persistence

* fix(ios): make relay migration transactional

* fix(ios): make relay migration host-owned

* fix(ios): reject legacy auth in share extension

* fix(ios): reject failed relay credential migration

* style(ios): fix relay settings indentation
2026-08-11 18:46:34 +05:30
Ayaan Zaidi d699ed0198 fix(ui): record chat-header startup JS growth in the budget baseline
#121734 landed 982 B of startup JS, leaving merge-ref builds 1 B over the
baseline ceiling; every open PR's build-artifacts job fails inherited red.
CI-measured bytes per the updater contract.
2026-08-11 15:08:53 +02:00
Peter Steinberger 59dc87290f test(plugins): remove cache resize test knob (#121904)
* test(plugins): remove cache resize test knob

* chore(plugin-sdk): refresh cache closure hashes
2026-08-11 06:05:32 -07:00
Peter Steinberger 5584318e6e test(cli): remove startup metadata bridges (#122024) 2026-08-11 05:41:48 -07:00
Ayaan Zaidi 1dde25cb20 test(telegram): expect status-only default command progress preview
#121600 (4c951398ef) made default command progress status-only — raw
command text stays out of chat previews. This assertion still expected
the pre-#121600 preview with the raw command line; bisect-confirmed
first-bad at 4c951398ef. Pre-existing failure surfaced by the
dispatch-suite CI gap (#122029). Dispatch suite now 247/247.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:40:20 +02:00
Ayaan Zaidi 56d62e6f23 test(telegram): expect canonical channel-prefixed durable delivery target
resolveDeliveryTarget (src/channels/turn/durable-delivery.ts:57) reads
OriginatingTo/To — channel-prefixed refs — as its own fallback chain, so
telegram:-100555 is the contract shape for the durable 'to', not the
bare chat id this assertion expected. Pre-existing failure surfaced by
the dispatch-suite CI gap (#122029).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:40:20 +02:00
Vyctor H. Brzezowski 16d0132c1b feat(ui): lead the chat header with the project and its own icon (#121734)
* feat(ui): show a workspace's own project icon in the chat workspace chip

Resolve the conventional project icon inside a session's workspace root once
per Gateway process and serve it over a strictly scoped authenticated route so
the Control UI can render real project identity instead of a folder glyph.

Refs #121723

* test(gateway): keep the workspace icon server teardown out of a promise executor return

* fix(ui): keep flat project icons legible on the workspace chip in every theme

* feat(ui): lead the chat header with the project, then the session title

Reorder the header into an identity trail — project chip, muted slash, session
title — rendered from one segment list so a later parent-session segment
extends it. Drop the project icon halo and record the flat-dark-icon contrast
tradeoff at the style site.

Refs #121723

* fix(ui): type the header identity trail segments without a lit result predicate

* fix(gateway): scope the workspace icon route to visible local sessions

Owner-gate the route so it cannot answer for sessions the caller's own
sessions.list would hide, withhold the workspace root of exec-node sessions so
a remote project never resolves to this host's icon, bound SVG icons before
they reach a renderer, and retry ordered Control UI credentials so a stale
saved token no longer silently drops the icon.

Refs #121723

* fix(ui): render the header project as a flat breadcrumb segment, not a badge

Drop the pill border, fill, and radius from the project name so it reads as a
quiet trail segment inline with the session title: one type size across the
trail, hierarchy carried by colour, hover and focus reusing the sibling title
button's tint so removing the border keeps a visible focus indicator.

Refs #121723

* fix(ui): balance the header trail separator spacing after the title pull-back

* test(ui): migrate the shared avatar loader tests to ordered credential arrays

* fix(ui): center the chat header identity trail

* refactor(ui): reuse workspace icon credentials

* test(ui): scope deleted-session recovery to the visible pane

* fix(ui): cache missing workspace icons across renders

* chore: refresh plugin SDK API baseline
2026-08-11 09:33:57 -03:00
Peter Steinberger 686294f9f8 test(sqlite): right-size reliability crash payloads (#122016)
* test(sqlite): right-size reliability crash payloads

* test(agents): replace hanging provider error integration

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 05:26:07 -07:00
Ayaan Zaidi a6ab4b7d54 test(telegram): align dispatch custody assertions with final-update options
#121908 (210aca6de3) added the onPlatformSendDispatch options bag to
final draft-stream updates and updated draft-failures-progress.test.ts,
but missed 19 sibling assertion sites across 6 dispatch test files.
Those files do not currently execute in any CI lane, so main's local
dispatch suite has been red since. Two remaining failures
(context-recovery session-target prefix, draft-failures-progress
preview shape) predate #121908 and are tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:21:06 +02:00
Peter Steinberger 4d606ecb5e test(outbound): use test-support suffix for shared fixtures (#122017) 2026-08-11 05:18:20 -07:00
Peter Steinberger fcb1dd9ab9 refactor(agents): collapse prompt dispatch relay (#122018) 2026-08-11 05:14:56 -07:00
Peter Steinberger 02e8470bb8 refactor: burn SDK export collision debt (#121888)
* refactor: burn SDK export collision debt

* chore: regenerate collision debt baselines

* fix: update durable delivery core import

* fix: remove stale channel metadata type import

* fix: preserve config write SDK parameter type

* fix: preserve chat metadata SDK return type

* chore: refresh plugin SDK API baseline

* test: update plugin enable mock import

* fix: remove duplicate status helper re-export

* fix: preserve strict QA runtime availability errors
2026-08-11 05:06:11 -07:00
Peter Steinberger 1c2ca3f2fc test(audit): remove private test bridges (#122012) 2026-08-11 04:58:55 -07:00
Peter Steinberger f12fe48075 refactor(gateway): finalize kernel composition (#122014) 2026-08-11 04:54:54 -07:00
Peter Steinberger 3cfb344f9f refactor(plugin-sdk): make API baseline module-mergeable (#121842) 2026-08-11 04:45:44 -07:00
Peter Steinberger 2cc11aff38 test(scripts): streamline Crabbox wrapper fakes (#122007)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 04:33:11 -07:00
Peter Steinberger 12165769c7 refactor(agents): move OpenRouter failover ownership to its plugin and derive reason schemas from one tuple (#121898)
* refactor(agents): centralize failover ownership and reasons

* test(agents): move OpenRouter failover cases to plugin owner

* fix(agents): preserve prepared provider failover ownership

* test(agents): avoid failover mock shadowing

* fix(agents): preserve provider owner in error copy

* fix(agents): complete provider owner propagation

* chore(plugins): refresh failover type closure hashes
2026-08-11 04:30:18 -07:00