[pull] main from openclaw:main - #653
Open
pull[bot] wants to merge 2815 commits into
Open
Conversation
* 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
…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
* 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 : )