Skip to content

[pull] main from openclaw:main - #653

Open
pull[bot] wants to merge 2815 commits into
sanketshah-dev:mainfrom
openclaw:main
Open

[pull] main from openclaw:main#653
pull[bot] wants to merge 2815 commits into
sanketshah-dev:mainfrom
openclaw:main

Conversation

@pull

@pull pull Bot commented Aug 21, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

@pull pull Bot locked and limited conversation to collaborators Aug 21, 2026
@pull pull Bot added the ⤵️ pull label Aug 21, 2026
Jason (Json) and others added 26 commits August 28, 2026 00:03
* fix(ios): scope sidebar sessions to selected agent

* fix(ios): fence session roster ownership

* fix(ios): partition cached sessions by agent

* refactor(chat): remove unused session list overload

* fix(macos): scope session rosters to selected agent

* test(ios): guard canonical activity roster owner

* fix(chat): fail closed for legacy scoped caches
* fix(test): clean fallback SQLite state after test runs

* test: make temporary-state fixtures ownership-aware

* fix(scripts): resolve test temp helper in native Node
* fix(ui): keep typed input in the selected dialog field

* test(ui): await Workboard modal readiness before focus checks
* fix: keep model reasoning out of generated session titles

Request strict visible output before transport recovery can discard reasoning
tag provenance. Share host-prepared completion execution across bundled
harnesses while preserving normal completion recovery and title fallback.

Keep selected model/auth routing, HTTP-boundary coverage and persisted-title
browser proof. Remove duplicate completion paths and redundant test setup.

Co-authored-by: luyifan <al3060388206@gmail.com>

* fix(agents): preserve strict empty CLI completions

Forward strict-visible output policy through the CLI owner and allow a clean
empty result only for strict isolated completions. Keep ordinary CLI empty
responses rejected before successful auth settlement, without a silent token.

Consolidate post-dispatch empty validation and duplicate usage test setup.

Co-authored-by: luyifan <al3060388206@gmail.com>

* test(agents): retain label fallback and prompt contracts

Consolidate utility-success coverage into the two-API prompt and auth-owner
table. Keep both rejected and reasoning-only utility fallback cases bound to
the selected runtime owner after the main composition.

Co-authored-by: luyifan <al3060388206@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(ui): open worktree sessions before setup finishes

Admit the first turn before naming, checkout, and repository setup; show
startup progress and keep failures retryable in the same session. Reuse the
accepted-run workspace owner, fence cancellation and setup authority, and
block sibling work until the workspace is ready.

Fixes #124966 (immediate worktree sessions and setup progress).

* test(ui): retain project picker capability in startup fixture

* fix(worktrees): fence checkout retries after cancellation

* test: align native phases and title fallback with admitted startup
* fix(usage): attribute named sessions to their store owner in all-agent list

The all-agent `sessions.usage` list labeled durable (store-backed) session
rows with whichever agent discovery surfaced, instead of the store owner.
When a subagent spawned from a session left a discovery transcript that
reused the parent sessionId, the Sessions dashboard card showed the
subagent's id (e.g. `scout-research`) instead of the owning agent
(`main`).

Resolve the owner from the durable store key via
`resolveSessionStoreAgentId`, re-resolve the owner's transcript file, and
de-duplicate by store key so a reused subagent transcript cannot shadow or
duplicate the owner row. Unnamed discovery-only sessions keep using the
discovered agent id.

Closes #128755

* fix(usage): reject cross-agent transcript fallback for named sessions

Address the ClawSweeper review finding on #128755: when owner transcript
resolution returned no file, the `?? discovered.sessionFile` fallback
could load the subagent's reused transcript under the owner row, leaving
attribution and usage totals inconsistent.

Resolve only an owner-associated transcript for store-backed named rows.
When the owner transcript is absent the row stays attributed to the owner
with no usage loaded (cold cache) instead of substituting another agent's
transcript.

Move the two #128755 regression tests into a dedicated
`usage.sessions-usage-owner-attribution.test.ts` so the existing
oversized test file stays under the max-lines limit, and add a case
covering the unresolved-owner path.

* fix(usage): bind transcript resolution to the durable store owner marker

Address the ClawSweeper re-review finding on #128755: the owner-file
resolver accepted a store entry SQLite marker by sessionId alone, so a
marker reusing the sessionId under a different agent (e.g. a subagent)
could still substitute that agent's transcript for a main-owned row.

Guard the resolver call: parse the store entry marker and only forward the
entry when its embedded agent matches the resolved owner. When the marker
belongs to another agent, drop the entry so the resolver falls back to the
owner agent's own transcript directory (or no file), never the subagent's.

