Commit Graph

78555 Commits

Author SHA1 Message Date
Peter Steinberger 917fd92686 feat(cli): openclaw resume attaches the TUI to a recent session (#120664)
* feat(cli): openclaw resume attaches the TUI to a recent session

Implements docs/plan/runners.md milestone 2.

* fix(cli): resume covers global sessions and preflights TTY

* fix(cli): require a terminal before resume

* fix(cli): adapt resume gateway disconnect state

* fix(cli): preserve global resume ownership

* test(cli): prove qualified global resume crosses the gateway boundary
2026-08-09 02:52:06 -07:00
Peter Steinberger 135278c896 fix(cron): avoid no-op writes and unbounded page copies (#120910)
* fix(cron): avoid no-op writes and unbounded page copies

* fix(cron): preserve read maintenance invariants
2026-08-09 02:40:47 -07:00
Peter Steinberger d0e812e18f refactor(chutes): remove accidental core OAuth shim (#120993)
* refactor(chutes): remove accidental core OAuth shim

* chore(plugin-sdk): refresh API baseline

* chore(plugin-sdk): refresh API baseline

* chore(plugin-sdk): refresh API baseline

* chore(plugin-sdk): refresh API baseline

* chore(plugin-sdk): refresh API baseline
2026-08-09 02:27:27 -07:00
Peter Steinberger 7d4066639e feat(meetings): enable Linux Chrome talk-back (#118451)
* feat(meetings): add Linux audio routing

* chore(plugin-sdk): refresh meeting audio API baseline
2026-08-09 02:13:17 -07:00
Peter Steinberger c708b41af4 fix(beam): open uploads at canonical catalog URLs (#120927)
* fix(beam): emit canonical catalog URLs

* fix(beam): type readonly runtime config

* fix(gateway): keep minimal metadata startup lazy

* chore(plugin-sdk): refresh API baseline
2026-08-09 02:09:01 -07:00
Peter Steinberger 0e56fce87b fix(plugin-sdk): preserve system event snapshot identity (#120984)
Assign queue-owned opaque IDs to modern system-event snapshots so copied stale snapshots cannot acknowledge a later identical event. Keep structural matching only for shipped legacy ID-less consumers.
2026-08-09 02:05:36 -07:00
Peter Steinberger 00854a7002 fix(macos): proper provider brand icons + softer contrast in onboarding AI setup (#120907)
* fix(macos): let AI setup proceed when the login keychain is unavailable

A missing/locked login keychain made GatewayActivationBindingKeyStore
unable to mint the activation binding key, and onboarding refused every
candidate and manual-key activation with 'Secure storage is unavailable'.
The fingerprint only protects the crash/relaunch resume receipt, so
degrade instead of refusing: write an ownerless pending record (still
matched exactly, never as a wildcard), keep the full activation-ambiguity
window, and skip only restart reconciliation, which needs fingerprint
proof by design. A relaunch then repeats activation rather than trusting
the receipt.

Reported by Peter Steinberger.

* fix(macos): render proper provider brand icons in onboarding AI setup

Nearly every provider icon URL the gateway sends is a simpleicons.org
SVG, which AsyncImage cannot decode, so the Connect your AI page fell
back to generic symbols for every tool and provider; the two GitHub
avatar PNGs that did render clashed as full-color rasters.

Bundle nine monochrome template marks (Simple Icons CC0; xAI from
LobeHub icons, MIT) and resolve them local-first by brand id/kind,
including composed choice ids like xai-oauth. Remote icons now load via
NSImage(data:), which decodes SVG, with vector payloads tinted as
templates so plugin-supplied icons blend too. Every glyph sits in a
uniform rounded well; install cards show host-only links, hover states,
and a softer translucent surface shared by all setup sections instead
of controlBackgroundColor.

Requested by Peter Steinberger.

* fix(macos): use failable UTF-8 decode in icon vector sniffing (swiftlint)

* fix(macos): address ClawSweeper review of onboarding icon/keychain changes

- Refuse relaunch handoff from ownerless (keychain-unavailable) completed
  receipts at the reconciliation trust boundary; such receipts can belong
  to replaced credentials, so setup repeats a fresh activation instead.
- Decode and pass the canonical brandId the gateway sends for candidates,
  auth options, and manual providers so bundled marks resolve for opaque
  choice ids.
- Scan the bounded XML prolog (comments, declarations, doctype) when
  sniffing remote SVG payloads; comment-prefixed vectors now tint as
  templates.

* refactor(macos): move setup error enum to support file (swiftlint file length)

* chore(i18n): refresh native source inventory

* fix(macos): give keychain-unavailable activations attempt-specific unbound leases

A nil owner made concurrent unbound attempts indistinguishable: a stale
attempt's delayed response could complete or clear a newer attempt's
record. Unbound attempts now mint a random per-attempt lease id with a
sentinel fingerprint — live matching stays attempt-exact, restart
reconciliation's fingerprint guard rejects them, and relaunch
verification refuses unbound receipts before any handoff.

* chore(macos): ship third-party artwork notices with provider icons

Simple Icons (CC0) attribution and the LobeHub Icons MIT license text
for the xAI mark now travel inside the bundled ProviderIcons directory.

* fix(ci): refresh plugin-sdk API manifest for private-type hashing

#120975 changed the baseline generator to hash private types but landed
without regenerating the manifest; the check-plugin-sdk-api-baseline
lane was gated off on that PR and first failed here. Regenerated via
pnpm plugin-sdk:api:gen with no SDK surface change in this branch.
2026-08-09 01:49:50 -07:00
Peter Steinberger 29c442d483 fix(ci): recheck ClawSweeper PR ack marker before posting (#120990)
Propagates the canonical dispatcher step from openclaw/clawsweeper#1083
byte-identically: the acknowledgement step waits 15s after a clean
marker check and rechecks immediately before posting, so near-simultaneous
opened and ready_for_review runs (draft PR marked ready within seconds,
as on #120974) post exactly one receipt ack.
2026-08-09 01:37:34 -07:00
Peter Steinberger 7cf4f9aa6a refactor(acp): split grandfathered translator and event-ledger files (#120941)
* refactor(acp): split translator and event ledger

* refactor(acp): keep sqlite ledger owner stable
2026-08-09 01:23:11 -07:00
Peter Steinberger a5cad30645 test(ui): stabilize history and reconnect e2e races (#120732) 2026-08-09 01:18:57 -07:00
Peter Steinberger 7af8e129d6 refactor(acp): collapse SDK and lazy runtime shims (#120958) 2026-08-09 01:08:24 -07:00
Peter Steinberger 92f4af79f0 fix(agents): bound session lock teardown safely (#120921) 2026-08-09 01:08:09 -07:00
Peter Steinberger 411777dc1f fix(gateway): recover cloud worker placement state (#120976)
* fix(gateway): recover cloud worker placement state

Related: #120953

* test(gateway): type failed placement fixture

Related: #120953
2026-08-09 01:01:31 -07:00
Dallin Romney dcdbd7aab6 fix(update): prevent stable upgrade notices on extended-stable (#118518)
* fix(update): keep extended-stable update notices on channel

* fix(update): repair extended-stable CI checks

* fix(update): retain verified extended-stable channel

* fix(update): normalize gateway install surface

* test(update): split effective channel coverage

* fix(update): resolve verified extended-stable status paths

* fix(update): preserve Sparkle fallback on missing channel

* fix(update): restore effective channel after rebase

* fix(update): repair rebased CI coverage
2026-08-09 16:01:14 +08:00
Peter Steinberger da463bfef4 fix(gateway): hydrate auth snapshots at startup (#120977)
Refs #120951.
2026-08-09 00:55:07 -07:00
Peter Steinberger e09b0ebfba fix(plugin-sdk): detect private type changes in API baseline (#120975)
* fix(plugin-sdk): hash private declaration dependencies

* chore(plugin-sdk): refresh API baseline
2026-08-09 00:52:34 -07:00
Peter Steinberger cc4cc83e36 refactor(acpx): remove dead config keys (#120937) 2026-08-09 00:50:12 -07:00
Goutam Adwant 13cb098cab fix(cron): remove deleted job sessions (#119520)
* fix(cron): remove deleted job sessions

* fix(cron): guard deferred session cleanup

* test(cron): remove invalid cleanup await

* fix(cron): fence deferred session cleanup

* fix(cron): share removal cleanup fence

Co-authored-by: Goutam Adwant <workwithgoutam@gmail.com>

* fix(cron): preserve stored add result type

Co-authored-by: Goutam Adwant <workwithgoutam@gmail.com>

* fix(cron): release lock before session cleanup

Co-authored-by: Goutam Adwant <workwithgoutam@gmail.com>

* fix(cron): avoid materializing cleanup store

Co-authored-by: Goutam Adwant <workwithgoutam@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-09 00:49:54 -07:00
Dallin Romney 389c10217c improve(wizard): clarify security disclaimer copy (#120172)
* improve(wizard): clarify security disclaimer

* improve(wizard): retain security disclaimer title

* improve(wizard): strengthen personal-use disclaimer

* improve(wizard): clarify shared-agent isolation

* improve(wizard): restore direct prompt warning

* improve(wizard): restore direct tool warning

* improve(wizard): simplify security disclaimer
2026-08-09 15:49:48 +08:00
Peter Steinberger 5bd623c4b6 feat(macos): open dashboard as soon as onboarding inference connects (#120950)
* feat(macos): open dashboard as soon as onboarding inference connects

* chore(i18n): remove retired setup helper strings

* fix(i18n): keep generated locales isolated
2026-08-09 00:47:43 -07:00
Peter Steinberger e839d4b6de fix(mcp): preserve client and requester lifecycle ownership (#120894)
* fix(codex): preserve MCP discovery client ownership

* fix(codex): close MCP client lifecycle gaps

* test(gateway): isolate profile avatar state

* test(gateway): use immutable cleanup ordering
2026-08-09 00:47:32 -07:00
Peter Steinberger 499d81cdbd perf(plugins): make every plugin closure statically kysely-free and guard it transitively (#120876)
* perf(plugins): close the last kysely closure chains and guard reachability transitively

Follow-up to #120698/#120811/#120882: the closure guard's enumerated barrel
bans cannot catch new heavy edges, and two closures still statically reached
kysely on main.

- guard: add a transitive kysely-reachability test that walks static value
  imports from every doctor-contract and legacy-setup closure through plugin,
  plugin-sdk, and relative core graphs, failing with the full import chain;
  type-only and lazy dynamic imports stay allowed
- llm-task/model refs: manifest-model-id-normalization reads snapshots
  through a registration-slot runtime bridge (snapshot modules register at
  eval; require fallback covers cold processes) and
  current-plugin-metadata-state moves its process-scoped facts onto a
  globalThis singleton so dual module instances share published state
- telegram: split thread-bindings-store.ts (pure record shapes + legacy-file
  readers) out of the acp-runtime-heavy manager, delete the consumer-less
  testing export, move the pure bot-user-id token parse to
  token-fingerprint.ts, and lazy-import token.js in the async update-offset
  detector

llm-task enumeration drops to ~0.8s/157 modules cold; every closure is now
statically kysely-free and stays that way by construction.

* fix(telegram): repoint the native-command menu state at the token-fingerprint parser
2026-08-09 00:39:45 -07:00
Dallin Romney 4847655826 fix(cua-computer): ignore retired driver path (#120502) 2026-08-09 15:34:30 +08:00
Peter Steinberger 266ad72be9 fix(gateway): keep listener live when restart state is invalid (#120966)
* fix(gateway): preflight database state before reload

* fix(gateway): wire managed restart readiness
2026-08-09 00:28:48 -07:00
Peter Steinberger 2f50cc8b64 refactor(plugin-sdk): remove unused lazy fallback (#120974) 2026-08-09 00:24:51 -07:00
Vincent Koc bccf65938e fix(recovery): fence reply admission across owner release (#120935)
Punchcard-Session: amber-workshop-workshop-36
2026-08-09 15:17:02 +08:00
Peter Steinberger 79c0524992 refactor(outbound): reuse prepared channel plugins (#120946)
* refactor(outbound): reuse prepared channel plugins

* fix(outbound): preserve legacy channel docking

* style(outbound): format rebased channel selection
2026-08-09 00:16:14 -07:00
Peter Steinberger adcf5bd93a ci: acknowledge pull request receipts in clawsweeper dispatch (#120934)
Propagate the receipt-acknowledgment steps from the canonical
ClawSweeper dispatch template (openclaw/clawsweeper#1080): mint a
minimal issues:write App token and post an idempotent
clawsweeper-pr-ack marker comment for non-draft opened and
ready_for_review pull requests, before review dispatch.
2026-08-09 00:15:08 -07:00
Peter Steinberger 1b59c28164 refactor(agents): simplify prepared registry dispatch (#120963) 2026-08-09 00:14:44 -07:00
Peter Steinberger caf7762176 fix: bound outbound bootstrap state and preserve workspace locks (#120939)
* fix(outbound): bound channel bootstrap outcomes

* fix(cloud-workers): preserve workspace lock controller ownership
2026-08-09 00:08:51 -07:00
Peter Steinberger 6ad761a36b test(infra): budget full heartbeat admission proof (#120955) 2026-08-09 00:04:37 -07:00
Peter Steinberger f67da420f6 feat(ui): labs-gated CLI agent targets in new-session model picker (#120949)
* feat(config): gate CLI agent discovery

* feat(ui): add CLI agents to model picker
2026-08-09 00:00:00 -07:00
Peter Steinberger 8ede4046e2 fix(cli): guard embedded agent state ownership (#120896) 2026-08-08 23:59:50 -07:00
Peter Steinberger 7dc4dc83fe fix(infra): wait for concurrent startup-migration lease instead of failing gateway startup (#120959) 2026-08-08 23:56:15 -07:00
Vincent Koc 1b404a1755 fix(release): accept repeated PR title suffixes (#120948) 2026-08-09 14:49:39 +08:00
Peter Steinberger dba99b355b fix(mac): fail fast without full Xcode (#120909) 2026-08-08 23:42:36 -07:00
Ayaan Zaidi a3d2ac7dc8 fix(telegram): inherit root group policy across accounts
Use channels.telegram.groups as the shared default when an account omits groups. Explicit account maps, including {}, remain full replacements. This keeps chat admission and sender restrictions on one policy path and fixes silent multi-account authorization failures.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-09 12:08:53 +05:30
Peter Steinberger 5297429b3e fix(gateway): keep task suggestions recoverable (#120940)
Abandon unexpected acceptance failures instead of leaking accepting slots. Reject non-Git or blank suggestions before side effects, and protect unseen pending suggestions ahead of accepted replay state.
2026-08-08 23:38:50 -07:00
Peter Steinberger 5f14d4631a refactor(plugin-sdk): unify lazy channel config schemas (#120938)
* refactor(plugin-sdk): unify lazy channel config schemas

* fix(plugin-sdk): preserve channel schema contract types
2026-08-08 23:36:14 -07:00
Peter Steinberger 4c2d8d8adb fix(doctor): migrate legacy agent databases and bound registry writes to the active state dir (#120906)
* fix(doctor): migrate legacy agent databases discovered on disk and bound registry writes to the active state dir

* fix(doctor): discover configured agent databases without registry rows

* fix(doctor): preserve filesystem and configured database identity

* fix(doctor): prioritize configured agent database identity

* fix(doctor): prefer recorded agent database ownership
2026-08-08 23:34:38 -07:00
Peter Steinberger 1fc9d15804 refactor: simplify message channel routing (#120925)
* refactor: simplify message channel routing

* test: complete message channel resolution mocks
2026-08-08 23:32:01 -07:00
Peter Steinberger 3bfe82180e fix(gateway): unbreak cloud session creation — stale chat metadata, unbounded tunnel hangs, swallowed dispatch errors (#120926)
* fix(gateway): rebuild chat metadata when auth-profile snapshots change

chat.metadata cached a prepared generation built before the runtime
auth-profile store snapshot was published (empty-store fallback) and
generationFactsMatch never compared auth state, so the Control UI showed
"No models available" after a gateway restart until an unrelated config
edit. Capture per-agent auth snapshot revisions in the generation facts,
subscribe the metadata lifecycle to auth-store mutations, and run one
awaited revision-aware catch-up refresh after listener registration so
publications that precede registration are still observed.

* fix(gateway): bound cloud worker tunnel startup and surface dispatch failure detail

Live stress-testing the Control UI cloud flow found sessions.dispatch
hanging unbounded (observed 12+ min) when the worker SSH tunnel could
not connect: the runner's exited promise settled only on "close" (a
spawn error never settled it), the reconnect loop swallowed every
failure with no logging, the poisoned ready promise was re-handed to
every later dispatch, and dispatch errors dropped the actionable reason
recorded in worker_environments.last_error.

- settle exited on the real "exit" event, wire the owner abort signal
  into spawn, bound stop()'s post-SIGKILL wait, and fail stop honestly
  when termination is unconfirmed instead of fabricating an exit
- add a 60s per-attempt readiness deadline and log each failed connect
  attempt (bounded, redacted); keep an unconfirmed child tracked and
  wait for its real exit before retrying
- add a 3-minute epoch-fenced startTunnel deadline with a typed,
  actionable error; detach its cleanup so the deadline holds
- append the bounded recorded reason to the five dispatch-visible
  worker environment error messages (docs already promise these)
- remote socket setup: drop "--" from chmod (BSD/macOS chmod treats it
  as a filename), which blocked every tunnel to a macOS worker host
- workspace quiescence: tolerate EPERM without crashing the protocol
  while keeping unsignalable freeze targets counted as live so
  quiescence fails closed

* test(gateway): type worker child kill mock
2026-08-08 23:28:51 -07:00
Peter Steinberger bb799aec0f refactor(plugin-sdk): simplify plugin entry contracts (#120930)
* refactor(plugin-sdk): simplify plugin entry contracts

* fix(plugin-sdk): keep suppression context barrel live
2026-08-08 23:24:44 -07:00
Peter Steinberger 54ae94530c refactor(approvals): simplify resolver plumbing (#120923) 2026-08-08 23:09:24 -07:00
Peter Steinberger a8f8fd3256 fix(macos): prevent shared state in parallel test suites (#120912)
* fix(macos): isolate parallel test state

* chore(i18n): refresh native source inventory
2026-08-08 23:03:20 -07:00
Vincent Koc 13e9bf2317 fix(qa): use current voice call runtime generation (#120920)
Punchcard-Session: amber-workshop-workshop-36
2026-08-09 14:01:40 +08:00
Peter Steinberger b164a4222e refactor(plugins): simplify activation compatibility flow (#120928) 2026-08-08 22:59:25 -07:00
Peter Steinberger d7133e7df6 fix(telegram): preserve direct messages topic routing (#120916)
Replies, previews, and media in channel Direct Messages topics now remain in their originating topic. Bot-private and forum topic routing remains unchanged.
2026-08-08 22:53:35 -07:00
Peter Steinberger c315a94682 refactor(doctor): simplify deprecation registry metadata (#120922) 2026-08-08 22:53:16 -07:00
Peter Steinberger 7a8eee4a36 perf(agents): keep turn-path model catalog reads off the full live build (#120834)
* perf(agents): keep turn-path model catalog reads off the full live build

First agent turns (embedded and cron) resolved thinking capability through
loadPreparedModelCatalogSnapshot without readOnly, which materialized the
full live model-runtime catalog: ambient synthetic-auth discovery fanned out
to every registered provider and loaded plugin discovery modules through
jiti source transform (3,172 TS modules, 36s event-loop block, +600MB heap,
58.7s model-selection on a cold gateway).

- add loadProviderScopedThinkingCatalog: manifest metadata first, then a
  provider-scoped read-only static catalog, then scoped live discovery only
  for runtime-discovery providers (preserves #116584 Ollama semantics)
- route scopedLiveProviderDiscovery through the scoped read-only loader
- scope live-mode ambient synthetic-auth refs to the requested providers
- bound the last-resort synthetic-auth sweep to discovery entry modules
- memoize per-turn plugin skill dir resolution/republish (single-slot,
  lifecycle-cleared; was a full walk + symlink republish every turn)

Cold first turn 72.7s -> ~22s wall (remaining cost is provider prefill of
the ~19.5k-token default prompt); model-selection 58,726ms -> 124ms.

* test(agents): align model-catalog.runtime mocks with scoped thinking catalog seam

Explicit vi.mock factories must export every binding prod touches; the new
loadProviderScopedThinkingCatalog export is now mocked everywhere the module
is stubbed, and the live-model-switch Ollama hydration test asserts the new
provider-scoped seam instead of the retired unscoped snapshot call shape.

* test(agents): export scoped thinking catalog from every prepared-catalog mock; split synthetic-auth helpers

- add loadProviderScopedThinkingCatalog to all explicit prepared-model-catalog
  and model-catalog.runtime mock factories (vi.mock factories must export every
  binding prod touches)
- move synthetic-auth ref scoping/resolution into
  prepared-model-runtime.synthetic-auth.ts; keeps facts under the max-lines cap

* test(agents): prove scoped thinking hydration for runtime-only models

Boundary proof for the ClawSweeper review gap: the three-tier helper stops at
manifest or scoped-static when they resolve, and runs provider-scoped live
discovery (no broad fanout) only for runtime-only models; cron selection
hydrates through the same scoped helper and skips it entirely for thinking=off.

* test(agents): accept rest args in scoped thinking catalog mocks
2026-08-08 22:48:40 -07:00