Commit Graph

66965 Commits

Author SHA1 Message Date
yashkot007
e99f254f1c fix(cron): treat exact-second cron slots as valid in stale-future repair (#81731)
isStaggeredCronRunAtMs probed the cron library at runAtMs + 1 to decide
whether a persisted nextRunAtMs was a real schedule slot. Croner-style
second-granular schedules normalize that 1ms probe back to the candidate
second, so previousRuns(1, runAtMs + 1) returns the slot before the
candidate instead of the candidate itself. shouldRepairFutureCronNextRunAtMs
then classified valid exact-second slots two-plus intervals out as stale
and rebased them.

Probe at runAtMs + 1_000 instead so the previous-run lookup lands past the
candidate second, matching the +1s cursor step used elsewhere in this file.

Fixes #81691

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-28 15:19:07 -07:00
RayRuan
542e9a4e67 Fix getSubagentDepth for legacy subagent session keys (AI-assisted) (#54593)
The previous implementation split on ':subagent:' which requires
colons on both sides. Legacy session keys like 'subagent:worker'
(starting without a colon) were missed and returned depth 0.

Fix: normalize key, match (^|:)subagent: pattern to correctly count
nested subagent levels for both legacy and current key formats.

- Add test cases for legacy key formats

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-28 15:17:30 -07:00
John McChesney TenEyck Jr
a54206f0f5 Fix iOS chat Dynamic Type text (#97552)
Co-authored-by: Your Name <you@example.com>
2026-06-28 14:52:37 -07:00
Jayesh Betala
8f31b3218f Fix Discord gzip response parsing (#80788)
* Fix Discord gzip response parsing

* fix(discord): decode gzipped REST responses

* fix(clownfish): address review for live-pr-repair-20260628T212840-001 (1)

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-28 14:43:28 -07:00
kiranmagic7
a54919dcbc fix(cli): differentiate gateway-restart hint for hot-loadable agent config sets (#80722) (#80823)
* fix(cli): narrow config hint branch

* Plan config hints from actual changes

* Plan direct unset hints from actual changes

* Expand broad unset hint paths

* fix(cli): respect reload mode in config hints

---------

Co-authored-by: Kiran Magic <kiran@Alices-Laptop.local>
Co-authored-by: kiranmagic7 <262980978+kiranmagic7@users.noreply.github.com>
2026-06-28 14:20:54 -07:00
NIO
91297bf420 fix(google): bound embedding-batch JSON response reads (#97535)
* fix(google): bound embedding-batch JSON response reads

* fix(google): repair embedding-batch test types and lint

---------

Co-authored-by: NIO <nocodet@mail.com>
2026-06-28 14:20:28 -07:00
Arnav Panicker
8e69811560 docs(cli): clarify strict json parsing (#80981) 2026-06-28 14:19:19 -07:00
Gio Della-Libera
9bb004359e Add marketplace feed entries command (#96158)
Merged via squash.

Prepared head SHA: 1289a25156
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-28 14:11:29 -07:00
linhongkuan
d1d0176acc fix(terminal-core): strip controls from terminal links (#96440)
* fix(terminal-core): strip controls from terminal links

* fix(terminal-core): sanitize hyperlink fallback text

* fix(terminal-core): preserve empty fallback

---------

Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
2026-06-28 14:09:19 -07:00
zengLingbiao
686a2876c7 fix(cron): truncate failure alert error text on UTF-16 boundary (#97298)
* fix(cron): truncate failure alert error text on UTF-16 boundary

* test(cron): add regression test for UTF-16 safe failure alert truncation

Verify that emitFailureAlert does not produce dangling surrogates when
truncating a cron failure error message with a non-BMP character (emoji)
straddling the 200-code-unit truncation boundary.

* fix(test): cover last code unit in surrogate scan

The dangling surrogate check loop stopped at length-1, missing a
high surrogate at the final position. Extend to i < alertText.length
so charCodeAt(i+1) returns NaN for the last char, correctly failing
the high-surrogate pair assertion.

* fix(test): address lint issues in regression test

- Use template literal instead of string concatenation
- Add braces to type guard if-statement
2026-06-28 13:59:06 -07:00
zengLingbiao
c9d2edfb7e fix(shared): use UTF-16 safe truncation in subagent line display (#97557)
* fix(shared): use UTF-16 safe truncation in subagent line display

truncateLine sliced by code units instead of preserving surrogate pairs,
causing emoji / CJK Extension B characters at the truncation boundary
to display as broken replacement characters.

* fix(shared): move import above export to satisfy import/first lint rule
2026-06-28 13:58:58 -07:00
JC
78029e43d2 fix(doctor): warn and document QMD session recall gates (#80947)
* Warn on QMD session recall export mismatch

* Clarify session transcript recall gates
2026-06-28 13:55:27 -07:00
Zhang
f37e45ecc1 Add prototype pollution guard to resolveConfigPath (#59694)
* config: block prototype keys in config path resolver

* config: guard config defaults fallback
2026-06-28 13:48:24 -07:00
Zhang
26f92a4f8d Replace SHA-1 with SHA-256 for config fingerprinting (#59695)
* hash: use SHA-256 for bundle MCP fingerprints

* Replace SHA-1 with SHA-256 for config fingerprinting

* Replace SHA-1 with SHA-256 for config fingerprinting

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-28 13:38:24 -07:00
Darshan Paccha
7236e5f89f fix(issue-template): split logs and screenshots into separate fields (#73649)
* fix: remove render shell from bug report template

* fix: split logs and screenshots in bug report template
2026-06-28 13:38:16 -07:00
Martins Lasmanis
904c8717d0 fix(gateway): handle exec approvals persistence errors (#79861) 2026-06-28 13:31:18 -07:00
ly-wang19
a1d1381c2b fix(web-fetch): decode astral HTML entities and stop double-decoding &amp; (#96268)
* fix(web-fetch): decode HTML entities via the shared canonical decoder

web_fetch's hand-rolled decodeEntities used String.fromCharCode (truncating
astral entities like emoji to garbage) and decoded &amp; first (double-decoding
"&amp;#39;" into "'"). Route entity decoding through the shared
decodeHtmlEntityAt in agents/utils/html.ts so web_fetch and the renderer share
one entity contract — the divergence is what produced the bug. A single
left-to-right pass also avoids the double-decode (the "&amp;" is consumed before
its trailing "#39;" is seen as an entity); &nbsp; is mapped to a space, which
the shared decoder does not cover.

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

* fix(web-fetch): preserve entity contract in shared HTML entity decoder

Addresses the ClawSweeper review: decodeHtmlEntityAt matched only lowercase
named entities and used a lenient Number.parseInt, so routing web_fetch through
it changed the prior contract — uppercase forms like &AMP; were left escaped,
and a malformed numeric entity like &#39x; was consumed as "'" (parseInt stops
at the first non-digit). Match named entities case-insensitively and require
numeric references to be fully valid digit/hex tokens, restoring web_fetch's
/gi-style named matching and strict numeric handling while keeping the
single-pass shared-decoder boundary. Strictly more correct for the other caller
(syntax-highlight), which only emits well-formed lowercase entities. Adds
regression tests for uppercase named entities and malformed numeric input.

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

* ci: retry — cross-os socket-close flake is main-branch, unrelated to web-fetch entity decode

---------

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-28 13:28:13 -07:00
Sam
3cabde7a4a fix(control-ui): honor verbose level for tool expansion (#74398)
* fix(control-ui): honor verbose level for tool expansion

* chore: drop release-owned changelog entry

---------

Co-authored-by: Sami Rusani <sr@samirusani>
2026-06-28 13:26:26 -07:00
Sasan
201686d9e3 fix(agent-tools): resolve workspace-scoped tool fs root lazily (#89226)
* fix(agent-tools): resolve workspace-scoped tool fs root lazily

Workspace-scoped edit/write tools resolved their fs-safe root eagerly at
construction. Doctor's active-tool schema projection builds the full coding
toolset just to read tool schemas; when an agent workspace dir is absent at
that time (e.g. an unresolved ${ENV} placeholder in the authored config the
legacy-migration path operates on), the eager fsRoot orphaned a rejecting
promise as 'Unhandled promise rejection: FsSafeError: root dir not found'.

Resolve the root lazily and memoized so construction never opens an fs handle;
the root is only opened on the first real read/write/access operation.

* fix(agent-tools): defer fs-safe root start until workspace write validation succeeds

A workspace-only write/edit against an absent root started fsRoot(root) eagerly
(passed as getRoot() into writeWorkspaceFile) before toCanonicalRelativeWorkspacePath
ran. When validation failed (realpath on the missing root), the rejecting root promise
was left unawaited and surfaced as an unhandled rejection — the readFile/access paths
already defer getRoot() the same way.

writeWorkspaceFile now takes a getRoot thunk and calls it only after validation; the
write and edit-write callers pass the thunk instead of a started promise. Adds a
regression that a missing-root write/edit rejects without starting the fs-safe root or
emitting an unhandled rejection.

---------

Co-authored-by: Sasan <sasan.sotoodehfar@gmail.com>
Co-authored-by: Gio Della-Libera <giodl73@gmail.com>
2026-06-28 13:26:21 -07:00
zengLingbiao
19617b0b45 fix(agent-core): avoid splitting surrogate pairs in grep line truncation (#97559)
truncateLine could cut a surrogate pair when the maxChars boundary
fell between a high surrogate and its paired low surrogate, producing
a broken unpaired surrogate in grep tool output.
2026-06-28 13:26:15 -07:00
xingzhou
cc757839d5 fix: proxy streams fail fast on oversized or stalled responses (#97235)
* fix proxy response and SSE read bounds

* test(line): reuse surrogate regex in action tests

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-28 13:04:47 -07:00
黄伟浩
f4201578e5 fix(matrix): warn on accumulated token storage roots (#97353) 2026-06-28 12:34:52 -07:00
qingminlong
1a1587963a fix: preserve cron sessions with stale transcript metadata (#97495)
* fix: repair stale session cleanup transcript metadata

* fix: report repaired session cleanup metadata
2026-06-28 12:29:37 -07:00
NIO
b948c86b2a fix(telegram): bound getChat Bot API response reads (#97274)
* fix(telegram): bound getChat Bot API response reads

* fix(telegram): repair getChat bound-read type and proof script lint

---------

Co-authored-by: NIO <nocodet@mail.com>
2026-06-28 12:29:14 -07:00
NIO
a07d59e014 fix(telegram): bound Bot API response reads to prevent OOM (#97271)
* fix(telegram): bound Bot API response reads to prevent OOM

* fix(scripts): make proof-telegram-bound.mjs lint-clean

---------

Co-authored-by: NIO <nocodet@mail.com>
2026-06-28 12:28:51 -07:00
黄伟浩
35fcfe85cd fix(plugins): preserve mutable hook context (#97281)
* fix(plugins): preserve mutable hook context

* fix(plugins): satisfy hook context lint
2026-06-28 12:28:30 -07:00
aliahnaf2013-max
f527def0a9 fix(tasks): harden ACP task cancellation (#97352)
* fix(tasks): harden acp task cancellation

* test(gateway): cover acp task cancellation handler
2026-06-28 12:27:49 -07:00
WhatsSkiLL
7ac8b48a08 fix: flush embedded transcript before afterTurn (#97342)
Fixes #97301

Co-authored-by: OpenClaw PR Agent <openclaw-pr-agent@example.invalid>
2026-06-28 12:22:58 -07:00
qingminlong
9f66f61d05 docs: add scripts directory index (#97250) 2026-06-28 12:19:30 -07:00
Yung-Chen Tang
f3bcee8b2e fix: clarify pinned plugin dry-run updates (#97282)
* fix: clarify pinned plugin dry-run updates

* fix(plugins): normalize pinned npm dry-run versions
2026-06-28 12:18:31 -07:00
LiLan0125
a083c76621 fix(bedrock): honor adaptive model max tokens (#97343) 2026-06-28 12:15:02 -07:00
wangmiao0668000666
66ffad1176 fix(azure-openai-responses): bound SSE response reads via buildGuardedModelFetch (#97349)
Inject buildGuardedModelFetch with resolved Azure base URL into both
SDK constructors (OpenAI and AzureOpenAI path) so Azure Responses
requests route through OpenClaw's guarded transport (SSRF policy,
timeout, retry limiting, SSE/JSON synthesis caps).

The non-OK response body cap is applied lazily inside the shared
sanitizeOpenAISdkSseResponse guard via TransformStream — closes the
unbounded response.text() OOM path for hostile 4xx/5xx responses
while preserving the OpenAI SDK's ability to cancel and retry.

- src/llm/providers/azure-openai-responses.ts: pass guardedFetch into
  both OpenAI and AzureOpenAI SDK constructors (no per-provider wrapper)
- src/agents/provider-transport-fetch.ts: add capNonOkResponseBodyLazily
  helper and wire into sanitizeOpenAISdkSseResponse for !response.ok
- src/agents/provider-transport-fetch.test.ts: 2 inline tests
  (cap fires + SDK cancel preserves source)

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-28 12:14:53 -07:00
Masato Hoshino
c026546063 fix(signal): sanitize internal tool-trace lines from outbound text (#97360)
Wrap the signal outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).
2026-06-28 12:14:45 -07:00
Masato Hoshino
cd6d0f9b00 fix(slack): sanitize internal tool-trace lines from outbound text (#97367)
Wrap the slack outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).
2026-06-28 12:14:35 -07:00
ly-wang19
20645753a4 fix(feishu): truncate streaming-card summary on a code-point boundary (#97462)
truncateSummary used clean.slice(0, max - 3), which can cut between the
two UTF-16 halves of a surrogate pair (emoji / astral char) straddling
the limit. The serialized card summary then carries a lone high
surrogate that Feishu renders as the replacement char.

Slice with the surrogate-safe sliceUtf16Safe helper instead, matching
the pattern already used in extensions/slack/src/truncate.ts, so a
straddling code point is dropped whole.

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-28 12:10:42 -07:00
aditya-vithaldas
3e90125c88 fix: clarify exec tool failure warnings (#97511)
* clarify exec failure warnings

* fix exec failure raw command labels

* preserve node context in exec failure warnings

* fix exec raw context warnings

* fix exec payload test metadata types

* fix raw exec command backtick parsing

* chore: retrigger ci after security-fast outage

---------

Co-authored-by: aditya-vithaldas <13113194+aditya-vithaldas@users.noreply.github.com>
2026-06-28 12:10:33 -07:00
ly-wang19
3e64d84712 fix(qqbot): treat escaped pipes as literal content when splitting table cells (#97429)
splitTableCells/splitPartialTableCells split on every '|', including a GFM
backslash-escaped pipe ('\|'), which is literal cell content rather than a
column delimiter. A cell containing '\|' was therefore mis-counted as multiple
columns, so the oversized-row fallback (renderTableRowAsFields) rendered the
trailing content under the wrong header.

Split via an escape-aware scan that treats '\|' as a literal '|' (and '\\' as
a literal backslash so a following '|' still delimits). Behavior is byte-for-byte
unchanged for any row without an escaped pipe, so existing chunking is preserved.

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-28 12:03:52 -07:00
Omar Shahine
9b9a124cc5 Fix Codex message-tool-only source reply completion (#95942)
* fix(codex): recognize message tool source replies

* fix(codex): accept numeric source message ids

* fix(codex): account for source reply SDK surface

* fix(codex): require delivered reply receipts

* fix(codex): reject alias-routed source replies

* fix(codex): require delivered non-send telemetry

* fix(codex): honor normalized source routes

---------

Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
2026-06-28 12:02:36 -07:00
ly-wang19
4b36cf451c fix(line): truncate template title/altText on grapheme boundaries, not raw UTF-16 (#97428)
* fix(line): truncate template title/altText on grapheme boundaries, not raw UTF-16

createConfirmTemplate/createButtonTemplate/createTemplateCarousel/createCarouselColumn/
createImageCarousel truncated title and altText with a raw `.slice(0, N)`, so an
emoji straddling a LINE field limit (e.g. a 40-char button title) was cut in half,
leaving a lone high surrogate that LINE renders as the replacement char or rejects.
Route those fields through the file's existing grapheme-safe truncateTemplateText
(already used for the text body) via a small truncateOptionalTemplateText wrapper.
Byte-identical for all-BMP input; only straddling-emoji truncation changes.

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

* chore: retry OpenGrep scan (HTTP 502 infra flake)

* test(line): cover grapheme-safe template fields

---------

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-28 11:59:59 -07:00
ly-wang19
630034ef62 fix(memory-wiki): keep claim freshness tied to evidence timestamps (#97465)
* fix(memory-wiki): keep claim freshness tied to evidence

* fix(memory-wiki): preserve page freshness fallback only for untimestamped claims

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-28 11:58:45 -07:00
Masato Hoshino
25490d4c42 fix(matrix): sanitize internal tool-trace lines from outbound text (#97372)
Wrap the matrix outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).
2026-06-28 11:58:36 -07:00
qingminlong
5e1f4c1073 fix(memory): stop light dreaming from restaging stale summaries (#97446)
* fix(memory): stop restaging stale light dreams

* fix(memory): preserve cross-day light freshness
2026-06-28 11:58:24 -07:00
ooiuuii
3c826ed5c9 fix: shorten managed npm generation paths (#97488) 2026-06-28 11:58:16 -07:00
NIO
245c18da5a fix(agents): retry compaction on provider-side AbortErrors (#97504)
Align inner compaction retry and compaction-safeguard provider fallback
with the #90908 signal.aborted pattern so undici disconnect AbortErrors
retry or fall back to LLM instead of producing degraded placeholder
summaries. Caller abort remains terminal.

Co-authored-by: NIO <nocodet@mail.com>
2026-06-28 11:55:25 -07:00
xingzhou
fb7e10e868 fix(auth): recover from malformed API-key profiles (#97520)
* fix: reject malformed API-key auth profiles

* fix(auth): detect onboard command API-key variants

* fix(auth): reject malformed API-key flags
2026-06-28 11:54:24 -07:00
NIO
4c477ee632 fix(openai): bound embedding-batch and realtime session JSON response reads (#97533) 2026-06-28 11:53:50 -07:00
wangmiao0668000666
bd0c052aa5 fix(oauth): bound github-copilot OAuth response reads at 16 MiB (#97499)
* fix(oauth): bound github-copilot OAuth response reads at 16 MiB

* chore: trigger CI re-run after PR body update
2026-06-28 11:53:46 -07:00
Yung-Chen Tang
fcff01cc82 fix: archive role-ordering reset transcripts (#97544)
* fix: archive role-ordering reset transcripts

* test: fix session reset archive lint
2026-06-28 11:46:54 -07:00
NIO
51064bda4d fix(signal): bound GitHub release info JSON response with readProviderJsonResponse (#97536)
Replace bare `await response.json()` in `installSignalCliFromRelease` with
`readProviderJsonResponse` (16 MiB cap, stream cancel on overflow). The
external GitHub Releases endpoint can include a large `body` changelog field;
the error path was already guarded but the success path was unbounded.
The existing inner catch continues to convert overflow errors into the
graceful `{ ok: false, error: "Failed to parse signal-cli release info." }` path.

Adds a regression test verifying the stream is cancelled before all chunks are
read on an oversized 20 MiB streaming response.

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 11:46:25 -07:00
liuhao1024
ee72fa7f5f fix(auth): skip legacy OAuth repair when destination profile already exists (#97541)
When doctor --fix runs legacy OAuth profile id repair, it picks the
single non-legacy OAuth profile as the migration target. If that target
profile already exists as a separate user-configured account, the repair
unconditionally overwrites it, destroying the account's config
(displayName, email) and collapsing two distinct accounts into one.

Add a guard: if the destination profile id already exists in
cfg.auth.profiles, skip the repair entirely to preserve both accounts.
Also pass cfg to resolveAuthProfileMetadata so config-set displayName
is preserved when the repair does proceed.

Fixes #97522
2026-06-28 11:46:20 -07:00