Commit Graph

77380 Commits

Author SHA1 Message Date
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
Peter Steinberger 562129d5df fix(doctor): ignore channel metadata during plugin repair (#120891)
* fix(doctor): ignore channel metadata during plugin repair

* test(doctor): avoid unsafe optional chain
2026-08-08 22:38:16 -07:00
Peter Steinberger a996a86f98 test(macos): serialize unread view model suite (#120877) 2026-08-08 22:26:09 -07:00
Peter Steinberger 5ea44f5916 refactor(ui): remove dead Control UI weight (#120870)
* refactor(ui): remove dead Control UI weight

* test(ui): trim redundant preview fixture

* fix(ui): preserve agent file preview behavior
2026-08-08 22:22:32 -07:00
Peter Steinberger c2d3d2ce34 fix(cloud-workers): preserve cleanup across fallback disconnects (#120715)
* fix(cloud-workers): close lifecycle ownership gaps

Own bootstrap cleanup at the operation boundary and make fallback workspace sync converge across retries. Re-establish tunnel readiness per connection, retire placements before destructive session mutation, and keep operator diagnostics lightweight and redacted. Cover destructive lifecycle paths in their original execution order.

* fix(cloud-workers): drain local claims before retirement

delete/reset drain admitted local work, re-read exact identity, retire before destructive cleanup; active-claim/race tests.

* fix(cloud-workers): bind retry cleanup to workspace owner

Attest canonical HOME and the exact managed path.
Revalidate ownership before recursive fallback cleanup.
Cover malicious paths and ownership drift with tests.

* fix(cloud-workers): fence fallback workspace receivers
2026-08-08 22:18:54 -07:00
Vyctor H. Brzezowski 7a727cbb4d fix(ui): show OpenAI plan usage accurately (#120846)
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
2026-08-09 02:16:43 -03:00
Vincent Koc 587def9c9d fix(gateway): keep new nodes compatible with older gateways (#119981)
* fix(gateway): keep new nodes compatible with older gateways

Punchcard-Session: golden-brook-lantern-zp

* fix(gateway): clear protocol compatibility check failures

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): retire manifest before inventory refresh

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): keep new nodes compatible with older gateways

Punchcard-Session: golden-brook-lantern-zp

* fix(gateway): clear protocol compatibility check failures

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): retire manifest before inventory refresh

Punchcard-Session: cobalt-timber-orchard-d1

* docs(gateway-client): describe compatible admission

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): ignore retired publication failures

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): keep new nodes compatible with older gateways

Punchcard-Session: golden-brook-lantern-zp

* fix(gateway): clear protocol compatibility check failures

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): retire manifest before inventory refresh

Punchcard-Session: cobalt-timber-orchard-d1

* docs(gateway-client): describe compatible admission

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): ignore retired publication failures

Punchcard-Session: cobalt-timber-orchard-d1

* test(node-host): split optional publication coverage

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): retain latest rejected inventory

Punchcard-Session: cobalt-timber-orchard-d1

* chore(gateway-protocol): remove release-only changelog edits

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): normalize blank node host families

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): normalize node metadata before pairing

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): negotiate legacy node metadata

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): complete rolling node convergence

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): honor publication retry backoff

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): close rolling compatibility gaps

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): migrate node pairing rollback metadata

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): scope legacy support to wire admission

Punchcard-Session: cobalt-timber-orchard-d1

* test(gateway): type legacy hello protocol fixture

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): converge node protocol after upgrade

Punchcard-Session: cobalt-timber-orchard-d1

* fix(node-host): preserve publication retry backoff

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): honor latest node compatibility state

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): recover protocol negotiation after rollback

Punchcard-Session: cobalt-timber-orchard-d1

* fix(gateway): guard legacy metadata lookup

