Commit Graph

11339 Commits

Author SHA1 Message Date
Peter Steinberger a7f9a7fdd4 refactor(gateway): interrupt at admission; sessions.steer delegates to chat.send (#126291)
* refactor(gateway): interrupt at admission; sessions.steer delegates to chat.send

chat.send queueMode interrupt now aborts the captured current operation
at the session-work admission owner (exact-instance abort, never a
same-key successor) and dispatches the new turn after the abort
settles; channel-originated interrupts share the same primitive.
sessions.steer keeps its validation, sharing/access checks, and
response shape but becomes a thin deprecated adapter over that path -
its private inflight/retry and hard-abort machine is deleted. The
Control UI /redirect command rides canonical chat.send. Compaction's
use of the old hard-interrupt helper moves unchanged to
session-run-interruption.ts.

* fix(gateway): interrupt non-reply admissions
2026-08-19 04:36:57 -07:00
Peter Steinberger 4af09d4961 feat(ui): unify focused presentation routes (#126143)
* feat(ui): unify focused presentation routes

/focus/<target> replaces unshipped standalone query links across dashboard, terminal, desktop, and native apps.

Gateway-served index assets are anchored so nested documents resolve their bundles from the Control UI base path.

* test(gateway): narrow emitted asset URLs

Fixes check:test-types TS18048/TS2322 by dropping unmatched optional captures before comparing emitted asset URLs.

* test(docs): follow centralized cloud secret guidance

Fixes the stale current-main docs test after #126132 centralized GCP and Hetzner setup in docker-vm-runtime.

* test(ui): retry missing locator reads

The 500ms locator text read can time out while the menu label is still rendering, causing expect.poll to reject instead of using its owning 10s retry window. Treat only Playwright TimeoutError as a missing value so the outer poll retries while page-closure and arbitrary failures still surface.

* test(android): capture TLS probe coroutine

The TLS probe test inferred its coroutine from mutable scope children, racing unrelated child startup and teardown in CI. Capture the exact Job from inside the probe coroutine and join that owner before asserting the stale-attempt guard.

* fix(gateway): preserve plugin focus routes

Keep approval handling ahead of plugin dispatch, but treat focus documents as an unclaimed Control UI fallback after plugin authentication and routing. Exact and prefix plugin routes therefore retain ownership, while unclaimed reads serve the focus document and other methods return 404.

* fix(ui): migrate released terminal links

Preserve stable v2026.7.1 terminal query compatibility by rewriting the root/base ?view=terminal URL once to the canonical /focus/terminal path with history.replace. Keep URL parsing path-only, and leave the removed desktop and dashboard query forms as a hard cut.

* test(codex): assign run-attempt tools shard

Cached filtered configs caused duplicate ownership, and the test lacked a canonical full-suite owner.

* test(ui): keep cloud recovery proof state-owned

The recovery test should assert owner state and reload identity, while dedicated tests own transient alert visibility.

* test(qa): wait for outbound bus state

* fix(qa): reserve gateway ports through staging

* refactor(qa): keep socket creation in gateway owner
2026-08-19 03:41:29 -07:00
Peter Steinberger 46ef757a29 feat: add per-project cloud worker profile defaults (#126238)
* feat(config): add cloud worker project profiles

* feat(gateway): resolve project cloud worker profiles

* docs(gateway): document project profile defaults

* fix(gateway): require admin for project profile dispatch
2026-08-19 03:20:39 -07:00
Peter Steinberger e71fc902ee fix(gateway): make activeRunIds presence mean a complete exact run set (#126106)
* fix(gateway): make activeRunIds presence mean a complete exact run set

Session rows no longer emit activeRunIds: [] while hasActiveRun is
true. Presence now means the complete exact set of direct run ids;
omission means identities are unavailable (projected/embedded owners);
[] only ever represents proven idle. Consumers stop guessing:
soleActiveSessionRunId() replaces the arbitrary [0] fallbacks in the
observer digest, transcript cache key, activity inspector, and
stale-terminal reconciliation, each falling back to its owner fact.

Follows the maintainer direction from #125983: the field stays as
Gateway-owned exact facts; producer-side liveness/observer projections
are a named follow-up.

* fix(gateway): clear unavailable active run ids in events

* fix(gateway): preserve idle active run sets

* fix(clients): close active run id cache gaps

* test(android): isolate history run snapshot
2026-08-19 02:08:57 -07:00
Peter Steinberger 67750753a2 fix: capture GitHub identity from authenticated sign-in (#126114)
* fix: capture GitHub identity from authenticated sign-in

Automatically persist verified GitHub identities from Cloudflare Access and Tailscale Serve while keeping public Git co-author credit as a separate opt-in.

* test: stabilize cleanup and activity capture

* fix(security): bind GitHub profiles by account id

* test: scope activity capture to route

* fix(security): gate profile requests on identity sync

* fix(security): close pending profile authorization gaps

* test(ui): stabilize terminal continuation menu

* test: stabilize startup recovery timing

* test: keep one Codex attempt tools owner

* fix(plugins): allow profile-independent gateway reads
2026-08-19 01:35:52 -07:00
Peter Steinberger fef5fc55f4 fix(codex): prevent node process control from targeting gateway sessions (#126253) 2026-08-19 01:31:52 -07:00
Peter Steinberger 80934e5639 feat(ui): dispatch sessions to paired devices (#126187) 2026-08-19 01:11:49 -07:00
Peter Steinberger 3378e07d50 refactor(plugin-sdk): promote shared runtime primitives (#126193)
* refactor(plugin-sdk): promote shared runtime primitives

* test(codex): keep one attempt tools owner
2026-08-19 01:10:18 -07:00
Peter Steinberger cb5c061cb3 fix(gateway): resolve ambient heartbeat owner without crashing startup (#126232)
Ambient heartbeat ownership now follows the cron owner chain: heartbeat.agentId, legacy default, systemAgent.agentId, then sole agent.
Ownerless multi-agent rosters disable heartbeats with gateway and config-validate warnings instead of throwing AgentSelectionRequiredError during gateway startup.
2026-08-19 01:05:28 -07:00
Peter Steinberger 554fc80e2f fix: Full access sessions no longer request exec approval (#126210)
* fix: stop Full access sessions from requesting exec approval

* fix: propagate Full access policy to compaction

* fix: source compaction permissions from session state
2026-08-19 01:04:36 -07:00
Peter Steinberger 44736749eb feat(skills): custodian-only skill library (first wave) (#126186)
* feat(skills): add custodian-only skill library

* docs: document custodian skill library

* refactor(skills): make custodian skills concrete and non-interactive

Replace docs-link-first playbooks with verified openclaw config/message/infer
one-liners; drop interactive onboard references; encode the in-session
config-write policy boundary (models.*/secrets.* via trusted shell).

* fix(skills): corrections from live A/B testing of custodian skills

--agent required for models list/auth list in multi-agent rosters; drop
hanging channels capabilities probe; telegram target is chatId; roster-safe
prove via agent turn (infer model run has no --agent and dead-ends
multi-agent setups); note expected not-found on pre-setup config get.

* fix(skills): front-load harness plugin check in add-model-provider Gather

A/B timing showed the codex plugin dependency surfacing mid-Prove, at the
most expensive point (approval gate + turn boundary). Checking and
remediating during Gather removes the stall.

* fix(skills): keep status inventory unfiltered while scoping custodian source

buildWorkspaceSkillStatus forwarding agentId activated the loader's agent
allowlist filter, dropping excluded skills from the workshop's status view
(collection-review regression on CI). New closed agentSkillFilter mode lets
agentId scope custodian-source discovery without filtering the entry list,
per the documented status invariant.
2026-08-19 00:33:02 -07:00
Peter Steinberger 554dfbe0a2 feat(discord): auto-join occupied voice rooms (#125974)
* feat(discord): auto-join occupied voice rooms

Add opt-in voice.autoJoin[].whenOccupied residency so Discord voice bots join for the first human and leave when the room becomes empty while preserving existing always-on, manual, transcript, and follow-user behavior.\n\nCloses #125973

* test(discord): isolate process runtime mocks

Use stable hoisted runtime-env mocks so isolate=false Discord test ordering cannot turn sleepWithAbort back into an unmocked function.

* fix(discord): defer unknown voice occupancy

Treat memberless voice states as unresolved instead of human so bot-only rooms cannot trigger occupancy-managed auto-join. Add cache-to-listener and manager regressions.\n\nCloses #125973

* test: isolate shared module mocks

Replace ineffective non-isolated module spies with stable hoisted mocks and a child-process SQLite connection-reuse probe so gateway and Discord shards are order-independent.

* test(gateway): inline connection reuse probe

Keep the child-process SQLite ownership probe in its owning Vitest file so Knip sees the full test surface without weakening process isolation or the original order regression.
2026-08-19 00:08:54 -07:00
Peter Steinberger 57a65def4f fix(ui): restore sidebar session hovercards (#126222)
* fix(ui): restore sidebar session hovercards

* test(codex): include run-attempt tools in full suite
2026-08-19 00:07:05 -07:00
Peter Steinberger 49d8cfd393 fix(security): prevent blocked SearXNG refs from using ambient URLs (#126214)
* fix(security): honor blocked SearXNG secret refs

* docs(searxng): clarify blocked SecretRef policy

* test(codex): route attempt tools coverage
2026-08-19 00:02:58 -07:00
Ayaan Zaidi 97e3136b9e feat(qa): add a standalone Telegram Desktop recorder with a prebaked desktop image (#125186)
Records native Telegram Desktop from a digest-pinned prebaked image: a ready desktop in ~12s with no per-lease apt installs or downloads, which also removes the dpkg-lock failures that killed recent runs.

The recorder only records; callers drive the turn and supply the TDLib driver used for QR authorization. Nothing in this repository invokes it yet - routing the Mantis Telegram Desktop Proof workflow through it is a follow-up.
2026-08-19 11:23:48 +05:30
Peter Steinberger 0d14434d0e feat(secrets): add explicit protected and agent-readable access (#126088)
* feat(secrets): add explicit agent access modes

Distinguish protected write-only secrets from agent-readable Gateway environment values, expose policy-bound Gateway exec aliases to Codex, and activate Node environment proxy support for destination-bound egress.\n\nCloses #125975

* fix(gateway): bind lifecycle dispatch to owning instance

* test(ui): preserve mock gateway recovery state

* fix(codex): avoid unavailable gateway process guidance

* fix(harness): keep run correlation host-owned

* fix(gateway): bind restart delivery to instance

* test(codex): construct tools through test host capability
2026-08-18 22:51:15 -07:00
Peter Steinberger 2bcc06cc22 fix(cron): required delivery failures no longer report success (#126164)
* fix(cron): preserve required delivery completion

Record durable completion independently from payload execution so required delivery failure cannot delete one-shots or report successful waits.\n\nCloses #126163

* fix(cron): keep completion contracts acyclic

* fix(cron): keep delivery predicate private
2026-08-18 22:44:33 -07:00
Peter Steinberger 3550b174e9 fix(crabbox): derive machine classes from catalog (#126184) 2026-08-18 22:35:13 -07:00
Peter Steinberger 404eddbc6a fix(plugins): preserve subagent lifecycle results (#126167) 2026-08-18 22:22:20 -07:00
Peter Steinberger e38a06439e refactor: trim locale and QA fixture debt (#126139)
* refactor: trim locale and QA fixture debt

* fix(qa): preserve shared flow portability

* chore(qa): document shared flow branch

* fix(docs): align plugin SDK subpath catalog

* fix(ci): align shared docs and flow contracts
2026-08-18 22:17:19 -07:00
Peter Steinberger 5564671c4f fix(gateway): bound audit and Codex backlogs (#126154)
* fix(gateway): bound audit and Codex backlogs

Live Gateway SQLite lock failures and process heap pressure exposed two
independent queue owners. Route best-effort audit persistence through the
canonical shared-state connection with bounded contention retries, and remove
the per-notification Codex yield so the keyed turn queue can drain directly.

Follow-up to #126033 and #126073.

* fix(gateway): annotate raw SQLite cold-open probe

* test(codex): register notification burst shard
2026-08-18 21:44:09 -07:00
Peter Steinberger 4ffa2a4418 fix(gateway): avoid readiness flaps during Reef reconnects (#126151)
* fix(gateway): avoid readiness flaps during Reef reconnects

* docs: preserve plugin SDK private-local contract wording
2026-08-18 21:29:43 -07:00
Peter Steinberger 00482543ff fix(agents): bound Skill Workshop model projections (#126158) 2026-08-18 21:28:54 -07:00
Peter Steinberger 7bc994aee8 fix(install): avoid success after incomplete lifecycle changes (#125992)
* fix(install): make lifecycle mutations transactional

Standalone installers now apply npm-version-aware lifecycle approval. Updates verify and repair the installation before reporting success and preserve the prior install owner during method switches. Uninstall now exits nonzero when requested cleanup is only partially completed. Plugin update behavior is unchanged.

Closes #125925

* test(uninstall): assert aggregated live-owner failure

* fix(install): satisfy standalone shell checks

* fix(update): scan PATH for prior Git wrapper

* test(hooks): await Gmail watcher descendant exit

* fix(install): verify Windows npm candidate

* fix(ci): normalize package acceptance version

* fix(update): preserve staged local package links

* test(update): fold staged symlink coverage

* fix(update): retire every legacy Git wrapper

* test(docs): align consolidated ownership checks
2026-08-18 20:50:15 -07:00
Peter Steinberger 2a97397f47 docs: consolidate setup and plugin references (#126132)
* docs: consolidate setup and plugin references

* docs: preserve meeting plugin configuration
2026-08-18 20:00:05 -07:00
Peter Steinberger c97b8ffdfc refactor: consolidate meeting and media provider families (#126053)
* refactor(plugins): consolidate provider family helpers

* fix(plugin-sdk): keep meeting script helpers private

* fix(plugins): sync meeting boundary paths
2026-08-18 19:11:13 -07:00
Peter Steinberger 15fb00eb6b fix: surface paired-device runtime requirements (#126067)
* fix: surface paired-device runtime requirements

* test: cover session runtime placement metadata

* test(gateway): stabilize runtime catalog fixtures

* fix(gateway): reject incompatible device moves
2026-08-18 19:10:41 -07:00
Peter Steinberger 948a444d63 fix(ui): require exact active run ownership (#126116) 2026-08-18 18:54:58 -07:00
Josh Avant 784676537c feat(ui): enable link favicons by default (#126109) 2026-08-18 18:41:54 -07:00
ClawSweeper a480d0347f feat(sessions): expose sidebar category controls (#126074)
* feat(sessions): expose sidebar category controls

* fix(sessions): make category controls explicit

* test(sessions): update list description fixture

---------

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
2026-08-18 19:41:35 -06:00
Samuel Judson 6ccc57b331 fix: add ssrf protection to Beam fetches (#123848)
* Add ssrf protection to Beam fetches.

* Additional robustness following initial comments.

* fix(beam): make redirect failures terminal

* chore(plugin-sdk): refresh surface budget

* docs(beam): define redirect restart behavior

* docs(beam): align redirect config help

* test(beam): cover warning before redirect block

* fix(beam): always report terminal redirect blocks

---------

Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-08-18 18:00:58 -07:00
Vyctor H. Brzezowski 421104253b feat(ui): proxy opt-in link favicons through gateway (#121906)
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-08-18 17:44:57 -07:00
Josh Avant 8d6cbee1b5 fix(gateway): avoid Tailscale crash loops after upgrades (#126069)
* fix(gateway): migrate legacy Tailscale routes on upgrade

* fix(gateway): preserve unattributable Tailscale routes
2026-08-18 17:14:49 -07:00
Josh Avant 50720c3b8e fix(codex): preserve native approval scope (#125995) 2026-08-18 16:18:01 -07:00
Peter Steinberger 9924e2d7a7 feat(cli): prepare session-host onboarding (#125879)
* feat(cli): prepare session-host onboarding

* fix(cli): gate session-host installer capability
2026-08-18 16:08:48 -07:00
Peter Steinberger 1d9cda833f feat(ui): show machine CPU and RAM in the cloud picker (#125696)
The cloud machine picker described each class in prose ("Cheap smoke checks
and small repos"), which was the widest thing in the row, got ellipsized, and
did not say what the operator actually picks on. Machine options now carry the
class shape and the picker renders "32 vCPU · 64 GB" instead.

Crabbox reports per-provider class shapes from `providers --json`; the plugin
reads that catalog once per lifecycle and attaches cpu/memoryGb to each option.
A missing binary, failed command, unparseable output, absent classes, or an
unmatched provider all degrade to label-only rows, so an older Crabbox keeps
working.

`description` was never released, so it is removed rather than deprecated, and
listMachineOptions becomes async for the catalog read. Deletes the duplicate
machine-option projector in the environments server method.
2026-08-18 15:38:15 -07:00
Patrick Erichsen f6f426c8e8 feat(ui): add copy session id action (#124059) 2026-08-18 22:29:20 +00:00
Peter Steinberger 39aec9b3d7 docs(gateway): document cloud-workers settings page and machine picker (#126049)
The Control UI settings page (#124864) and the New Session place
picker's machine section had no doc coverage — the configuration and
dispatch walkthroughs only described the JSON/RPC paths.
2026-08-18 15:19:48 -07:00
Peter Steinberger 4be131107f docs(gateway): document the Cloudflare Tunnel and Access deployment (#126029)
* docs(gateway): document the Cloudflare Tunnel and Access deployment

* docs(gateway): clarify Cloudflare Access trust boundary
2026-08-18 15:03:27 -07:00
Peter Steinberger 41e3968ee4 docs(config): clarify missing unset behavior (#126036) 2026-08-18 14:55:19 -07:00
Peter Steinberger 491dc7f8b1 fix(codex): report native project docs truthfully (#126010) 2026-08-18 14:42:56 -07:00
Onur Solmaz 5cabd2b72e Revert "fix(providers): report request acceptance consistently (#125807)" (#126021)
This reverts commit f5e9622fc9.
2026-08-19 00:16:09 +03:00
Peter Steinberger 39b39ca6ee fix(gateway): apply configured edge auth to session-URL targets (#125982)
* fix(gateway): apply configured edge auth to session-URL targets

Follow-up to #125700.

A URL target with explicit auth skipped config loading and silently dropped
gateway.remote.edgeAuth. Config I/O is now skipped only for plaintext loopback
targets.

Also document mandatory passEnv: ["HOME"] for the cloudflared exec provider.

* fix(gateway): keep explicit secure connections working when config is invalid

Addresses the ClawSweeper finding on #125982 by preserving the invalid-config recovery path while still applying configured edge auth.
2026-08-18 14:08:51 -07:00
Peter Steinberger f2158a9c36 feat(sessions): keep durable work visible and auto-archive stale sessions (#124925)
* feat(agents): clarify visible session guidance

* feat(sessions): auto-archive inactive dashboard sessions

* fix(sessions): preserve active dashboard sessions during maintenance

* test(sessions): preserve admitted dashboard sessions during archive

* chore: refresh session generated artifacts

* test: align recovery id with transcript redaction

* fix(sessions): report only committed maintenance counts
2026-08-18 14:02:54 -07:00
Onur Solmaz f5e9622fc9 fix(providers): report request acceptance consistently (#125807)
* fix(providers): report request acceptance consistently

* fix(providers): retain response hook compatibility

* fix(providers): keep legacy response hook path

* fix(providers): distinguish rejected response attempts

* fix(providers): keep acceptance evidence truthful

* fix(google): preserve provider acceptance errors

* test(google): satisfy acceptance callback lint

* fix(google): exclude acceptance hooks from retry deadline

* fix(openai): report Codex websocket acceptance

* fix(openai): commit websocket state before acceptance hook

* fix(google): abort pending acceptance callbacks

* fix(providers): abort pending acceptance callbacks

* fix(mistral): report observed HTTP response

* fix(mistral): report rejected HTTP responses

* fix(providers): derive acceptance from HTTP status

* fix(providers): preserve acceptance lifecycle cleanup

* fix(anthropic): report observed HTTP response

* fix(anthropic): report rejected HTTP responses

* fix(plugin-sdk): expose provider lifecycle

* fix(providers): stop after lifecycle abort

* fix(mistral): cancel unread acceptance failures
2026-08-18 23:50:57 +03:00
Peter Steinberger 549e6349f8 fix(workboard): prevent orphaned runs and overwritten cards (#125951)
* fix(workboard): make ownership updates atomic

Persist launch intent before worker acceptance, reconcile accepted identities,
fence cross-host card mutations, and deduplicate session capture in SQLite.

Closes #125932

* test(workboard): keep race fixtures plugin-local

Use a plugin-local synchronization helper and update the sessions-page capture
expectation for the new store-owned RPC.

* fix(workboard): fence lifecycle and restore races

Apply terminal lifecycle state only while the matched association is current,
and converge concurrent archived session restores on the active winner.
2026-08-18 13:50:17 -07:00
Peter Steinberger 347a0eaf8c feat(ui): activity feed automation grouping, live status, deep-link inspector (#125981)
* feat(ui): collapse automation sessions in activity feed

* feat(ui): show live run status on activity feed rows

* feat(ui): make run inspector deep-link only

* fix(ui): only link inspect run to a current active run

Addresses ClawSweeper P1: a stale observer digest could deep-link a live
row to an ended run's audit record; trust digest runId only when it is
still in activeRunIds.
2026-08-18 13:49:25 -07:00
Peter Steinberger d1a194b52f fix(gateway): refresh edited skills in agent RPC sessions (#125962)
* fix(gateway): watch skills for agent RPC turns

* ci: rebalance hosted agent chat shard
2026-08-18 13:06:48 -07:00
Peter Steinberger d5aff660a2 fix(codex): keep large AGENTS.md instructions visible (#125966)
* fix(codex): raise native project doc budget

Default OpenClaw Codex threads to a bounded 128 KiB aggregate project-document budget so large AGENTS.md chains remain visible. Preserve explicit ordinary-thread overrides and keep restricted or lightweight turns at zero.

* test(codex): refresh project doc config expectations
2026-08-18 12:39:52 -07:00
Peter Steinberger bb92dc61c8 fix: stop --tag main from failing during npm pack (#125949)
* fix: refuse unsupported OpenClaw source package updates

* refactor: narrow main update refusal
2026-08-18 12:22:45 -07:00