Commit Graph

81146 Commits

Author SHA1 Message Date
Peter Steinberger 5fe0e94a79 fix(macos): consume outbox queue result 2026-08-20 19:26:10 -07:00
Peter Steinberger 90dbdc5767 test(mantis): simplify platform gates 2026-08-20 19:00:39 -07:00
Peter Steinberger a56a52af92 test(mantis): gate Linux process fixtures 2026-08-20 18:59:20 -07:00
Peter Steinberger 6ab7968f6e test(node-host): track temporary directories 2026-08-20 18:31:20 -07:00
Peter Steinberger e255730ddc fix(macos): root elevation worker build 2026-08-20 18:26:46 -07:00
Peter Steinberger d6677b91d2 fix(ci): cover mac worker build config 2026-08-20 18:26:46 -07:00
Peter Steinberger a7754747c0 fix(macos): bind elevation runtime to app source 2026-08-20 18:26:46 -07:00
Peter Steinberger 07c8b42a71 fix(channels): preserve delivery after preview cleanup (#126922) 2026-08-20 18:18:25 -07:00
zhanxingxin1998 2064e416e3 fix(setup): preserve chat handoff during inference repair (#109938)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-20 18:16:14 -07:00
Sasan 034325d3e2 fix(ui): surface provider-usage failures instead of silent empty panels (#120309)
* fix(ui): surface provider-usage failures instead of empty panels

* fix(ui): complete typed route-data fixtures and stop reporting cancelled usage requests as failed

- Add providerUsageUnavailable to the five UsageRouteData fixtures in
  gateway-source-replacement.test.ts; check-test-types passes again.
- requestProviderUsage reports failed only for non-cancelled rejections; an
  aborted request is the caller superseding its own load, not an outage.
- Cover answered, failed, and cancelled outcomes.

* chore(ui): keep ProviderUsageFetch local to its module

* fix(ui): clear the provider failure flag when an aggregate usage load fails

- A failed aggregate refresh says nothing about provider usage; the stale
  flag no longer keeps claiming the last provider request failed after a
  later usage.cost or sessions.usage rejection.
- Sequential regression: usage.status failure, then an aggregate failure,
  ends with the flag cleared.

* test(ui): type the usage route data on the test element

* test(ui): cover provider usage request outcomes

* fix(ui): model provider usage request outcome

* fix(ui): preserve provider usage outcomes

* fix(ui): resolve provider usage build
2026-08-20 18:15:14 -07:00
Peter Steinberger 319df0e7a1 test: trim plugin test duplicates (#126917) 2026-08-20 18:07:27 -07:00
Peter Steinberger 7e87d77261 fix(auth): report the database that actually holds an agent's profiles (#126918)
`openclaw models auth list` printed `Auth state store:
<state>/agents/main/agent/openclaw-agent.sqlite` on every install created since
a8a9f284fb, and that file does not exist. Credentials now persist in the shared
state database, so an operator debugging auth was sent to the wrong file while
the listed profiles resolved correctly from somewhere else.

`resolveAuthStorePathForDisplay` and `resolveAuthStatePathForDisplay` named the
agent-local file whenever an agent dir was supplied. That matched storage before
shared-auth ownership moved and stopped matching afterwards. The same helpers
feed `models auth order`, `models list --status`, the auth overview, two
auto-reply directive surfaces, and the `path` field of doctor's auth
HealthFindings, so structured diagnostics pointed at the wrong file too.

Display now mirrors the loader's own selection: an agent with a local auth store
shows its own database, otherwise the shared owner. Both helpers move to the
`paths.ts` barrel so they can consult `hasLocalAuthProfileStoreSource` without a
cycle back through `path-resolve`. Nothing about storage or loading changes.

`model-auth-provider` no longer derives the agent dir from the store path -- that
would have reported the state directory once the shared owner is selected -- and
uses the caller's agent dir instead.

Production -4 LOC.
2026-08-20 18:05:50 -07:00
Josh Avant a042125170 fix(memory): preserve provenance across dreaming (#126489)
* fix(memory): preserve provenance across dreaming

* fix(build): preserve bundled hook metadata

* refactor(build): remove obsolete directory helper

* test(memory): align provenance fixtures

* test(memory): type consolidation run options

* test(memory): register write provenance siblings

* fix(memory): preserve legacy provenance registration

* fix(memory): make provenance provider-independent

* fix(memory): canonicalize provenance workspace keys

* fix(memory): keep provenance mutation host-private

* fix(build): track runtime postbuild implementations

* fix(build): verify bundled hook metadata outputs
2026-08-20 17:58:31 -07:00
Peter Steinberger afb430d10f fix(cli): render sandbox JSON failures (#126915) 2026-08-20 17:56:20 -07:00
Peter Steinberger df2cc8f259 fix(onboard): honor secret-input-mode ref for the generated gateway token (#126877)
* fix(onboard): honor secret-input-mode ref for the generated gateway token

`openclaw onboard --secret-input-mode ref` was silently ignored for
`gateway.auth.token`: onboarding generated the token and wrote it into
`openclaw.json` as a plaintext string, so `openclaw doctor` warned about
`gateway.auth.token` on the install it had just created. The flag was
honored for provider credentials, so an operator who explicitly opted into
references still ended up with a plaintext secret and a remediation
(`openclaw secrets configure`) that cannot migrate a self-generated value,
because it validates a ref by resolving one that already exists.

Setup mints this token itself, so reference mode now provisions it:

- an ambient OPENCLAW_GATEWAY_TOKEN keeps an `env` ref to that variable, so a
  later rotation stays authoritative instead of being pinned by a stale copy
- anything else (freshly generated, or an existing plaintext token being
  migrated) goes into the shared SQLite secret store as a write-only `secret`
  entry, with config holding only `{source:"store",...}`

An existing store entry wins over a freshly generated one, so reruns never
rotate a token already paired with clients. The store write precedes the
config write: a ref persisted without its value would leave the gateway
unauthenticatable, while an orphaned entry is reused by the next run.

The interactive wizard had the same dead end and is fixed the same way.
Default (plaintext) onboarding is unchanged.

User impact: `--secret-input-mode ref` now keeps the gateway token out of
openclaw.json, and a fresh install no longer self-reports a plaintext-secret
warning.

* test(onboard): split gateway onboarding suite under the max-lines gate

The added gateway auth-token tests pushed
onboard-non-interactive.gateway.test.ts to 1014 lines, over the max-lines
limit (check-lint-core-3). Repo policy is to split, never suppress.

Extract the shared vi.mock/harness preamble into
onboard-non-interactive.gateway.test-mocks.ts, following the existing
agent-command.test-mocks.ts pattern, and move the four gateway auth-token
storage tests into their own suite. The reachability mock becomes a holder
object so both suites can swap it across the module boundary, and hoisted
mocks are re-exported in a separate export clause because Vitest rejects
exporting a vi.hoisted binding at its declaration.

Test set is unchanged: the it-declaration multiset matches the pre-split
file exactly, with no duplication across the two suites.

* test(onboard): give the shared gateway onboarding mocks unique export names

check-export-name-collisions flagged `runtime` and `readConfigFileSnapshotMock`
as colliding with program.test-mocks.ts and plugins-cli-test-helpers.ts once the
gateway onboarding preamble became a shared module. Rename the exports to
gatewayOnboardRuntime / gatewayOnboardConfigSnapshotMock per the repo's
unique-export-name rule; suites alias them locally so the assertions read the
same as before.

* test(tooling): route the new gateway auth-token suite from its test helper

test-projects asserts which suites a change to
onboard-non-interactive.test-helpers.ts should run. The new
onboard-non-interactive.gateway-auth-token.test.ts imports that helper, so it
belongs in the expected routing plan.
2026-08-20 17:46:59 -07:00
Josh Lehman 133d5fff6c fix(cron): deliver current-session completions to the source chat (#126860)
* fix(cron): persist current-session completions

* test: refresh cron prompt snapshots

* fix(cron): preserve current-session completion delivery

* fix(cron): defer current-session awareness until commit failure
2026-08-20 17:44:10 -07:00
Peter Steinberger f0881cfaa9 test: trim native test mirrors (#126896) 2026-08-20 17:41:18 -07:00
Josh Avant 3d77a28da8 fix(gateway): enforce incognito session access (#126897) 2026-08-20 17:27:26 -07:00
Patrick Erichsen 987d314181 fix(onboard): honor explicit system agent (#126861) 2026-08-20 17:15:02 -07:00
Peter Steinberger 500fd2cac9 refactor(codex): separate exec session transport (#126859) 2026-08-20 17:10:26 -07:00
Peter Steinberger a73166b49d fix(cli): render QR JSON failures (#126884) 2026-08-20 17:02:59 -07:00
Peter Steinberger a0786cf741 perf(matrix): replace lease drain test waits with fake timers (#126885) 2026-08-20 17:01:23 -07:00
Peter Steinberger 91b8a03453 fix(ui): recover failed new-session navigation without duplicate tasks (#126873)
* fix(ui): preserve committed sessions when chat navigation fails

* test(ui): keep committed-session retry fixtures fully typed
2026-08-20 16:27:26 -07:00
Peter Steinberger e78b9d3ce4 fix(install): defer success until verification (#126871) 2026-08-20 15:57:11 -07:00
Vincent Koc fa71a6f27b fix(qa): isolate packaged mock auth bootstrap (#126247)
* fix(qa): isolate packaged mock auth config

Punchcard-Session: frost-orchard-lantern-ze
(cherry picked from commit 648bd40a4f)

* fix(qa): scrub inherited shell startup env

* fix(qa): block exported Bash functions
2026-08-21 06:51:34 +08:00
Peter Steinberger 40e3ab8784 fix(heartbeat): report the cadence of active agent heartbeats (#126869) 2026-08-20 15:48:19 -07:00
Peter Steinberger b00734bd4c fix(plugins): invalidate replaced web runtime artifacts (#126867) 2026-08-20 15:43:21 -07:00
Vincent Koc c19bdb3a1d fix(agents): preserve explicit harness runtime selection (#126259) 2026-08-21 06:32:23 +08:00
Conan-Scott 7c959c85f9 fix(openai): preserve OAuth realtime session policy (#126363)
Co-authored-by: Clawdbot <clawdbot@apilab.us>
2026-08-20 15:17:03 -07:00
Eden c972fda893 fix(channels): keep started ingress deliveries admissible after their inherited root releases (#126590) 2026-08-20 15:10:34 -07:00
Peter Steinberger 6c9aae7cee fix(firecrawl): prevent canceled requests from caching late results (#126857) 2026-08-20 15:09:38 -07:00
Peter Steinberger 6086ccb85b fix(gateway): own post-ready drain cancellation (#126855) 2026-08-20 15:05:18 -07:00
Sarah Fortune 67bcea131e feat(slack): add compact commentary progress (#126480)
* feat(slack): add compact progress style

* chore(slack): protect compact progress contract

* chore(slack): clarify compact progress comment

* chore(slack): document compact task card behavior

* chore(slack): document compact draft card behavior

* chore(slack): document compact progress config contract

* fix(slack): enforce compact commentary-only progress

* chore(slack): strengthen compact style guard

* fix(slack): type compact progress config

* fix(slack): scope compact plan suppression

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-20 15:02:33 -07:00
Ben Badejo 784a228781 fix(matrix): recover after late leases drain (#126712)
Co-authored-by: Benjamin Badejo <ben@benbadejo.com>
2026-08-20 14:44:29 -07:00
Peter Steinberger d00cbd1593 fix(web-fetch): honor Unicode BOM before HTTP charset (#126854) 2026-08-20 14:43:35 -07:00
Peter Steinberger a8a9f284fb fix(auth): create a fresh install with canonical shared-auth ownership (#126783)
* fix(auth): create a fresh install with canonical shared-auth ownership

A brand-new install was born in the retired shape. `parseSharedAuthStoreOwnership(undefined)` returns
`legacy-main`, which is the correct compat answer for an existing install whose profiles really do
live in the main agent database -- but a new install has no ownership row and no legacy data either,
so onboarding wrote its first credential into `agents/main/agent/openclaw-agent.sqlite` and the
operator's very first `openclaw doctor` told them to run a migration for state OpenClaw had created
seconds earlier. The main agent also stayed undeletable until they did.

Record `auth.sharedStore = {"location":"state-db"}` when the shared store is first written and the
legacy source provably holds nothing: no `auth_profile_store` row, no `auth_profile_state` row, and
no unfinished cleanup ledger entry. Any legacy row, or any inspection error, leaves ownership alone
so doctor keeps owning the relocation. The check is memoized per ownership generation with a WeakSet
keyed on the process-stable ownership object, so a legacy root is inspected once per process and
doctor's committed flip naturally invalidates it.

The legacy row inspection moves out of `state-migrations.shared-auth-store.ts` into the auth-profiles
owner so doctor and runtime share one contract instead of runtime importing migration code. Explicit
main-agent credential writes now follow the shared target, which is a no-op on legacy roots where
both routes already resolve to the same file.

No SQLite schema change; the ownership row is data. Existing installs take exactly the path they take
today.

* fix(auth): preserve JSON-era shared credentials

* docs(auth): explain why doctor names the main agent dir during a shared JSON import

* test(auth): assert shared-owner runtime reads

* test(doctor): read migrated catalog credentials through the shared owner

A fresh root records state-db shared ownership, so the model-catalog credential migration persists into the shared store rather than the agent file. The assertion read the agent file directly and saw an empty store while all three credentials were present and correct in state/openclaw.sqlite. Read through the owner for that state root instead of pinning storage layout; the credential contents are still asserted exactly.
2026-08-20 14:39:11 -07:00
Peter Steinberger 1d3d65e924 fix(workers): preserve results after scratch cleanup (#126849) 2026-08-20 14:29:54 -07:00
Peter Steinberger cd5002610d fix(web-fetch): extract readable content from XHTML pages (#126835) 2026-08-20 14:26:50 -07:00
Eden 4c52d3fe9d fix(cli): message send cannot address channels from npm-installed plugins (#126700)
* fix(cli): message send cannot address channels from npm-installed plugins

Target resolution, channel enumeration, and target-prefix inference only consulted the process-root channel registry, so message CLI actions running against a scoped registry handle could not see installed channel plugins even though selection and send execution could. Carry the selection-resolved plugin into target resolution, fall back to the registry handle in scope for resolver-owned lookups, and list runtime-visible channel plugins for channel selection and prefix inference.

* fix(cli): keep runtime-visible channel reads import-light

Importing channel-resolution from the target-prefix leaf pulled the plugin bootstrap/loader graph into every consumer and reordered module loading under distant vi.mock factories (subagent-registry.steer-restart failed in CI with a hoisting TDZ). Move the scoped-registry reads into a dedicated import-light module, share its registry matcher with channel-resolution, and drop the mock workarounds the heavier graph had required.

* chore(ui): re-baseline startup JS for the outbound scoped-registry reads

CI measured 348285 B gzip on the merge ref (baseline 347023 + 1056 tolerance). The first CI round measured 347784 B, so most of the growth is main-side drift since the 2026-08-19 baseline; the outbound changes account for roughly 60 B in a local A/B. Updated with the documented --update-baseline --startup-js-bytes flow using the CI value.

* Revert "chore(ui): re-baseline startup JS for the outbound scoped-registry reads"

This reverts commit f60bd4c45f.

* fix(cli): plan broadcast accounts from runtime-visible channel plugins

The unscoped message broadcast --account planner still enumerated only process-root plugins, so a registry-scoped installed channel could not join broadcast candidate planning. Use the runtime-visible read and cover the scoped and no-scope paths.

* fix(cli): honor scoped channel plugin precedence

* fix(outbound): preserve loaded plugin fallback order

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-20 13:56:01 -07:00
Peter Steinberger 1362490b80 refactor(sandbox): canonicalize backend ownership (#126828) 2026-08-20 13:52:15 -07:00
Peter Steinberger 21bab3a8ac fix(gateway): honor local port for usage and stability queries (#126832) 2026-08-20 13:51:36 -07:00
Peter Steinberger 96cb0b9b49 fix(ui): retire stale tools and skills after reconnects (#126826) 2026-08-20 13:47:31 -07:00
Peter Steinberger 6b3f7272dc fix(plugin-state): bound expired row cleanup (#126827) 2026-08-20 13:42:18 -07:00
Peter Steinberger ea77d4c708 fix(plugins): fence stale config-scoped loader failures (#126829) 2026-08-20 13:35:24 -07:00
Peter Steinberger a4178c7eb1 fix(discord): demote expected command truncation logs (#126824) 2026-08-20 13:26:44 -07:00
openclaw-mantis[bot] ddf73d4ca2 chore(ui): refresh control ui locales (#126614)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-20 13:16:10 -07:00
joshavant b52d2f08f5 fix(ci): trust maintainer-authored dependency changes 2026-08-20 15:09:22 -05:00
Peter Steinberger 97c0455add fix(tui): route messages to the replacement agent session (#126820) 2026-08-20 13:04:25 -07:00
Josh Avant a4901b6291 fix(gateway): preserve managed Tailscale ingress compatibility (#126519)
* fix(gateway): accept tailnet peers on managed Funnel

* fix(gateway): release Tailscale claim on interrupt

* test(gateway): cover Funnel tailnet ingress

* docs: remove Tailscale changelog entry
2026-08-20 13:04:06 -07:00
ZYV5ge adc608401e fix(control-ui): queue distinct repeated submissions instead of dropping user actions (#118884)
* fix(control-ui): preserve distinct identical chat submissions

Co-authored-by: ZYV5ge <39863830+ZYV5ge@users.noreply.github.com>

* fix(control-ui): keep submission guard key immutable

Co-authored-by: ZYV5ge <39863830+ZYV5ge@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-20 12:53:08 -07:00