Punchcard-Session: cobalt-timber-orchard-d1
2026-08-09 13:16:37 +08:00
Peter Steinberger ec866d8abc fix(telegram): clear stale localized command menus (#120885)
* fix(telegram): clear stale localized command menus

* test(telegram): satisfy command menu lint
2026-08-08 22:14:58 -07:00
Peter Steinberger 4b7454bb1c fix(sessions): batch archives no longer repeat full-store work (#120873)
* perf(sessions): batch session patch storage work

Batch archive patches now share store projection, persistence, cron scanning, and direct audit appends so multi-session archives complete without repeated full-store work.

Refs #120871

* fix(ci): remove unused batch archive exports

* test(sessions): inject failures through append-only audit path
2026-08-08 22:12:08 -07:00
Peter Steinberger 192885c4e8 perf(agents): reuse prepared inbound plugin registry (#120879)
* perf(agents): reuse prepared inbound plugin registry

* test(gateway): align sidecar counts after prewarm removal
2026-08-08 22:08:41 -07:00
clawsweeper[bot] a7273a20e4 test(doctor): give SecretRef scenario timeout headroom (#120852)
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
2026-08-09 13:08:23 +08:00
Peter Steinberger 3aec297be0 refactor(sandbox): simplify legacy registry migration (#120895) 2026-08-08 22:03:58 -07:00
Peter Steinberger 6192673da4 perf(doctor): delete the heavy doctor barrel and finish slimming enumeration (#120882)
* refactor(plugin-sdk): delete the heavy runtime-doctor barrel

Nothing may pull the state-db/kysely graph through a doctor barrel anymore.
The barrel's remaining heavy exports move to two narrow private-local
subpaths, each with a single purpose:

- doctor-repair-runtime: install-path diagnosis, plugin config removal, and
  state-database schema detect/repair (matrix doctor, voice-call lazy import)
- plugin-state-store-runtime: the sync keyed-store factory. It stays out of
  plugin-state-runtime because hot channel entrypoints import that at module
  load and opening a store pulls the state-database graph.

Doctor closures also stop pulling ssrf-runtime (fetch-guard + gateway net)
for two legacy private-network helpers that live in the lighter ssrf-policy
subpath: mattermost, nextcloud-talk, tlon, matrix.

The closure guard now forbids the two new heavy subpaths instead of the
deleted barrel, so the invariant keeps being enforced where it still applies.

* perf(doctor): keep heavy graphs out of every doctor closure

Doctor enumeration cold-loads each declaring plugin's contract closure, so
one heavy import in a closure is paid by the whole sweep. Four barrels were
still dragging unrelated graphs in for trivial helpers; each is repaired at
the leaf rather than by caching downstream:

- Legacy private-network config migration moves to a config leaf. It only
  reshapes records, but lived beside the SSRF runtime (DNS, proxy, logging),
  costing mattermost ~2.7s. ssrf-policy re-exports it, surface unchanged.
- Streaming config readers move to a leaf. They read two config keys, but
  streaming.ts also formats tool aggregates, pulling tool-display/logging/
  acp-core; that cost slack ~2.3s.
- signal took the channel-secret barrel for isRecord; the canonical plugin
  record guard is string-coerce-runtime (root AGENTS.md).
- llm-task took the provider-model barrel for parseModelRef, now a narrow
  model-ref-parse subpath.

Full doctor enumeration of all 42 declaring plugins, built mode:
legacy config rules 6668ms -> 1265ms, state migrations 184ms -> 127ms.
No plugin remains an outlier; the slowest is now ~380ms against a ~200ms floor.

Public export surfaces of every touched SDK subpath are byte-identical
(verified by diffing built module exports before/after); the API baseline
hashes move only because re-exported declarations emit differently.

The closure guard gains rules for each repaired barrel so the invariant
holds for future closures.

* fix(release): exclude new private-local declarations from the published package

Same pack-path rule as c41da3759f: private-local subpaths ship without d.ts.

* fix(doctor): repair the closure guard violations that break main

The landed guard fails on main: three closures import heavy barrels for one
symbol each. Two more surfaced once the guard learned about the provider-model
barrel. Each gets a narrow subpath at the leaf:

- telegram sent-message-cache + state-migrations took the session-store barrel
  (session accessor + state-db) for resolveStorePath -> session-store-paths
- discord thread-bindings.state took the channel-outbound barrel (reply
  pipeline + channel registry) for one identity write -> outbound-echo-runtime
- discord model-picker took the provider-model barrel for normalizeProviderId,
  which model-ref-parse now exposes beside parseModelRef

The guard also stops walking artifacts of plugins whose manifest declares no
doctor surface. Such a declaration gates the artifact off every enumeration
path exactly as resolvePluginDoctorContracts does, so its closure cost is never
paid; anthropic ("doctorContract": {}) was being held to a cost it cannot
incur. Absent declarations still load eagerly and stay enforced.

Side effect worth naming: discord's built doctor contract now loads again.
On main both discord and telegram fail to require in packaged builds (an
ESM-only transitive dep) and silently lose their repairs; this restores
discord and takes enumerated legacy config rules from 87 to 99. Telegram's
built artifact still pulls execa through dist chunking - a build-level defect
with a different owner, filed as follow-up.
2026-08-08 22:01:44 -07:00
Peter Steinberger 4e74ae229e perf(gateway): stop penalizing device-token Control UI reads (#120849)
* perf(gateway): skip shared-secret brute-force penalty for valid device tokens

* fix(gateway): preserve trusted-proxy auth penalties

* fix(gateway): preserve device auth during shared lockout

* fix(gateway): decouple control ui auth penalties
2026-08-08 22:00:58 -07:00
Peter Steinberger 150670c64a test(ci): restore source performance isolation guards (#120878)
* test(ci): restore performance isolation guards

* test(ci): exercise source performance isolation
2026-08-08 21:59:18 -07:00
Colin Johnson 5cd184c91b fix(ios): keyboard unavailable after tapping chat composer (#120723)
* fix(ios): restore composer keyboard focus

* test(ios): cover composer focus in screenshot CI

Co-authored-by: Colin <colin@solvely.net>

* test(ios): make composer focus proof device-aware

Co-authored-by: Colin <colin@solvely.net>

* fix(ios): stabilize sidebar layout under keyboard

Co-authored-by: Colin <colin@solvely.net>

* chore(ios): refresh native i18n inventory

Co-authored-by: Colin <colin@solvely.net>

* test(ios): keep focus proof in screenshot helper

Co-authored-by: Colin <colin@solvely.net>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-08 21:56:46 -07:00
Peter Steinberger cb9bf8c173 test(config): isolate recovery fixtures (#120847) 2026-08-09 12:51:26 +08:00
Peter Steinberger 7443882f45 refactor(chutes): move OAuth refresh into provider plugin (#120840)
* refactor(chutes): move OAuth refresh into provider plugin

* test(chutes): prove OAuth refresh load ordering
2026-08-08 21:50:25 -07:00
Peter Steinberger 34062ead20 fix(gateway): allow write-scoped session model changes (#120875) 2026-08-08 21:43:55 -07:00
Peter Steinberger 7f3cc6995b refactor(plugin-sdk): collapse plugin entry type aliases (#120814)
* refactor(plugin-sdk): collapse plugin entry type aliases

* chore(plugin-sdk): refresh plugin entry API baseline
2026-08-08 21:33:29 -07:00
Peter Steinberger 62b833981f fix(windows): preserve unknown port diagnostics (#120845) 2026-08-08 21:33:09 -07:00
Peter Steinberger 7b076155d0 refactor: clarify message channel validation (#120872) 2026-08-08 21:30:22 -07:00
Peter Steinberger 6246f67784 refactor(clickclack): reuse session URL contract (#120810) 2026-08-08 21:22:51 -07:00
Peter Steinberger ee30bb46c2 fix(macos): keep onboarding alive during Local Network permission (#120859)
* fix(macos): wait for Gateway startup owner

* chore(i18n): refresh macOS source inventory

* fix(macos): bound first-install readiness grace
2026-08-08 21:22:14 -07:00
Peter Steinberger 26ee1b4935 fix(doctor): enforce deprecation registry deadlines (#120868) 2026-08-08 21:19:04 -07:00
Peter Steinberger 642b486986 fix(macos): prevent parallel Swift test hangs after coordinator timeouts (#120869)
Make timeout paths cancel or release every pending test continuation before cleanup, so failures cannot poison the remaining Swift suite. Inject the retry sleeper to preserve invalidation-before-backoff ordering without real-time polling.
2026-08-08 21:17:39 -07:00