Add a regression covering a durable row whose stored marker names a
different agent.

* fix(usage): drop redundant type assertion for store entry sessionFile

SessionEntry already declares sessionFile?: string, so accessing it
directly avoids a non-const type assertion. Restores the assertion-safety
ratchet (8 > 7 baseline) without changing behavior.

* fix(usage): validate entry marker agent in transcript resolver

Move the store-entry SQLite marker ownership check into
resolveExistingUsageSessionFile itself: matchingEntryMarker now requires
entryMarker.agentId to equal the requested agentId, so a subagent marker
reusing a parent sessionId can no longer be substituted for the owner
transcript. This lets the all-agent usage list drop its redundant outer
guard (and its non-const type assertion) and simply request the owner
agent, restoring the assertion-safety ratchet baseline.

Adds a regression test in session-cost-usage.test.ts covering the mismatched
agent marker path.

* fix(usage): preserve selected-agent ownership for global list rows (#128755)

- Only resolve durable owner for agent-scoped named keys; keep discovered
  agentId for global/unknown so a scoped request keeps its own global row.
- Add scoped-global list-path regression test.
- Add real-state remote-proof test (no internal mocks) logging the RPC trace.
- Add positive marker-match test; trim verbose comments.

* fix(usage): drop unused eslint-disable directive in remote-proof test

* fix(usage): resolve global durable rows to owner in all-agent lists (#128755)

ClawSweeper P1: all-agent discovery is newest-first, so a subagent transcript
that reuses a global durable row's sessionId could still relabel the row.
Resolve global/unknown rows to their logical owner in all-agent lists while
keeping the explicitly requested agent for scoped lists.

- Add all-agent global-row regression test.
- Add authenticated Gateway WebSocket proof test capturing the RPC trace.

* test(usage): restore gateway token env after ws-proof server

* test(usage): add real-Gateway UI e2e proof for #128755 owner attribution

Add a real-Gateway Control UI e2e test that seeds the #128755 scenario
(main owns the durable telegram DM row; an opus subagent transcript reuses
its sessionId, discovery-only) and drives a real Chromium browser against a
loopback token-free Gateway. The Sessions usage dashboard must attribute the
Telegram DM card to its store owner (agent:main), never to the reused opus
subagent, with no duplicate/shadow row.

- Asserts the .session-bar-row for agent:main:telegram:dm shows agent:main
  in its meta and no agent:opus row appears.
- Captures a redacted isolated dashboard screenshot when
  OPENCLAW_CAPTURE_UI_PROOF=1 (sanitized test fixtures, loopback, no tokens).
- Registered in the checks-ui-e2e-real-gateway CI lane and excluded from the
  standard ui-e2e shard via uiE2eRealGatewayTestFiles.

* fix(usage): bind owner transcript to canonical durable target (#128755 P1)

ClawSweeper P1: resolveExistingUsageSessionFile still received storeMatch.entry,
whose sessionFile can hold a cross-agent legacy JSONL path. resolveSessionFilePathCore
intentionally accepts absolute paths from other agents, so a main-owned row
carrying an opus path would be labeled main while the opus transcript loaded
into main's usage group.

Resolve via the canonical durable owner target instead: pass a complete
sessionTarget (owner agentId + sessionId + store key + owner storePath) so
resolveExistingUsageSessionFile validates owner identity and returns the owner's
canonical SQLite marker, never consulting the cross-agent legacy file.

- Add regression: owner target rejects an existing cross-agent opus transcript
  file on the durable entry and returns the owner's sqlite:main: marker.

* fix(usage): join sessions by agent and transcript identity

Carry projected session ownership into usage reporting and preserve independent
cross-agent transcripts with equal IDs. Scope historical-family suppression to
the same identity, retaining canonical aliases within each agent.

Replace re-attribution and deduplication branches with one owner-aware join.
Add real-state ownership coverage and retain real-Gateway browser proof.
Stabilize neighboring cache range coverage by awaiting its real refresh.

Fixes #128755. Refines #128803. Thanks to @yetisoldier for the report.

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

* test(usage): seed browser transcripts within the active date window

* test(ui): assert reader anchoring across transcript growth

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Reject catalog searches whose callable names exceed the existing output
budget, with guidance to narrow the query or lower the limit. Remove the
guest fallback that turned an oversized match set into a false empty result.
Ordinary successful tool-result truncation remains unchanged.

Fixes #131551. Release context: Code Mode agents can distinguish search
overflow from genuine no-match results and retry discovery without silently
abandoning an available tool. No config, budget, or native Codex change.
…131548)

* fix(discord): retire voice sessions after realtime provider closure

Route terminal provider closure through the existing voice entry teardown owner and resume queued speech after reconnect readiness. Closes #131397.

* test(discord): prove terminal closure retires transcript captures

* test(discord): split terminal lifecycle coverage
Reuse the existing operator scope checker for dynamic admission and the selected session-action handler. Preserve independent privileged scopes and post-admission revalidation.\n\nFixes #131526.
* fix: recover active sessions across repeated gateway restarts

* fix: resolve recovery CI integration failures

* chore: document transcript assertion safety

* fix: finish recovery start persistence before command teardown

* test: type command fixtures with internal session state
Prefer the verified GitHub public name for new or unnamed profiles and upgrade saved names only when they exactly match the current canonical login. Preserve other saved names and provider fallback on the next normal identity sync. Reuse existing GitHub requests without migration or schema changes.
Reconcile complete history membership at the run coordinator while preserving concurrent runs and activity observed during history requests. Keep unknown membership distinct from an empty active set and preserve gap-recovery ordering.

Fixes #131484
* fix(test): synchronize descendant watchdog readiness

* fix(test): verify child readiness and final liveness
…1586)

Keep consumed attachment URLs out of the shared Slack fanout context so Block Kit finalization does not fail and plain-text presentation fallback does not upload the same file twice.

Match the payload harness to the real core caller and cover singleton aliases and media lists through durable delivery and the real Slack sender, preserving thread routing and receipt aggregation.
* fix(gateway): own standalone MCP App request lifetimes

Keep initial loading and individual MCP requests bounded without applying
a derived single-request timeout to composed App operations. Carry caller
cancellation through the HTTP request owner, isolate shared catalog waits,
and preserve bounded graceful cleanup before terminal document teardown.

Retire stale document/bootstrap responses and observe asynchronous catalog
rejections without changing authorization, public SDK contracts, or retry
behavior. Add serialized-owner regressions and real Chromium conformance.

Rewrites #119388 while preserving the contributor's report and credit.

Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com>

* test(ui): preserve rendered MCP App diagnostics without suppression

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com>
* fix(release): consent to staged Codex onboarding companion

* fix(e2e): prepare reviewed onboarding plugins explicitly

Use the shared command-help consent helper for the reviewed Codex and
external channel fixtures. Keep exact staged Codex versions pinned, use
official catalog selectors for published packages, and preserve historical
automatic setup when the candidate CLI lacks capability consent.

Replace source-order assertions with shell boundary coverage and document
reviewed plugin preinstallation before retrying noninteractive setup.

Co-authored-by: Dallin Romney <dallinromney@gmail.com>

* fix(e2e): preserve official provenance for candidate channels

Stage the selected Discord or Slack companion with Codex in the verified
prerelease registry and install its exact pinned npm spec after onboarding.
The former npm-pack path installed matching bytes but could not establish
the official provenance required by trusted plugin state APIs.

Remove local archive packaging and install overrides. Reject missing or
mismatched source companions before CLI use while keeping published catalog
selection and historical automatic setup unchanged.

Co-authored-by: Dallin Romney <dallinromney@gmail.com>

* fix(e2e): preserve frozen channel candidate registry

Keep the immutable Codex registry artifact unchanged and serve source Discord/Slack tarballs as separately validated exact npm packages. Remove source install overrides and fail closed without the mounted registry.

Co-authored-by: Dallin Romney <dallinromney@gmail.com>

* fix(e2e): keep candidate plugins in one registry

Restore the planner-owned immutable prerelease registry artifact containing Codex and the selected source channel companion. This supersedes the separate tarball mount follow-up.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Dallin Romney <dallinromney@gmail.com>
Bind legacy JSON source discovery, sibling paths, verification, and SQLite relocation to the explicit Doctor environment. Preserve shared ownership, tilde relocation, and pending-schema deferral. Fixes #131560.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Let LINE `/card` operators keep commas, pipes, and colons inside card data without changing unescaped commands.

Use one escape-aware parser across action, buttons, list, receipt, and confirm values.

Co-authored-by: 許元豪 <146086744+edenfunf@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(gateway): honor scope implications in operator role ceilings

Allow admin-only named roles to approve valid Control UI scope upgrades and preserve already-granted implied scopes across WebSocket, HTTP, and plugin-cookie authorization. Recheck the current role before releasing approved tokens and retain existing denial and scope-cap boundaries.

* fix(gateway): cap default plugin runtime scopes by role

Reuse the existing implication-aware HTTP ceiling for plugin default grants across HTTP and upgrades. Keep ordinary defaults write-only, deny read/empty roles, and preserve explicit headers and shared-secret behavior.

Add durable-profile boundary regressions and preload the real Control UI test owner outside request deadlines after measuring cold-import timeouts.

* test(gateway): bound plugin upgrade fixture payloads
ANIRUDDHA ADAK and others added 30 commits August 28, 2026 11:15
…des (#129823)

* fix(discord): keep component attachment names through classic downgrades

* test(discord): correct multipart and Gateway proof contracts

Require string-valued multipart JSON fields and assert the canonical settled
core delivery receipt instead of the plugin-only success envelope. Keep all
five raw-wire cases, including the explicit filename override, unchanged.

This is a diagnostic stage: the structured-component outbound adapter may
still drop its prepared filename override. Obtain the actual Gateway case
result before making another production repair; do not merge this stage.

* fix(discord): preserve prepared component filenames

Read the existing normalized filename before selecting the outbound payload
branch and forward it to the first structured-component attachment. Keep
later uploads' source names and existing Components V2 mismatch validation.

The built Gateway regression reproduced the dropped operator override before
this repair. Extend the existing adapter fixture with first-only classic and
V2 overrides plus rejection of conflicting V2 names before upload. All 38
focused owner and sibling cases pass; the five-case built Gateway rerun and
exact-head CI remain required before merging.

Co-authored-by: Aniruddha Adak <aniruddhaadak80@users.noreply.github.com>

* test(docker): seed MCP history through canonical session APIs

Replace the MCP smoke fixture's retired session-file writers with the
packaged session entry and ordered transcript APIs. Preserve the existing
session metadata, message IDs, media facts, and unchanged MCP assertions.

Keep legacy migration owned by Doctor; do not change runtime startup or
the session schema to accommodate a stale non-migration fixture.

---------

Co-authored-by: Aniruddha Adak <aniruddhaadak80@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* docs: prohibit publishing unreleased model identifiers

* docs: clarify public model IDs for integration tests
* refactor(cli): simplify message result rendering

* chore(cli): tighten message formatter assertion budget
…rted when the working directory is unreadable (#131998)

* fix(daemon): stop reporting failed runtime probes as unsupported runtimes

The daemon runtime probe wrapped its exec in a bare catch that returned
`supported: false`, so any failure to *run* the probe was laundered into a
verdict that the runtime itself was unsupported. Operators on a perfectly
good Node install were told to install a Node version they already had.

Observed on Ubuntu 26.04 with Node 26.8.1: `openclaw node install` failed
with "No supported Node runtime was selected for the daemon" whenever the
process cwd was not readable by the service user (e.g. `runuser -u openclaw`
inheriting root's 0700 home over SSH), because every child spawn then fails
EACCES. The version logic was never wrong -- resolveSystemNodeInfo returned
supported:true and resolvePreferredNodePath returned /usr/bin/node when
probed directly on the affected host.

Node and Bun probes now share one resolver returning a closed
supported | unsupported | probe-failed union. A failed probe retains its
cause, executable, and cwd, and selection propagates that instead of falling
through to Node-upgrade advice.

Also:
- Derive the supported-version wording from NODE_RELEASE_FLOORS via a new
  exported SUPPORTED_NODE_VERSIONS, replacing six hand-copied spellings that
  omitted the >=25.9.0 line and told operators to downgrade.
- Forward OPENCLAW_WRAPPER through the node-host install path; the documented
  escape hatch was previously gateway-daemon-only.

Production LOC net +6 (+156/-150); consolidating the duplicated Node/Bun
probes paid for the new failure handling.

* docs(cli): drop machine-local path from node probe-failure guidance

ClawSweeper P3: docs/AGENTS.md requires generic docs content with no local
paths. The probe-failure recovery example prescribed a specific directory;
state the readability requirement instead.
* fix(buzz): persist account names during noninteractive setup

* docs(buzz): preserve setup release notes in the PR
* fix(agents): keep dangling symlinks visible in ls listings

Retain directory-entry names when optional target metadata is unavailable, preserving healthy directory-link suffixes and bounded output notices.

Related: #131776

* test: simplify ls regression arguments
)

* fix(plugins): unblock registry refresh across agent workspaces

* test(plugins): complete scoped registry harness fixtures

* test(plugins): complete registry snapshot type fixtures
* docs: reframe for teams and soften group-chat guidance

The docs framed OpenClaw as single-user ("personal AI assistant",
"personal assistant trust model") even though multi-user sessions,
named operator roles, presence, and commit credit shipped. Reframe the
trust model as one trust boundary per gateway (a single operator or a
mutually trusting team), treat group chats as a first-class deployment
with caution scoped to genuinely public rooms, and add a Team setup
guide next to the personal one.

* docs: link Why OpenClaw from README and docs root

Reframe the README intro away from single-operator-only wording, add the
team deployment and Why OpenClaw links, and point the docs landing page
at the architecture case.

* docs: soften security callouts from warnings to notes

* docs: keep Slack DMs on pairing default in team example
* test(discord): remove retired voice fixture aliases

* test(discord): use recorded player mocks in voice e2e
#131883)

* fix(qa): prevent early Discord bot reuse and implicit transcript rooms

* chore(qa): defer the Crabline dependency update

* fix(ci): use public QA helper and gate skipped report fetches
* feat(buzz): support flat replies with committed tool-state tracking

Keep automatic reply and typing placement in the Buzz plugin, preserving default threading and explicit targets. Reconcile with canonical schema, transcript-cache, live-argument, and correlation-ID owners on main; retire pending results only after persistence and before callbacks.

* docs(buzz): keep release notes in the PR
Unify accepted-send recording and remove duplicate participant, Activity, avatar, and listener projection paths. Preserve identity, timing, visibility, and storage contracts; retain boundary coverage and isolate the pre-existing shared /tmp test fixture.
Relay Claude CLI partial assistant snapshots through the canonical parser while keeping nested tool-result text out of visible replies.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* test(exec): characterize companion response loss without local replay

Exercise signed Unix socket requests, real native execution, and enforced routing after a lost response. Clarify that HOST=app already requires the companion; FALLBACK does not change current routing. This records the nullable transport ambiguity without changing production behavior.

* test(exec): stabilize transport proof fixtures

Use socket-owner readiness and awaited shutdown for the real native proof. Freeze the JSONL deadline instead of asserting wall-clock latency, and align fixture types with the existing test helpers.

* test(macos): observe native cancellation fixture readiness

Wait for registered PID-marker observation or a real native terminal response before injecting cancellation. Gate the sentinel delay on readiness and drain failure cleanup before removing fixture state. Cover slow admission, early native failures, and incomplete PID publication without changing production behavior.

* test(exec): register and validate native proof client
* feat(ui): keep latest assistant actions visible

* fix(ui): scope latest actions to group footer

* fix(ui): hide assistant actions after user follow-up
* improve(ui): refine chat image presentation and controls

* fix(ui): address chat image review findings

* style(ui): format chat image coverage
* feat(profile): enable Git co-author credit by default

Verified GitHub identities now get public `Co-authored-by` credit unless the
person explicitly opts out. An absent `git.coauthor.enabled` row is the default
rather than a refusal, resolved through one shared helper used by both the
attribution resolver and the Control UI toggle.

* fix(profile): fail closed on malformed co-author preference values

The preference API persists arbitrary JSON, so `value !== false` let a
non-boolean row read as consent to publish a verified person's public Git
trailer. Only a missing row or literal `true` now enables credit, with
regression coverage at the attribution resolver and the profile toggle.

* docs(vision): state the team-assistant direction alongside personal use

The privacy rule governs what leaves an install, not what teammates see on a
shared Gateway. Say that explicitly so co-author credit and other shared-session
attribution are not read as a violation of the telemetry opt-in rule, and name
team.openclaw.ai as where OpenClaw is built with OpenClaw.
* perf(installer): use blobless PowerShell clones

* fix(installer): preserve clone compatibility on older git

* fix(installer): recognize modern git filter help
* fix(ui): retain prompts after cloud startup failures

Keep the initial submission in its existing scoped tab recovery until delivery is confirmed. Retry known failures on the created session and captured target; check uncertain delivery without replaying work. Preserve attachment ownership and newer submissions.

Refs #131452.

* test(ui): clarify placement startup fixture names

* fix(ui): preserve initial-turn ordering across reconnects

Keep unresolved placement submissions ahead of ordinary chat admission while transport is disconnected, without exposing content or executing through stale credentials. Preserve lazy and memory-only recovery ownership and distinguish first dispatch after an explicit create retry from placement reconciliation.

* docs(ui): describe automatic transcript text recovery

* fix(ui): hold chat admission until initial recovery settles

Keep later input behind credential recovery and the retained initial turn. Wake the canonical outbox drain when readiness or initial ownership resolves, after projecting the initial handoff. Cover cold Hello, accepted receipt and invalid-record release through the browser boundary; retain ordinary offline queuing.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.