Commit graph

66940 commits

Author SHA1 Message Date
Peter Steinberger
7303f42917
fix(macos): fail fast during node lifecycle cleanup (#105282) 2026-07-12 11:41:21 +01:00
Peter Steinberger
4249cdb8fe
fix(discord): keep slash commands deployed at the application limit (#105280)
* fix(discord): reconcile commands at the application cap

* docs(changelog): note Discord command cap fix

* chore: keep release changelog unchanged

* fix(discord): narrow command deployment errors
2026-07-12 11:37:29 +01:00
Peter Steinberger
75f0960b71
fix(ui): recover worktree creation after reconnect (#105285) 2026-07-12 11:36:54 +01:00
Peter Steinberger
c5208f9dfe
feat(tooling): enforce indexed access checks in UI tests (#105283) 2026-07-12 11:35:00 +01:00
Vincent Koc
2148c3bf7e
fix(active-memory): restore SQLite recall sessions (#105255)
* fix(qa): seed memory scenarios through SQLite

* fix(active-memory): initialize SQLite recall sessions

* test(active-memory): model missing harness reservation

* fix(active-memory): clean up transient recall sessions

* fix(active-memory): isolate concurrent recall sessions

* fix(active-memory): discard transient SQLite recalls

* fix(active-memory): preserve transient recall boundaries

* fix(active-memory): retry transient recall cleanup

* fix(active-memory): always clean transient recall workspaces

* chore: drop release-owned changelog entry
2026-07-12 18:29:23 +08:00
Peter Steinberger
e6cba86509
chore(plugin-sdk): refresh API baseline 2026-07-12 11:24:42 +01:00
Peter Steinberger
feff4c7824
fix(plugin-sdk): isolate expect declaration surface 2026-07-12 11:23:43 +01:00
Vincent Koc
4d8b201371
refactor(plugins): remove dead channel helpers (#105276) 2026-07-12 18:21:11 +08:00
Peter Steinberger
f4659b7d4d
fix(updater): scope restart log audits to managed checkout (#105030)
* fix(updater): scope restart log audits

* test(updater): declare log source argument

* fix(updater): preserve configured plugin logs

* fix(updater): normalize plugin log sources

* fix(updater): reuse managed plugin config

* fix(updater): resolve relative plugin roots

* fix(updater): handle unset gateway workdir

* fix(updater): audit effective plugin roots

* fix(updater): bind logs to managed runtime

* fix(updater): canonicalize log source roots
2026-07-12 11:21:00 +01:00
Peter Steinberger
0350b87f06
test(ci): repair plugin prerelease contracts (#105272)
* test(ci): repair plugin prerelease contracts

* docs(agents): clarify stale Testbox recovery

* docs(agents): require Bash for Testbox compounds
2026-07-12 11:13:08 +01:00
Peter Steinberger
a824078101
fix(channels): tombstone corrupt ingress rows (#105259)
* fix(infra): guard channel ingress queue parseJson against corrupted JSON

* fix(infra): fix type assertion in ingress queue test

* fix(infra): use tagged parse result and validate payload before claiming

* fix(infra): remove unnecessary non-null assertion in ingress queue test

* fix(infra): scan corrupt ingress rows in claimNext

* test(gateway): avoid typed empty mock call tuple access

* fix(infra): tombstone corrupt ingress rows on duplicate enqueue and stale recovery

Two P1 gaps: enqueue() threw on duplicate when the existing row had corrupt
payload_json, and recoverStaleClaims() silently skipped corrupt claimed rows,
leaving them invisible to recovery. Both paths now tombstone the unrecoverable
row as failed with reason "corrupt_payload" and return a proper result.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(infra): resolve lint shadow and await-thenable in recoverStaleClaims

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(channels): tombstone corrupt ingress rows

* test(channels): use explicit placeholder claim tokens

* refactor(channels): name claim token values

* refactor(channels): keep claim projection direct

* fix(channels): preserve active ingress claims

* fix(channels): make corrupt recovery policy-aware

* refactor(channels): name corrupt claim token

* fix(channels): bound corrupt ingress reconciliation

* fix(channels): paginate pending ingress by key

* refactor(telegram): return live owner check directly

* build(plugin-sdk): refresh public export budget

---------

Co-authored-by: Pick-cat <huang.ting3@xydigit.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-12 11:09:52 +01:00
Peter Steinberger
dba78584ff
fix(ui): preserve rejected first message when session send fails (#105261)
* fix(ui): preserve rejected first session message

* chore: leave changelog to release closeout

* fix(protocol): regenerate session create result
2026-07-12 11:09:38 +01:00
Vincent Koc
4c077df1b1
fix(sqlite): repair canonical unique index drift (#105260)
* fix(sqlite): repair canonical unique index drift

* chore(sqlite): allow schema repair DDL
2026-07-12 18:08:16 +08:00
Vincent Koc
34205aabf9
refactor(plugins): remove obsolete runtime helpers (#105273) 2026-07-12 18:05:22 +08:00
Peter Steinberger
7bb59c4511
ci: pin release validation Go toolchain (#105270) 2026-07-12 11:02:04 +01:00
Peter Steinberger
1999935108
fix(config): restore canonical flat streaming-key resolution and preserve discord preview mode in doctor migration (#105054)
* fix(config): keep flat streaming keys resolving for canonical-flat channels and pin discord preview default in doctor migration

* fix(discord): pin inherited streaming mode for account alias migration and align core streaming test
2026-07-12 11:00:24 +01:00
Peter Steinberger
566043eb54
feat(tooling): enforce noUncheckedIndexedAccess from the base tsconfig (NUIA endgame) (#105239)
* feat(tooling): enforce noUncheckedIndexedAccess from the base tsconfig

Completes #104600: the flag moves to tsconfig.json, the five per-lane
copies are removed, and test lanes carry one documented opt-out at their
shared parent (the ~4,400 fixture-indexing sites are a tracked
lane-by-lane follow-up). Any future lane inherits the flag by default.
Synthetic probes verify src rejects unchecked reads while test files
compile; all nine lane commands green.

* fix(memory-core): give the batch-call sort a defined element type

Type-aware lint analyzes test files under the base flag (its tsconfig
extends the root, not the test parent), so the widened call[0] made the
bare toSorted() fire require-array-sort-compare.
2026-07-12 10:57:26 +01:00
Peter Steinberger
916d43c9b9
docs(agents): clarify Testbox cleanup syntax (#105268) 2026-07-12 10:55:36 +01:00
Peter Steinberger
5fe350c668 fix(docs): keep Dutch address informal 2026-07-12 05:55:10 -04:00
Peter Steinberger
842f8f3ee9
feat(ui): auto-load older external-session transcript on scroll (#105209)
* feat(ui): auto-load older catalog transcript on scroll with a stable viewport

* fix(ui): surface the load-older fallback when auto-load is blocked on a short thread

* fix(ui): clamp oversized aggregated tool output in catalog transcripts

* fix(ui): stop catalog auto-pagination when an older read makes no progress

* fix(ui): continue catalog paging through advancing empty pages; exhaust only on a stalled cursor

* fix(ui): detect catalog cursor cycles to bound auto-pagination
2026-07-12 10:52:00 +01:00
Peter Steinberger
5b56a1f664
feat(gateway): land remaining durable-approvals stack and repair main gates (#104837)
* feat(gateway): propagate approvals to ancestor sessions with replay

Squash-rebased #103921 segment onto the native-clients tip on current main.
Session-scoped approval events publish sanitized pending/terminal
transitions to opted-in session audiences, with authoritative pending
replay on stream subscribe and durable-expiry reconciliation through the
owning manager. SessionApprovalEvent/Replay wire types export from the
approvals owner module; Swift models regenerated.

(cherry picked from commit 2d1dcf9747044710111d0c730fc46ba6013a165c)
(cherry picked from commit ccf88efd56b513d07599ffcee997bf0cddaf9adc)
(cherry picked from commit 8eb33f59f00ec9ee4625259b76bd7ae60d2cd480)
(cherry picked from commit c297cbc93c8401e9c79c20f242245a194f5dd236)
(cherry picked from commit 93d68f28601ff37d863da4db009504993a22533a)
(cherry picked from commit d285ccd8b2f212bb57e814107e7709c896e96b7d)
(cherry picked from commit 5c536982231402b1b58d1683794ea9948b32d077)
(cherry picked from commit 1646e5b6dc4dd20de54e10f110a5909be18d7d50)
(cherry picked from commit 35cf1b705b247fb282f4d56ffe74bd2fb238221f)
(cherry picked from commit 4f8ef3699de54d9135d0a36bee9c4c11f5a51173)
(cherry picked from commit 74fbdcc99d5fff062d67760a51dba4ee9e84479b)
(cherry picked from commit 222b285502681d2be14b1819798e9ee5555f431e)
(cherry picked from commit b9e744951f676b600e7c5322bfd04b0e99797c07)
(cherry picked from commit 9e904efde5b6407b2d4748313ffc3ea57b4f33a7)
(cherry picked from commit 678f2384fafa29ea3073aacf55de64e69f50565d)
(cherry picked from commit 72842e5cf6e9f4aba7ee8a68b48db0011e10db73)
(cherry picked from commit be74c25e80e84a1f065053766f23efb84822e811)
(cherry picked from commit 93ba8c4b096689b3c54d85745cd771f5147768dd)
(cherry picked from commit 8f23761372)

* feat(gateway): fail-closed plugin and tool approval gates

Squash-rebased #103932 segment onto the ancestor-propagation tip on
current main. Plugin node.invoke approvals claim a one-shot allow-once
decision before handing execution authority to the policy, so observation
or retry cannot replay a consumed approval; sibling tool gates bind
approval ids to their originating reviewer identity.

(cherry picked from commit 122df0d75281f572c012b6484ed5daf085d1d577)
(cherry picked from commit f23d8ac240a8dcf2a42c4daaae962263975a0ae8)
(cherry picked from commit 8632fb6436a224dac7a9a9ef0216884530de2c24)
(cherry picked from commit d9fe2dd5c53665e5732f5f3da5ed1907a686ade8)
(cherry picked from commit bb139f2c8aa36ddad70413e1ef79ff491a6f2ecd)
(cherry picked from commit 9b3e056b68ea515c7d4baef269289b6670570480)
(cherry picked from commit b11e66b59a7af1f3b08712de06864aed64d349e4)
(cherry picked from commit a12916ee592d03dfa35e86a2aaede4476a5d4e5d)
(cherry picked from commit d699de840fc8346892b9ae244fe3c3e8c4413032)
(cherry picked from commit 9b7e5a9608f94732226776b801b3a2ac65329e05)
(cherry picked from commit 4b507593f1b2f10b4496984c84a2803b853e5c5e)
(cherry picked from commit 56408a186733c4eeb5aa76bd5907cde7b0cd3d5b)
(cherry picked from commit a4051d6d8353d39d6fa0b5d69c36e06c3cd3e796)
(cherry picked from commit 76829805a7135ed3a7984ae372edd0d872cb0dfc)
(cherry picked from commit a8b493f934b644ef8688a8044c2bdcdcc08d686d)
(cherry picked from commit aceb990597affb8388c341a10cb386ef96bed3e4)
(cherry picked from commit a29b0e75482470c53a9fb4fe3f204e14cf71868f)
(cherry picked from commit 2e3be08653d9332095a10ec13237c838258c0265)
(cherry picked from commit c9ae3d7202)

* fix: main-gate repairs for the durable-approvals stack

- android: capture createdAtMs on the pending exec-approval write at
  registration; canonical readback after a refresh that already replaced
  the visible rows was dropping the approval instead of surfacing the
  still-pending reconciliation message (#104913 merged without this)
- android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest
- agents: hermetic model-discovery test via the plugins/provider-runtime
  boundary (lazy plugin-runtime resolution hangs vitest workers since #104770)
- cli: usage-cost settle-budget test asserts the budget bound on every call
  instead of pinning the poll count (fast hosts fit a second poll in 50ms)
- protocol coverage: allowlist session.approval for ios/android (native
  review rides exec.approval push/nudge delivery)
- docs map, native i18n inventory, plugin-sdk api baseline regenerated
2026-07-12 10:51:38 +01:00
Peter Steinberger
ce562c3511
test(openai): align prerelease contracts (#105256) 2026-07-12 10:49:48 +01:00
Peter Steinberger
265ca345a1
ci: pin frozen iOS formatter (#105242)
* ci: pin frozen iOS formatter

* docs: clarify release CI dispatch

* ci: preserve frozen iOS formatter path

* style: format CI workflow guard
2026-07-12 10:49:26 +01:00
Peter Steinberger
cfe8019772
improve(ui): redesign the automation editor into prompt, general, schedule, and delivery cards (#105254)
* improve(ui): redesign the automation editor into prompt, general, schedule, and delivery cards

* fix(ui): calm last-run glyphs, saved next-run in header, prompt focus ring

* chore(ui): sync locale bundles for editor redesign keys

* test(ui): cover one-shot schedule summary formatting
2026-07-12 10:47:38 +01:00
Peter Steinberger
dad278a89d
test(telegram): align prerelease contracts (#105253) 2026-07-12 10:45:14 +01:00
Peter Steinberger
c4b41c1e4a
fix: clear transcript search data when sessions are deleted (#105249)
* fix: delete session transcript search state

* chore: keep release note in PR body
2026-07-12 10:43:53 +01:00
Peter Steinberger
7a4cfa3764
test(matrix): isolate approval reaction runtime (#105251) 2026-07-12 10:43:00 +01:00
Peter Steinberger
1bea458124
test(plugins): align prerelease contracts (#105252) 2026-07-12 10:42:34 +01:00
Peter Steinberger
e0f45bfbf0
feat(tooling): enforce indexed access checks in root tests (#105223)
* feat(tooling): enforce indexed access checks in root tests

* style(tooling): clarify scoped package guard
2026-07-12 10:42:07 +01:00
Peter Steinberger
251f54baec
fix(apps): remove dead native code 2026-07-12 02:41:17 -07:00
Vincent Koc
a67b124f10
refactor(sessions): remove unused transcript helpers (#105245) 2026-07-12 17:40:54 +08:00
Vincent Koc
9b7f828d01
chore(skills): sync canonical autoreview (#105250) 2026-07-12 17:37:15 +08:00
Peter Steinberger
48e7f76e3a
fix(nodes): expose typed executable lookup to agents (#105182)
* fix(nodes): add typed executable lookup action

* test(nodes): refresh executable lookup snapshots
2026-07-12 10:36:33 +01:00
Peter Steinberger
cc3dfc9ded
fix: preserve unmanaged gateway restart truth (#105241) 2026-07-12 10:32:17 +01:00
Vincent Koc
1592d422ee
fix(sqlite): reject orphaned database state before mutation (#105222)
* fix(sqlite): detect foreign key corruption

* docs(sqlite): document foreign key compaction checks

* fix(sqlite): prevent pragma shadow bypass
2026-07-12 17:31:24 +08:00
Vincent Koc
e90929ba41
chore(plugin-sdk): refresh node presence API baseline (#105236) 2026-07-12 17:25:03 +08:00
Peter Steinberger
477f3af688 fix(docs): preserve named runtimes and plugins 2026-07-12 05:24:06 -04:00
Peter Steinberger
b02d276bbc
test(slack): align prerelease contracts (#105214)
* test(slack): align prerelease contracts

* docs(agents): note review artifact enums

* style(slack): format prerelease test
2026-07-12 10:23:47 +01:00
Peter Steinberger
b4a0fc5c57
perf(agents): reduce repeated turn setup latency (#105220)
* perf(agents): reuse prepared auth route models

* chore: leave release notes to release automation
2026-07-12 10:21:31 +01:00
Peter Steinberger
9bdb2a5ac0
fix(cron): preserve successful run status after delivery failure (#105215)
* fix(cron): keep isolated run status ok when delivery fails

A successful isolated cron agentTurn whose post-run delivery phase returns
an error collapsed the execution status into the delivery error, so the
outer scheduled run persisted status=error even though the isolated session
ended successfully.

Decouple execution status from delivery outcome in finalizeCronRun: when the
agent payload is non-fatal and the run was not aborted, a delivery dispatch
error now keeps status=ok and records the failure separately via
delivered/deliveryAttempted plus delivery diagnostics, which drive the
already-decoupled run-log deliveryStatus (not-delivered). Aborted runs and
fatal agent payloads keep their error status.

Fixes #94058

* fix(cron): keep deliberate delivery-target refusals as error status

The #94058 fix kept isolated turn status=ok when post-run delivery
fails, but the broad `status === "error"` check also caught the
#91613 keyless implicit last-target refusal, which is a deliberate
delivery-target guard (errorKind "delivery-target") and must stay
status=error. Exclude that errorKind so genuine delivery dispatch
failures still become ok while target-guard refusals remain errors.

* fix(cron): surface successful run delivery errors to run logs

A successful isolated agent turn keeps status=ok when post-run delivery
fails (#94058), but the ok/not-delivered resolveRunOutcome branch only
forwarded delivery diagnostics and dropped the delivery dispatch error.
That left lastDeliveryError empty and the finished-event deliveryError
field blank, so CLI/UI/API run logs could not show why delivery did not
land for an otherwise successful run.

Thread the delivery error on a dedicated CronRunOutcome.deliveryError
field from resolveRunOutcome through executeDetachedCronJob and
applyJobResult into resolveDeliveryState, so it persists as
lastDeliveryError and reaches the finished event (and thus the run log)
without conflating it with a run-level error (lastError stays empty on a
successful run).

Add a service/run-log readback test proving the delivery error survives
the cron boundary into a persisted run-log entry, and extend the
isolated-turn regression to assert the dedicated deliveryError field.

* fix(cron): preserve successful delivery outcomes

* fix(cron): preserve startup delivery errors

* fix(cron): retain best-effort delivery errors

* fix(cron): preserve delivery errors on fallback paths

* fix(cron): preserve delivery errors on fallback paths

---------

Co-authored-by: Alix-007 <li.long15@xydigit.com>
2026-07-12 10:20:53 +01:00
Peter Steinberger
7c954849e6
fix(google-meet): use strong caption epochs (#105221) 2026-07-12 10:20:50 +01:00
Peter Steinberger
de4d4079ad
fix(browser): make ref uploads request-owned (#105151)
* fix(browser): make ref uploads request-owned

* style(browser): satisfy upload owner const lint
2026-07-12 10:19:19 +01:00
Peter Steinberger
4efe056d32
fix(ci): stop Telegram release checks from fetching history (#105219)
Some checks are pending
Native App Locale Refresh / resolve-base (push) Waiting to run
Native App Locale Refresh / Verify generated PR App permissions (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ar (push) Blocked by required conditions
Native App Locale Refresh / Refresh native de (push) Blocked by required conditions
Native App Locale Refresh / Refresh native es (push) Blocked by required conditions
Native App Locale Refresh / Refresh native fa (push) Blocked by required conditions
Native App Locale Refresh / Refresh native fr (push) Blocked by required conditions
Native App Locale Refresh / Refresh native hi (push) Blocked by required conditions
Native App Locale Refresh / Refresh native id (push) Blocked by required conditions
Native App Locale Refresh / Refresh native it (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ja-JP (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ko (push) Blocked by required conditions
Native App Locale Refresh / Refresh native nl (push) Blocked by required conditions
Native App Locale Refresh / Refresh native pl (push) Blocked by required conditions
Native App Locale Refresh / Refresh native pt-BR (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ru (push) Blocked by required conditions
Native App Locale Refresh / Refresh native sv (push) Blocked by required conditions
Native App Locale Refresh / Refresh native th (push) Blocked by required conditions
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Waiting to run
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Blocked by required conditions
Plugin Init Scaffold Validation / Validate provider scaffold (push) Waiting to run
Plugin NPM Release / preview_plugins_npm (push) Waiting to run
Plugin NPM Release / Validate release publish approval (push) Blocked by required conditions
Plugin NPM Release / preview_plugin_pack (push) Blocked by required conditions
Plugin NPM Release / Preflight plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / publish_plugins_npm (push) Blocked by required conditions
Plugin NPM Release / verify_plugins_npm (push) Blocked by required conditions
Workflow Sanity / generated-doc-baselines (push) Waiting to run
Workflow Sanity / no-tabs (push) Waiting to run
Workflow Sanity / actionlint (push) Waiting to run
* fix(ci): bound Telegram provenance lookups

* docs(agents): note linked worktree invocations
2026-07-12 10:18:39 +01:00
Vincent Koc
25f00f9881
refactor(plugins): remove dead contribution owner wrappers (#105224) 2026-07-12 17:17:54 +08:00
Peter Steinberger
e580275464
feat(tooling): enforce noUncheckedIndexedAccess in the scripts lane (NUIA phase 5) (#105180)
* feat(tooling): enforce noUncheckedIndexedAccess in the scripts lane

Burns down all 153 scripts-lane errors (bench aggregation, release
checks, i18n inventories, argv indexing) and flips the flag in
tsconfig.scripts.json. Direct-Node-executed release harness scripts use
local narrowing instead of workspace imports, which do not resolve
under plain node execution. Benchmark measured loops untouched.

* fix(scripts): import expect helpers via relative package sources

tsconfig path aliases resolve from cwd under tsx, so release wrapper
scripts running against old release target cwds could not resolve
@openclaw/normalization-core (not a linked root dependency). Relative
package-source imports match the established pattern on the adjacent
lines and are cwd-independent; old-target planning verified directly.
2026-07-12 10:17:00 +01:00
Peter Steinberger
d79373fa14
ci: bound legacy QA smoke compatibility (#105213) 2026-07-12 10:15:33 +01:00
Peter Steinberger
def7b51899
test(agents): keep model discovery assertions hermetic against bundled plugin runtime (#105050) 2026-07-12 10:15:05 +01:00
Peter Steinberger
a8b104c4e3
feat(mac): swap dashboard titlebar buttons with sidebar state (#105175)
* feat(mac): swap dashboard titlebar buttons with sidebar state

The Control UI reports sidebar collapsed/width over a new openclawNav
WKScriptMessage; the titlebar accessory shows toggle+back/forward
right-aligned to the sidebar edge while expanded, and
toggle+search+new-session while collapsed. Search opens the command
palette and + opens the new-session surface via openclaw:native-*
events. Older gateway bundles that never report keep the shipped
toggle/back/forward layout.

Refs #105129

* docs: describe state-dependent mac titlebar buttons
2026-07-12 10:13:36 +01:00
Coy Geek
3ac83ddfca
fix: Canvas WebSocket creation in browser context silently swallows... (#82505)
* fix(canvas): report live reload websocket errors

Surface WebSocket initialization failures from the injected canvas live reload client through console diagnostics, DOM attributes, and a browser event instead of silently swallowing them.

* refactor(canvas): keep reload diagnostics console-only

* fix(canvas): distinguish page teardown from socket failure

* style(canvas): brace pagehide listener

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 10:13:04 +01:00
Peter Steinberger
4983594867
test(browser): align snapshot contract fixtures (#105210) 2026-07-12 10:12:47 +01:00