Commit Graph

36115 Commits

Author SHA1 Message Date
Gio Della-Libera
3630d502eb Doctor: expose gateway runtime findings (#97075)
* feat(doctor): expose gateway runtime findings

* fix(doctor): redact gateway health targets
2026-06-27 17:17:49 -07:00
Galin Iliev
dc575d148a fix: page sessions_history beyond truncated tails (#97101)
* Add sessions history offset pagination

* Fix sessions_history pagination after tool caps

* Fix sessions_history PR CI blockers

* Update sessions_history prompt snapshots

* Fix offset history projection windows

---------

Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>
2026-06-27 15:30:49 -07:00
Gio Della-Libera
12685ee6b7 Add hosted catalog snapshot fallback (#95877)
Merged via squash.

Prepared head SHA: 5f71635bba
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
2026-06-27 15:26:49 -07:00
Gio Della-Libera
36722014ef Doctor: expose configured plugin install findings (#96171)
* feat(doctor): expose configured plugin install findings

* fix(doctor): satisfy configured plugin mapper lint
2026-06-27 14:18:50 -07:00
zengLingbiao
1b8b8500ce fix(auto-reply): truncate user-facing text on UTF-16 boundary (#97299)
Summary:
- The PR imports `truncateUtf16Safe` and uses it for the Codex usage-limit preview and verbose working-label truncation paths in auto-reply.
- PR surface: Source +2. Total +2 across 2 files.
- Reproducibility: yes. Current main uses raw `slice(0, N)` at both reported user-facing truncation sites, and ... ludes terminal before/after output showing dangling surrogates before the fix and safe truncation after it.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 74a0a32ed9.
- Required merge gates passed before the squash merge.

Prepared head SHA: 74a0a32ed9
Review: https://github.com/openclaw/openclaw/pull/97299#issuecomment-4820038635

Co-authored-by: zenglingbiao <zeng.lingbiao@xydigit.com>
Approved-by: takhoffman
2026-06-27 20:39:32 +00:00
Gio Della-Libera
c29e1fe764 Add hosted external catalog feed loader (#95868)
Merged via squash.

Prepared head SHA: 76da9328af
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
2026-06-27 13:20:05 -07:00
shengting
98ed83f848 fix(model-fallback): don't rethrow provider-side AbortErrors as user cancellations (#90908)
* fix(model-fallback): don't rethrow provider-side AbortErrors as user cancellations

When the LLM API closes the connection mid-stream, the fetch layer
surfaces AbortError("This operation was aborted") with no external
abort signal triggered. The old guard `shouldRethrowAbort()` returned
false for these errors (because isTimeoutError matched the message),
so they fell through to the fallback loop but were never retried —
the error propagated up and produced SILENT_REPLY_TOKEN in group
sessions, permanently silencing the topic.

Replace the guard with a direct check: only rethrow AbortError when
the external abort signal is actually set (user/gateway cancellation).
Provider-side AbortErrors without an external signal now fall through
to the next fallback candidate, giving the system a chance to recover.

* fix(cron): forward abort signal into runWithModelFallback

Thread the cron executor's abort signal into the shared
runWithModelFallback call so that cron timeouts and cancellations
stop the fallback chain instead of retrying with the next candidate.

Previously, the run callback checked params.abortSignal?.aborted and
threw, but runWithModelFallback itself had no signal — so the new
guard in model-fallback.ts could not distinguish a caller abort from
a provider-side AbortError and would retry silently.

Also adds a focused regression test verifying the signal is forwarded.

---------

Co-authored-by: Shengting Xie <shengting@openclaw.ai>
Co-authored-by: yayu <yayu@yayuMacStudio.local>
2026-06-27 20:53:16 +03:00
Gio Della-Libera
1bdde66950 Doctor: expose plugin registry findings (#96169)
Merged via squash.

Prepared head SHA: cf4399955e
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
2026-06-27 10:00:50 -07:00
Vincent Koc
b8e3de1160 fix(telegram): recover stalled ingress spool claims (#97118)
* fix(telegram): drain ingress with native queue claims

* fix(telegram): bound native claim drain snapshots

* fix(telegram): recover pid-reused ingress claims

* fix(channels): block claimed candidate lanes

* fix(telegram): recover stalled ingress spool claims

* test(telegram): cover native claimNext drain stalls

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-06-27 09:14:14 -07:00
mikasa
b9c64142e2 fix(agents): keep missing tool results on current model (#95543) 2026-06-27 19:06:56 +03:00
Gio Della-Libera
cb4244fe15 Doctor: expose state integrity findings (#95979)
Merged via squash.

Prepared head SHA: eb3bd1adad
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
2026-06-27 08:31:56 -07:00
Gio Della-Libera
4010b81a77 Refactor external plugin catalog toward feeds (#95846)
Merged via squash.

Prepared head SHA: 82d05bdc46
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
2026-06-27 07:41:40 -07:00
mushuiyu886
5ccfc97b31 fix(google): bound TTS success JSON response reads (#96984) 2026-06-27 07:00:36 -07:00
joshavant
fbfadbd806 test: relax local TUI PTY startup wait 2026-06-26 23:08:14 -05:00
Josh Avant
6f1076351c fix: defer active implicit session rollover (#97164) 2026-06-26 22:42:45 -05:00
joshavant
898ca9741c test(trajectory): cover truncated usage preservation 2026-06-26 22:34:55 -05:00
lin-hongkuan
bf2a8ecfdb fix(trajectory): preserve usage in truncated events 2026-06-26 22:34:55 -05:00
Josh Avant
cee2aca409 Scope agent cron operations to the calling agent (#96883)
* Scope agent cron operations to caller

* Scope OpenClaw tools MCP cron by session

* Address cron scope review feedback

* Preserve unscoped cron update retargeting

* Move cron caller identity into gateway context

* Clarify Gateway restart guidance

* Add cron caller identity regression proof
2026-06-26 21:41:14 -05:00
Peter Steinberger
56259606d1 fix(agent-core): ignore truncated tool calls (#97140)
* fix(agent-core): ignore truncated tool calls

Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>

* fix(agent-core): require explicit tool-call terminals

---------

Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>
2026-06-27 03:31:42 +01:00
wangmiao0668000666
1bccd29304 fix(provider-transport-fetch): bound SSE buffer to prevent OOM (#96989)
* fix(provider-transport-fetch): bound SSE buffer to prevent OOM

* fix(provider-transport-fetch): appease oxlint curly rule in test

* fix(provider-transport-fetch): drain events before cap + cancel reader on overflow

* fix(provider-transport-fetch): remove unused encoder from coalesced chunk test

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

* fix(transport): tighten SSE buffer guards

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 08:54:09 +08:00
pick-cat
498567190d fix(agents): guard delivery-evidence attachment recursion against cycles (#97041)
* fix(agents): guard delivery-evidence attachment recursion against cycles

* fix(agents): guard delivery-evidence attachment recursion against cycles

* fix(agents): guard delivery-evidence attachment recursion against cycles

---------

Co-authored-by: Pick-cat <266665499+Pick-cat@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 08:52:46 +08:00
wangmiao0668000666
5880e0afc4 fix(openai-chatgpt-responses): bound streaming success-body SSE reads at 16 MiB (#96762)
* fix(openai-chatgpt-responses): bound streaming success-body SSE reads at 16 MiB

Apply createSseByteGuard to src/llm/providers/openai-chatgpt-responses.ts
(parseSSE) so the ChatGPT Responses SSE parser cannot be exhausted by a
hostile or malfunctioning endpoint that streams an unbounded SSE body.
The 16 MiB cap matches the non-streaming readProviderJsonResponse cap.

What changed:
- src/llm/providers/openai-chatgpt-responses.ts: wrap body.getReader() in
  createSseByteGuard before the existing parseSSE loop. The function is
  also re-exported as parseSSEForTest for direct test access.
- Inline test added to openai-chatgpt-responses.test.ts: hostile 1 MiB
  pull stream, asserts canonical overflow message, cancel(reason) was an
  Error instance, pullCount bounded to 17-20.

Reuses the createSseByteGuard helper from src/agents/streaming-byte-guard.ts
(introduced in #96701 for the anthropic-transport-stream path; same
helper, same 16 MiB cap, same overflow-error shape). This PR is the
third of the planned per-surface rescue series for the previously closed
PR #96666, after PR #3b (#96723).

No SDK surface change. No repro script committed (proof in this body).

* fix(openai): bound ChatGPT error body reads

* fix(openai): bound chatgpt error parsing

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 08:35:10 +08:00
mushuiyu886
65fec9d787 fix(voice-call): emit canonical session keys (#89884)
* fix(voice-call): scope generated session keys by agent

* docs(voice-call): document session key canonicalization

* test(voice-call): prove legacy session migration

* fix(voice-call): preserve canonical session ownership

* fix(sessions): isolate opaque nested identities

* fix(voice-call): preserve routing ownership

* fix(voice-call): enforce inbound route direction

* fix(sessions): preserve migration and policy boundaries

* fix(sessions): normalize ambiguous main aliases

* fix(sessions): preserve canonical peer and warning paths

* fix(sessions): exclude mixed-case scoped legacy keys

* fix(sessions): cover first-run plugin migration gaps

* fix(sessions): compare aliased store identities

* fix(sessions): coalesce aliased store ownership

* fix(sessions): defer ambiguous aliased migrations

* fix(sessions): preserve shared migration boundaries

* fix(sessions): preserve opaque peer ownership

* fix(sessions): reject ambiguous ownership shapes

* fix(sessions): preserve transcript rewrite keys

* fix(sessions): close routing and migration ambiguities

* fix(sessions): preserve plugin-owned ACP aliases

* fix(sessions): retain physical store ownership

* fix(sessions): restore configured store owners

* fix(sessions): reject malformed store owners

* fix(sessions): validate ACP store ownership

* fix(sessions): include canonical store owners

* fix(sessions): preserve final store symlinks

* fix(sessions): retain shared row owners

* fix(sessions): close legacy policy gaps

* fix(sessions): preserve aliases across migrations

* fix(sessions): resolve first-run store ownership

* fix(sessions): preserve hostile legacy keys

* fix(sessions): inspect unlisted store owners

* test(doctor): refresh migration harness

* fix(sessions): preserve opaque route segments

* fix(sessions): retain metadata during migration

* fix(sessions): fail closed on store alias uncertainty

* fix(sessions): defer aliased store rewrites

* fix(sessions): retain legacy row owners

* test(sessions): harden migration proof

* fix(sessions): migrate opaque agent keys

* chore(plugin-sdk): refresh API baseline

* fix(voice-call): reuse public routing parser

* fix(sessions): retain readable alias warnings

* fix(sessions): reject opaque nested routes

* fix(sessions): share strict delivery parsing

* test(voice-call): preserve malformed Matrix case

* fix(sessions): reject legacy peer overlap

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-27 01:29:58 +01:00
Bartok
4d9cd7d227 fix(agents): truncate exec command detail on code-point boundaries (#96963)
* fix(agents): truncate exec command detail on code-point boundaries

compactRawCommand in src/agents/tool-display-exec.ts middle-truncated the
one-line command with raw String.prototype.slice. When the head or tail
boundary fell between the two UTF-16 code units of a surrogate pair (e.g. an
emoji like U+1F600), the slice kept a lone surrogate, which renders as the
replacement character in the tool-call summary shown in chat/transcripts.

Use the existing sliceUtf16Safe helper for both ends so the boundary falls on
a code-point boundary, dropping the whole emoji instead of half of it. This is
behavior-preserving for non-surrogate input.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor: move surrogate-safe slice helpers to browser-safe module

ClawSweeper flagged that importing sliceUtf16Safe from src/utils.ts into
tool-display-exec.ts pulls node:fs/os/path into the Control UI browser-shared
bundle (ui/vite.config.ts treats tool-display-exec.ts as browser-shared).

Move sliceUtf16Safe/truncateUtf16Safe into a self-contained, dependency-free
module src/shared/text/surrogate-safe-slice.ts. src/utils.ts re-exports them
(zero churn for existing Node-side callers), and tool-display-exec.ts now
imports directly from the node-free module so no Node built-ins can leak into
the browser bundle.

* fix(agents): use shared utf16 helper in exec display

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 08:24:14 +08:00
Wynne668
4932366b92 fix(cli): keep built-in nodes commands off the plugin load path (#96702)
registerNodesCli unconditionally registered plugin CLI commands, so
lightweight built-in commands like `nodes status`/`nodes list` paid the
full plugin CLI/runtime load cost. Only resolve plugin-provided node
subcommands (e.g. `nodes canvas`) when the invoked subcommand is not
already a built-in, keeping the built-in nodes path fast.

Fixes #96697
2026-06-27 08:11:31 +08:00
Bartok
e09b9dfc1b fix(agents): truncate tool-display detail on code-point boundaries (#96958)
* fix(agents): truncate tool-display detail on code-point boundaries

coerceDisplayValue truncated a long first-line detail value with raw
UTF-16 slice() at half = floor((maxStringChars-1)/2). When an emoji
(surrogate pair) straddles the cut boundary, the head kept a lone high
surrogate and the tail could begin on a lone low surrogate, rendering as
the replacement character. Use the existing sliceUtf16Safe helper so the
whole code point is dropped at the boundary, matching the UTF-16-safe
truncation used elsewhere in the repo. Behavior-preserving for
non-surrogate input.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(build): import surrogate-safe slice from node-free leaf module

tool-display-common.ts is in the UI browser bundle graph; importing
sliceUtf16Safe from utils.js dragged node:fs (via infra/fs-safe) into the
bundle and broke build-artifacts/QA Smoke. Extract sliceUtf16Safe/truncateUtf16Safe
into src/shared/utf16-slice.ts (dependency-free) and re-export from utils.js to
preserve the existing import surface.

* fix(build): import surrogate-safe slice from node-free leaf module

* fix(build): import surrogate-safe slice from node-free leaf module

* fix(build): import surrogate-safe slice from node-free leaf module

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 08:10:06 +08:00
Patrick Erichsen
808c227edb feat: scaffold provider plugins from init (#94352)
* feat: scaffold provider plugins from init

* fix: satisfy plugin init scaffold CI guards

* fix: preserve plugin init id argument
2026-06-26 16:43:51 -07:00
mushuiyu886
deb0ffdcdf fix #94040: [Bug]: nodes approve failed: GatewayClientRequestError: unknown requestId (#94452)
* fix(nodes): explain unknown approval request ids

* fix(nodes): keep stale request handling CI-clean

* fix(nodes): point stale approve hint at pending command

* fix(nodes): explain stale approval request ids

* fix(nodes): make stale approval guidance reliable

* fix(nodes): preserve stale approval error context

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-27 00:40:29 +01:00
mushuiyu886
a846b879ec fix(mcp): include image source for screenshot results (#90902)
* fix(mcp): emit image content with base64 source

* fix(mcp): keep plugin tool images in SDK schema

* test(mcp): exercise image bridge end to end

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-27 00:39:40 +01:00
Galin Iliev
6883c6c070 fix: wake yielded parent after subagents finish (#97090)
* fix: wake yielded subagent parents after descendants settle

* fix: wake yielded subagent parents after descendants settle

---------

Co-authored-by: Galin Iliev <Galin.Iliev@microsoft.com>
2026-06-26 16:31:20 -07:00
xingzhou
91726e9624 fix(cron): reject invalid no-output timeout (#96516)
* fix(cron): reject invalid no-output timeout

* fix(cron): validate command output limits

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-27 00:28:45 +01:00
pick-cat
6db4624f43 fix(auth): suppress recovery hint for format failures (#95779)
* fix(auth): suppress recovery hint for format failures

* test(auth): cover format failure recovery copy

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-27 00:27:25 +01:00
ly-wang19
aca905cce5 perf(sessions): find matching checkpoints without sorting (#96964)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-27 06:53:48 +08:00
zw-xysk
ab966c214b fix(tools): treat no-op writes and edits as terminal tool-loop failures (fixes #96983) (#97044)
* fix(tools): treat no-op writes and edits as terminal tool-loop failures

Fixes #96983

* fix(tools): treat no-op writes and edits as terminal tool-loop failures

Fixes #96983

* fix(tools): preserve valid sibling edits in mixed no-op batches

Fixes #96983

* fix(tools): terminate apply_patch no-ops safely

* fix(tools): validate no-op edits independently

* fix(tools): preserve no-op edit overlap checks

* fix(tools): preserve no-op patch file formatting

* fix(tools): preserve move no-op formatting

* fix(tools): narrow same-path move no-op typing

* fix(tools): distinguish edit no-op errors

* fix(tools): keep edit previews aligned with execution

* fix(tools): align no-op validation and formatting

* fix(tools): preserve empty patch and preview no-ops

* fix(tools): preview fuzzy edit no-ops cleanly

* fix(tools): isolate fuzzy-equivalent edit no-ops

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 06:41:26 +08:00
ly-wang19
41c00a65d6 perf(status): select recent sessions without full sort (#96955)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-27 06:33:00 +08:00
Vincent Koc
eba1ca683f test(i18n): include Hindi and Russian registry locales 2026-06-26 15:23:10 -07:00
ly-wang19
c1336b6b41 perf(plugins): classify cached tool candidates once (#96948)
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-27 05:49:35 +08:00
ly-wang19
d4a01e48bc fix(link-understanding): strip markdown links whose label contains brackets (#96476)
Merged via squash.

Prepared head SHA: 2d69ed259f
Co-authored-by: ly-wang19 <94427531+ly-wang19@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-27 05:43:11 +08:00
ly-wang19
a0e9ca1e95 perf(update): reuse missing plugin payload id set (#96950)
* perf(update): reuse missing plugin payload id set

* perf(update): reuse missing plugin payload id set

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 05:32:38 +08:00
Bartok
2968004680 fix(chunk): keep surrogate pairs whole when hard-splitting an over-long line (#96951)
chunkByNewline length-splits a single over-long line that has no usable break
point. The first head cut used a raw UTF-16 slice (lineValue.slice(0,
firstLimit)), so when firstLimit landed inside a surrogate pair it emitted a
chunk ending in a lone high surrogate and a next chunk starting with a lone low
surrogate, which render as U+FFFD on delivery. The recursive chunkText that
handles the remainder is already surrogate-safe; only this first cut was raw.

Route the head cut through avoidTrailingHighSurrogateBreak (the same helper
chunkText and chunkMarkdownText already use) so the cut backs off to a
code-point boundary. ASCII and non-surrogate cuts are unaffected. Reproduces at
the production-default 4096 limit for emoji-dense lines; chunkByNewline is the
published plugin-SDK channel.text helper, reachable with arbitrary outbound text.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 05:21:45 +08:00
Bek
9636bea901 perf(memory): add QMD search diagnostics and runtime cache (#96655) 2026-06-26 16:16:12 -04:00
NIO
527f8f0cbb fix(image-gen): bound image generation provider JSON response reads (#96495)
* fix(image-gen): bound image generation provider JSON response reads

Route success JSON reads through readProviderJsonResponse (16 MiB cap)
in openrouter, google, fal, minimax, openai, and vydra image generation
providers to prevent OOM from oversized or hostile endpoint responses.
Mirrors the response-limit campaign already applied to other provider paths.

AI-assisted.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(image-gen): size bounded JSON caps for inline image payloads

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sallyom <somalley@redhat.com>
2026-06-26 07:08:30 -04:00
Jesse Merhi
ec737ee74d fix: rebase clawhub install trust (#81364) 2026-06-26 18:33:19 +10:00
Liu Wenyu
9a735bea03 fix(outbound): ignore empty delivery receipts (#79811) 2026-06-26 09:40:46 +02:00
xingzhou
e9f9a68d68 fix(weixin): startAccount preserves session routing (#93686)
* fix(channels): resolve manifest account config by normalized id

* fix(routing): ignore blocked keys during normalized account lookup

* fix(routing): block normalized unsafe account keys

* test(routing): type normalized account lookup case

* trigger CI

* fix account lookup invalid key fallback

* fix(weixin): startAccount preserves session routing (#93686) (thanks @zhangguiping-xydt)

---------

Co-authored-by: sliverp <870080352@qq.com>
2026-06-26 14:36:49 +08:00
Josh Avant
db255b1154 Fix Telegram spooled claim refresh (#96962) 2026-06-26 01:30:57 -05:00
Gio Della-Libera
4fc504d321 Doctor: add lint --all (#96471)
* fix(doctor): keep audit scrub lint opt-in

* fix(doctor): keep audit lint defaults internal

* feat(doctor): add lint profiles
2026-06-25 22:26:42 -07:00
Jesse Merhi
0fdfc9f65f fix(exec): harden backend sandbox exec cleanup (#96926) 2026-06-26 13:51:52 +10:00
brokemac79
a0b397748f fix(status): restore Codex synthetic usage in status 2026-06-25 17:37:30 -07:00
brokemac79
dd0e4f6e61 fix: avoid plugin update range fallback after metadata failure (#96143)
Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-06-25 17:15:50 -07:00