Commit Graph

72900 Commits

Author SHA1 Message Date
Harjoth Khara e4907b92ec fix(cron): preserve browser tabs for persistent sessions (#113984)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 08:31:59 -04:00
Peter Steinberger 981a3dfad3 fix(packaging): require the code mode worker in shipped tarballs (#115178) 2026-07-28 08:26:30 -04:00
Peter Steinberger 2c5aff01f6 fix(ui): isolate board mock mode between test files (#115173) 2026-07-28 08:24:57 -04:00
lee-xydt f78d58379a fix(plugins): clone registration record metadata for transactional rollback isolation (#108084)
* fix(plugins): deep-clone registry snapshot values for transactional rollback isolation

Shallow spread / new Map() copies nested objects by reference, so
in-place mutations on PluginRecord fields and Map values inside
arrays leak through rollback() — violating transactional isolation.

Wrap array items, Map values, and object properties in a recursive
deep-clone helper that preserves function references so handlers
and resolvers are not lost. Fixes #106647.

* fix(plugins): replace generic deep-clone with targeted shallow record cloning

Replace the recursive deepCloneRegistryValue with cloneRegistryEntry that
shallow-clones registration records to isolate primitive metadata fields
while preserving opaque plugin-owned instances (providers, services,
channels, harnesses, resolvers) by reference. A generic deep-clone was
too broad: it converted every plugin-owned object into a plain object,
losing prototypes, internal slots, and shared identity.

Add a class-instance regression test proving that providers survive
snapshot/rollback with their prototype chain intact and methods callable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(plugins): add curly braces and fix TS type assertions for CI

- Add curly braces to single-line if statements in cloneRegistryEntry
  to satisfy eslint curly rule
- Use `as unknown as ProviderPlugin` double cast for test class instance
- Call test methods on original variable instead of through registry type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add loader-scenario rollback proof for two sequential plugin transactions (#106647)

Simulate the real loader pattern from loader-runtime-candidate L492-531:
transaction 1 registers a class-backed provider and commits, transaction 2
mutates registry state and rolls back. Prove the first plugin's metadata is
restored and its class-backed provider instance, prototype, and methods
survive the rollback.

* fix(plugins): snapshot active PluginRecord in registration transactions (#106647)

Add activeRecord parameter to createPluginRegistrationTransaction so
the active record's array fields (toolNames, hookNames, providerIds, etc.)
are snapshotted at transaction creation and restored on rollback.
Without this, the loader's recordPluginError path re-pushes the record
with stale id arrays from the failed register() call.

Also replace flat container copies in snapshotPluginRegistry with
cloneRegistryEntry that shallow-clones individual registration records
while preserving opaque plugin-owned objects by reference.

Update all three production callers (loader-runtime-candidate,
loader-channel-runtime, loader-cli-registry) to pass activeRecord.

* fix(plugins): snapshot all mutable PluginRecord metadata in transactions (#106647)

Expand activeRecord snapshot from array-only to full cloneRegistryEntry
so scalars (httpRoutes, hookCount), flags (configSchema, enabled,
memorySlotSelected), and Dates are also restored on rollback. Runtime
objects (configUiHints, configJsonSchema, contracts) stay by reference.

Also update the activeRecord JSDoc to reflect the broader contract.

* fix(plugins): restore exact rollback record shape

Co-authored-by: 詹幸心0668001037 <zhan.xingxin@xydigit.com>

* test(plugins): cover date rollback isolation

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: 詹幸心0668001037 <zhan.xingxin@xydigit.com>
2026-07-28 08:24:48 -04:00
Peter Steinberger 4f6fc38a22 fix(exec): prevent cancelled node commands from running (#115176)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 08:21:56 -04:00
Peter Steinberger 83096af168 fix: preserve provider timeouts across rebuilding plugins (#115102) 2026-07-28 08:21:07 -04:00
Dallin Romney a35bf77c82 fix(release): run harness install from its cwd (#115172) 2026-07-28 20:20:32 +08:00
Harjoth Khara f4da74a0af fix: preserve finalized Mattermost replies after tool warnings (#109555)
* fix(mattermost): preserve finalized preview after warnings

* test(mattermost): cover finalized preview warning trace

* docs(mattermost): clarify finalized preview invariant

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 08:17:20 -04:00
Peter Steinberger 10c6c0cb98 fix(memory-core): dream diary stays empty because narrative sessions have no agent scope (#115069)
* fix(memory-core): scope dream narrative sessions to their owning agent

Dreaming narratives built unscoped subagent session keys
(`dreaming-narrative-<phase>-<hash>`). Sessions live in per-agent SQLite
stores, so the plugin-runtime ownership pre-check could not resolve a store
and every narrative call failed with "Cannot resolve SQLite session scope
without an agent id" — the whole diary pipeline produced nothing while the
sweep still logged "dreaming promotion complete".

The agent id was available all along: `resolveMemoryDreamingWorkspaces`
returns it per workspace and the hook context carries the triggering agent.
Both were dropped. Session keys are now `agent:<id>:dreaming-narrative-...`,
while runIds stay unscoped so the orphan-transcript scrub marker still
matches. An unexpected narrative failure now writes the same dated fallback
diary entry the other failure branches write, and the promotion summary
warns instead of informing when every workspace failed.

* fix(memory-core): narrow the narrative export surface and type the sweep test double

* test(memory-core): drop the now-unused missing-path helper

* fix(memory-core): scope the narrative run id and keep empty sweeps a no-op

* fix(memory-core): route the ownerless narrative fallback through detached dispatch
2026-07-28 08:15:37 -04:00
Peter Steinberger 1602d457ba fix(cli): harden infer concurrent workflows (#115170) 2026-07-28 08:13:56 -04:00
chengzhichao-xydt dcce5b5237 fix(matrix): honor abortSignal during startup whoami retry backoff (#110115)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 08:13:09 -04:00
Peter Steinberger f0bf74bad4 feat(memory): backfill retained session transcripts (#115162)
* feat(memory): enumerate retained session transcripts

* feat(memory): add session transcript backfill

* test(memory): cover session backfill workflows

* docs(memory): document session transcript backfill

* fix(memory): preserve oldest session backfill ordering

* fix(memory): harden session archive backfill

* test(memory): prove owner-turn provenance gating

* fix(memory): persist session backfill progress

* fix(memory): preserve ranged backfill progress

* fix(memory): order per-file backfill candidates

* fix(memory): retain paged backfill diary entries

* fix(memory): preserve rem backfill diary history

* fix(memory): adapt backfill to retained session identity

* fix(memory): keep rem backfill preview-only

* fix(memory): satisfy backfill CI guards
2026-07-28 08:12:30 -04:00
Peter Steinberger 4fb33559fb fix(nodes): node screenshots saved as .png were actually JPEG (#115094)
* fix(nodes): name node screen captures after the encoding the node returned

screen.snapshot lets the node choose its encoding (macOS defaults to
JPEG) and reports it back in the payload. When the caller supplied
outPath, the tool wrote the bytes to that path verbatim, so a requested
.png happily received JPEG data. Anything dispatching on extension --
viewers, uploads, content-type headers, channel attachment handling --
then sees the wrong type.

Rename a caller-supplied outPath to match the reported format instead of
sniffing bytes, and drop the PNG default baked into
screenSnapshotTempPath. screen_record gets the same treatment; camera
snap/clip and photos.latest already derive their extension from the
payload format and take no outPath.

* fix(nodes): request the snapshot encoding the outPath promises

Correcting the extension after the fact would have written to a path the
workspace guard never saw: outPath is alias-checked on its exact final
segment before the tool runs, so swapping .mov for .mp4 could follow a
symlink out of the workspace.

Ask the node for the encoding the caller's filename already promises
instead, write the guarded path verbatim, and refuse to write bytes that
contradict the name.
2026-07-28 08:09:48 -04:00
Peter Steinberger c0df3cf0b9 fix(codex): preserve startup diagnostics on initialize timeout (#115161)
* fix(codex): preserve app-server startup diagnostics

* chore: leave release notes to release automation
2026-07-28 08:08:12 -04:00
Peter Steinberger bb634261cb fix(mcp): keep resource-only servers available after unknown methods (#115169) 2026-07-28 08:07:32 -04:00
SunnyShu bdb3918f4d fix(agent): check updateSessionEntry return value for pendingFinalDelivery write (#102128)
* fix(agent): add requireWriteSuccess:true to pendingFinalDelivery updateSessionEntry call

The pendingFinalDelivery write is a critical durable state write where silent
failure would cause data loss. This mirrors the same pattern used in 4 other
sites.

This commit resolves the merge conflict in PR #102128 by moving the change from
the old agent-runner.ts to the new agent-runner-result-complete.ts where the
code now lives after the refactoring.

* fix: update test import path and fix formatting

* fix: remove outdated test — store migrated to SQLite

The test file pending-final-delivery.store-write-failure.test.ts was written
for the legacy file-based store. Since main migrated updateSessionEntry to
SQLite, mocking writeTextAtomic/replaceFileAtomic no longer tests the actual
code path. SQLite writes are inherently ACID — write failures always propagate.

The requireWriteSuccess:true option is retained in agent-runner-result-complete.ts
as documentation of intent for this critical state write.

* fix(auto-reply): verify durable final delivery session

Preserve the session identity and committed pending intent before returning a final reply. Reject deleted or reset SQLite sessions without poisoning replacements, and cover the production reply-runner path. Follow-up to #102128 by @SunnyShu0925.

---------

Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 08:06:56 -04:00
Peter Steinberger 699315e7d7 feat(ui): redesign Ask OpenClaw — mascot, shared surface, dockable panel (#115123)
* refactor(ui): share custodian chat surface

* feat(ui): add dockable custodian panel

* refactor(ui): drop write-only panel-close latch from custodian store

* feat(ui): demo custodian in mock gateway

* chore(ui): update raw-copy baseline for custodian strings

* fix(ui): clean custodian surface/page/mock lint debris
2026-07-28 08:05:38 -04:00
Peter Steinberger 0f188c8cc6 fix(tui): preserve shared prompts when scrollback is full (#115165) 2026-07-28 08:05:16 -04:00
wanyongstar 89b6d85cdd fix(scripts): bound android-release-signing exec operations (#110822)
* fix(scripts): bound android-release-signing exec operations

* fix(scripts): test Android signing timeouts

Co-authored-by: wanyongstar <wan.yong@xydigit.com>

* fix(scripts): keep signing timeout internal

* docs(scripts): clarify signing timeout scope

* test(agents): isolate transport timeout proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 07:51:38 -04:00
Ayaan Zaidi a54e28e8e9 feat(browser): return inline page state after navigation (#114814)
navigate and act results that changed the page document now include the
loaded page's compact snapshot inline (honoring browser.snapshotDefaults
and standard caps/wrapping), removing the follow-up snapshot round-trip.
Snapshot execution moves to browser-tool.snapshot.ts to keep action
executors under the file size cap.
2026-07-28 20:42:57 +09:00
Peter Steinberger 20eda756fa fix(logging): scale heap pressure with V8 limit (#115153)
Fixes #104631.
2026-07-28 07:20:13 -04:00
Pavan Kumar Gondhi edea5287dc fix: reject unsafe SSH sandbox targets [AI] (#115036)
* fix: harden ssh sandbox target parsing

* fix: preserve ssh target token compatibility

* fix: reject option-like ssh usernames
2026-07-28 16:46:12 +05:30
Pavan Kumar Gondhi beab295d24 fix: reject malformed gateway upgrade claims (#115038) 2026-07-28 16:45:01 +05:30
Peter Steinberger 6499143313 fix(kimi): flag K3 as code-mode preferred (#115022)
The moonshot provider already declares compat.codeMode: "preferred" for the
same model (kimi-k3), so tools.codeMode: "auto" engaged code mode on the API
surface but silently skipped the Kimi Code subscription surface (kimi/k3,
kimi/k3-256k). Live proof on kimi/k3: "auto" reported codeModeEngaged=false
while true reported codeModeEngaged=true with "code-mode: cataloged 50 tools
behind exec/wait" and 2 bridge tool calls.

K2.7 (kimi-for-coding*) stays unflagged, matching moonshot's kimi-k2.7-code.
2026-07-28 07:09:05 -04:00
Peter Steinberger ca4727e1a1 fix(twitch): use managed runtime dependencies (#115147) 2026-07-28 07:08:56 -04:00
Peter Steinberger 9692e62119 test: align release validation fixtures (#115146)
* test: forward-port release validation fixtures

* test(telegram): isolate native command test dependencies

* test(telegram): await async file logs
2026-07-28 07:08:08 -04:00
Peter Steinberger e834293747 test(memory): align QMD alias identity fixture (#115150) 2026-07-28 07:07:44 -04:00
Peter Steinberger 0ecd449a43 fix(plugins): report missing plugin modules as missing, not boundary escapes (#115053)
* fix(plugins): report missing plugin modules as missing, not boundary escapes

The root-scoped open helper returns a classified failure, but five plugin
loader sites collapsed every failure into "escapes plugin root or fails
alias checks". A plugin artifact that is simply absent — e.g. while
dist/extensions/<id> is being re-emitted by a build — was therefore
logged as a containment violation.

Classify the failure instead: missing (ENOENT/ENOTDIR), unreadable
(coded), or an actual boundary/alias rejection. The containment check is
unchanged; only the reported reason is. Also drops the never-supplied
boundaryLabel/boundaryRootDir parameters on loadChannelPluginModule so
one root carries one label.

* test(infra): rename lint-flagged local helper in boundary failure test
2026-07-28 07:06:24 -04:00
Peter Steinberger fe035de4d6 fix(ci): compare env ratchet at branch fork (#115149) 2026-07-28 07:06:00 -04:00
Peter Steinberger f66a06e420 fix(feishu): inspect canonical doctor transcripts (#115148) 2026-07-28 07:05:46 -04:00
Peter Steinberger 2a94aa57eb fix(ui): hide Cron mutations from read-only operators (#115091)
* fix(ui): hide cron mutations from read-only operators

* chore: leave release notes to release automation
2026-07-28 07:03:19 -04:00
Peter Steinberger d28fb52651 fix(openai): preserve incomplete Responses stream output (#115132)
* fix(openai): recover incomplete Responses stream output

* test: include incomplete SSE in transport discovery
2026-07-28 07:03:05 -04:00
Peter Steinberger 29b6f56254 feat(system-agent): host skills and web-search setup in Ask OpenClaw (#115130)
* feat(system-agent): host skills and search setup

* test(system-agent): align stop-message assertions with channel-specific labels

* fix(system-agent): report failed search-provider install honestly

* fix(system-agent): preserve nonfatal search setup skips

* test(flows): satisfy plugin-install mock return type

* test(system-agent): split setup-flow operation tests
2026-07-28 06:59:28 -04:00
Peter Steinberger 59f8245f36 fix(state): accept pre-provenance agent DBs missing memory chunk metadata columns (#115144)
#114819 added importance/triggers to memory_index_chunks with a lazy memory-core
ALTER but did not allowlist their absence, so every existing agent DB fails the
canonical schema check, doctor errors, and the updater rolls back. Observed live
on both production Hetzner hosts (hourly update cycles 10:08/10:18 UTC failed
with 'column definitions differ for memory_index_chunks' and rolled back).
2026-07-28 06:57:47 -04:00
ToToKr d57e228c3a docs(mistral): fix broken adjustable reasoning docs URL (#114867)
* docs(mistral): fix broken adjustable reasoning docs URL

The linked Mistral page 404s; the reasoning docs now live one path segment up. Verified: old URL returns HTTP 404, new URL returns HTTP 200 and documents reasoning_effort. oxfmt --check passed on the changed file.

* fix(ci): audit links inside docs components

* test(cli): isolate root help exit fixture

* test(ci): split embedded agent shard

* fix(ci): harden docs link projection

* test(ci): satisfy docs audit strict types

* test(ci): isolate incomplete-turn harness

* test(cli): document root help fixture boundary

* test(ci): isolate overflow compaction harness

* test(ci): isolate contaminated agent model tests

* test(ci): update isolated prefix routing

* test(ci): bound loaded streaming HTTP cases

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 06:55:02 -04:00
SunnyShu 07c4f7b721 fix(tlon): use waitUntilAbort to fix monitor abort-race hang (#114940)
* [AI] fix(tlon): use waitUntilAbort to fix monitor abort-race hang

Replace ad-hoc abort listener with the shared waitUntilAbort
primitive, hoist pollInterval for unified finally cleanup, and
add .unref() per codebase convention.

The original code registered an abort listener inside a Promise
constructor without checking signal.aborted first. Per the
AbortSignal contract, a listener attached after abort has fired
is never called, so the monitor hung without running cleanup.

The fix reuses waitUntilAbort from plugin-sdk/channel-outbound,
which correctly handles already-aborted, normal, and absent
signals. pollInterval is hoisted and cleared in finally as a
single cleanup owner.

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

Fixes #114886

* fix(tlon): prove abort-safe Urbit monitor cleanup

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-28 06:53:37 -04:00
Peter Steinberger b6bebfa73c fix(agents): prevent silent corruption when editing non-UTF-8 files (#115088) 2026-07-28 06:46:01 -04:00
Peter Steinberger 7cf14c12c8 fix(release): accept advisory runtime gaps (#115140) 2026-07-28 06:42:10 -04:00
Wynne668 1d047ac4f1 fix(matrix): reject non-canonical synthetic thread cursors (#111243) 2026-07-28 06:40:11 -04:00
Peter Steinberger a20c5550c8 fix: stop synthetic model tests from stalling CI (#115139) 2026-07-28 06:37:30 -04:00
Peter Steinberger 4233301c7c fix(slack): keep previews with custom outbound identity (#115114)
* fix(slack): preserve previews with custom identity

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

* test(models): isolate configured visibility policy

---------

Co-authored-by: goutamadwant <workwithgoutam@gmail.com>
2026-07-28 06:33:59 -04:00
Peter Steinberger 7f37900bca perf(ui): flip sessions instantly and drop redundant switch RPCs (#115129)
* perf(ui): flip sessions instantly and drop redundant switch RPCs

* chore: revert changelog edit (release generation owns CHANGELOG.md)

* test(ui): adapt ported switch e2e tests to split-suite helpers

* chore(ui): un-export internal CachedShortSession type (knip)
2026-07-28 06:25:25 -04:00
Vincent Koc 8bae9cebaf refactor(plugin-sdk): share HTML escaping (#115109) 2026-07-28 12:11:08 +02:00
Peter Steinberger ecd22f5e2d fix(msteams): display decoded attachment filenames (#115127) 2026-07-28 06:09:34 -04:00
Peter Steinberger 28630a9a65 feat(memory): provenance-gated memory with dreaming on by default (#114819)
* feat(memory): add provenance and recall metadata to the memory index

* feat(memory): provenance-gated promotion and capture hygiene

* feat(dreaming): LLM consolidation with deterministic gates, on by default

* feat(active-memory): deterministic recall lane with escalation default

* feat(memory): user model file and standing intents

* docs(memory): document the memory architecture

* fix(memory): live-QA fixes — metadata writers, provenance classes, intent scope, claim accumulation
2026-07-28 06:04:25 -04:00
wahaha1223 4c2d06be2b fix(browser): reject startup when control ports are occupied (#109994)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 06:01:02 -04:00
Peter Steinberger 9c051c6513 fix(config): accept documented global exec approval notice delay (#115101)
Restore the already shipped global exec approval notice setting through the same strict validator as its per-agent override.

Reported-by: @glorifiedautocomplete
Original-fix-by: @natedemoss (#57293)
2026-07-28 05:51:20 -04:00
Peter Steinberger 18556423da fix(cron): allow no-timeout scheduled jobs in Control UI (#115090) 2026-07-28 05:46:17 -04:00
Chris M. 37bddc75cc fix(android): finish Wear OS release readiness [AI-assisted] (#110425)
* fix(android): harden Wear release quality

* fix(android): use Wear minimum touch targets

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>

* fix(android): localize Wear accessibility actions

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>

* fix(android): preserve dictation without live voice

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>

* fix(android): isolate Wear locale source changes

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>

* fix(android): keep Wear dictate preview exclusive

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>

* fix(android): separate large-font Wear hit targets

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>

* test(pr): isolate review artifact ripgrep fixture

* ci: extend embedded-agent fork watchdog

* refactor(android): clarify Wear voice action availability

* style(android): preserve Wear locale source lines

* chore(i18n): refresh native source inventory

* style(android): restore Wear label indentation

---------

Co-authored-by: Chris Mish <chrism@promethean-dynamic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-28 05:41:53 -04:00
ooiuuii edd1c4d30a fix(infra): preserve text in PowerShell clipboard fallback (#113835) 2026-07-28 05:38:58 -04:00