Commit Graph

67697 Commits

Author SHA1 Message Date
Vincent Koc
c0511692d8 test(plugins): repair prerelease validation fixtures 2026-07-01 18:02:09 -07:00
lsr911
050e1f3b5c fix(discord): guard JSON.parse against malformed API response bodies (#97889)
* fix(discord): guard JSON.parse against malformed API response bodies

Wrap JSON.parse(text) in requestDiscord with try/catch to prevent a malformed Discord API response body from throwing an unhandled SyntaxError and crashing the process. On parse failure, throw a DiscordApiError with a descriptive message so the caller can handle it gracefully.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* fix(clawsweeper): address review for automerge-openclaw-openclaw-97889 (validation-1)

* chore: trigger CI re-run for flaky checks-node-compact-small-whole-2

Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* chore: trigger CI re-run for flaky runtime-inventory-drift-check

Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* chore: trigger CI re-run for flaky checks-node-compact-large-whole-1

Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* fix(discord): guard JSON.parse against malformed API response bodies

* fix(discord): guard JSON.parse against malformed API response bodies

---------

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
2026-07-01 17:50:01 -07:00
Peter Steinberger
27104c1afb fix(codex): preserve app approvals in side forks (#98812)
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
2026-07-02 01:42:28 +01:00
Harjoth Khara
c49714f7b6 fix(agents): don't inject A2A turns into isolated-cron sessions_send (#92257) (#92283)
* fix(agents): don't inject A2A turns into isolated-cron sessions_send (#92257)

Fire-and-forget sessions_send (timeoutSeconds === 0) with announce
delivery runs the A2A ping-pong loop. For a cross-session send
(requester != target) the loop's first iteration feeds the target
agent's reply back into the requester session as a new turn. For a
normal requester that roundtrip is intended, but for an *isolated cron*
requester it injects reply context into the isolated run and causes an
agent feedback loop.

Narrow the fix to isolated-cron requesters only (detected by a session
key containing ":cron:" or channel "cron" -- the same signal used by
src/agents/subagent-registry.ts and set in
src/cron/isolated-agent/run.ts), NOT by timeoutSeconds. Gating on
timeoutSeconds was too broad: it disabled the intended ping-pong for
normal cross-session fire-and-forget sends.

Two hunks in src/agents/tools/sessions-send-tool.ts, both reusing one
`isIsolatedCronRequester` gate:

1. Force maxPingPongTurns to 0 in the runSessionsSendA2AFlow invocation
   only for an isolated-cron requester. The a2a flow's ping-pong guard
   (`maxPingPongTurns > 0`) then skips the requester-injection loop and
   proceeds straight to the announce step in the TARGET session,
   preserving fire-and-forget announce delivery. Normal requesters keep
   the configured turn count.

2. Read baselineReply for fire-and-forget sends when same-session (prior
   behavior) OR isolated-cron. Without a baseline fingerprint, a2a.ts
   would treat pre-existing assistant text in the target session (e.g.
   an unrelated concurrent cron's output) as "the reply" and
   misattribute it. The normal cross-session fire leg's history-call
   count is unchanged from origin/main. Read failures are tolerated so a
   snapshot error never blocks accepting the send.

Tests (sessions.test.ts): an isolated-cron cross-session fire-and-forget
forwards maxPingPongTurns: 0; a normal-requester regression guard
(discord:group:req / channel discord) forwards the configured turn count
(not 0), proving the normal ping-pong is preserved. a2a flow tests
(sessions-send-tool.a2a.test.ts): with turns=0 + requester!=target the
requester is never stepped but the target is still announced, and a
baseline-matching reply is neither injected nor announced.

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

* fix(agents): gate isolated-cron A2A on canonical cron-run classifier (#92257)

Address Codex [P2] review: replace the raw `:cron:` substring detector with
the canonical isCronRunSessionKey so a non-canonical cron-like requester key
(e.g. agent:main:slack:cron:job:run:uuid) keeps its intended cross-session
ping-pong. Keep the requesterChannel === "cron" arm (isolated cron runs set
that channel in src/cron/isolated-agent/run.ts). Add a regression covering the
non-canonical key.

* refactor(agents): drop dead cron-channel A2A arm, gate on canonical key only (#92257)

The requesterChannel === "cron" arm was unreachable: agentChannel is always a
DeliverableMessageChannel from resolveGatewayMessageChannel(messageProvider),
never the literal "cron". The channel: "cron" in src/cron/isolated-agent/run.ts
labels diagnostics events/lifecycle, not the tool channel. Gate on
isCronRunSessionKey alone and fix the misleading comment.

Tests drove the dead arm via agentChannel/requesterChannel "cron" plus a
non-canonical key (agent:main:cron:run:abc, which isCronRunSessionKey rejects).
Switch them to a canonical cron-run key (agent:main:cron:job:run:abc) and a
normal delivery channel so they exercise the real production gate.

* fix(agents): align cron A2A fallback baselines

* chore: prepare branch refresh

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 17:34:26 -07:00
zhangLei99586
273729bd95 fix(browser): guard setDeep against empty keys array (#98138)
When keys is empty, keys[keys.length - 1] returns undefined, and the
previous ??  fallback would silently create a property with an empty
string key on the target object. Add an early return so empty keys are
a no-op instead of silently polluting the object.
2026-07-01 17:29:56 -07:00
Ayaan Zaidi
3558391a75 docs(telegram): move maintainer decisions into scoped AGENTS.md 2026-07-01 17:19:16 -07:00
joshavant
6ad2626cfd fix(ios): generate light app store screenshots only 2026-07-01 19:16:23 -05:00
Masato Hoshino
8e28e88387 fix(gateway): distinguish reachable gateway from failed status probe (#98183)
* fix(gateway): distinguish reachable gateway from failed status probe

* fix(status): gate owns-port RPC recovery guidance on no stale gateway PIDs

inspectGatewayRestart can set health.healthy from bare reachability after
ownership attribution failed, while still returning a non-empty
staleGatewayPids. Printing owns-port recovery guidance in that case
contradicted the dedicated stale-PID diagnostic below it. Require
staleGatewayPids to be empty before treating healthy as owns-port proof.
2026-07-01 17:04:31 -07:00
Vincent Koc
dbf837f574 docs(changelog): refresh 2026.7.1 notes 2026-07-01 16:58:44 -07:00
Peter Steinberger
3e50f41dd6 improve(ios): simplify Talk controls and composer alignment (#98736)
* refactor(ios): streamline talk and composer controls

* test(ios): restore Talk control state

* chore(ios): refresh native i18n inventory
2026-07-02 00:48:37 +01:00
Peter Steinberger
17482a4026 fix(ci): restore docs and test type checks (#98792) 2026-07-02 00:36:52 +01:00
Gio Della-Libera
cdaafe198c doctor: expose channel plugin blocker findings (#97496) 2026-07-01 16:31:52 -07:00
Ayaan Zaidi
f8769559ae fix(telegram): honor long flood-wait retry_after on outbound sends 2026-07-01 16:22:34 -07:00
Ayaan Zaidi
fd18e39e51 fix(telegram): drop rejected native quotes instead of failing the send 2026-07-01 16:22:34 -07:00
Ayaan Zaidi
a53833e842 fix(telegram): fall back to plain captions when Telegram rejects caption HTML 2026-07-01 16:22:34 -07:00
Ayaan Zaidi
6ef0abbaae fix(telegram): fall back to plain text when rich entities are rejected on the durable send path 2026-07-01 16:22:34 -07:00
joshavant
03d23c56d1 Document Android release failure stop rule 2026-07-01 18:09:57 -05:00
joshavant
0ea304d02f Add Android release agent guardrails 2026-07-01 18:09:57 -05:00
joshavant
3832b2be5f Document iOS release failure stop rule 2026-07-01 18:04:50 -05:00
joshavant
77f632e7db Add iOS release agent guardrails 2026-07-01 18:04:50 -05:00
anagnorisis2peripeteia
6df7db9f9e feat(cli): add attach launcher (#96454)
* feat(cli): openclaw attach — launch Claude Code bound to a gateway session with scoped MCP tools
* fix(cli): use token-only MCP config for attach

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-07-01 15:52:39 -07:00
Ayaan Zaidi
55d31beeef fix(telegram): age-gate retry-limit spool tombstones (#98776) 2026-07-01 15:32:00 -07:00
Ayaan Zaidi
ce9ec4e1c3 fix(telegram): tombstone completed spooled updates to dedupe refetches 2026-07-01 15:32:00 -07:00
Ayaan Zaidi
eb41c7d2d3 fix(telegram): requeue spooled replays on transient store errors 2026-07-01 15:32:00 -07:00
Ayaan Zaidi
8dbcf6db16 fix(telegram): back off and dead-letter poisoned spooled updates 2026-07-01 15:32:00 -07:00
joshavant
341231831b chore(android): prepare 2026.6.11 Play release 2026-07-01 17:26:11 -05:00
Ayaan Zaidi
5a10a29807 fix(telegram): retry transient getUpdates API errors in ingress worker 2026-07-01 15:24:05 -07:00
Ayaan Zaidi
abaef63a35 fix(telegram): persist only new sent-message cache entries 2026-07-01 15:24:05 -07:00
Kevin Lin
d9b5afad18 fix(codex): rename destructive approval mode to ask (#98501)
* fix(codex): rename destructive approval mode to ask

* fix(codex): keep ask reviewer app-scoped

* test: fix current-main CI regressions
2026-07-01 15:14:55 -07:00
Josh Avant
eb417fa206 fix: diagnose Windows LAN Gateway firewall blocks (#98666)
* Diagnose Windows LAN Gateway firewall blocks

* Fix Windows firewall diagnostic lint

* fix: gate gateway firewall diagnostics to local targets

* fix: keep firewall inspection off critical flows
2026-07-01 16:24:16 -05:00
Darren2030
e79865569c fix(install): preserve SecretRef service env values (#96065)
* fix(install): manage config-secretref env refs via OPENCLAW_SERVICE_MANAGED_ENV_KEYS
* fix(install): preserve config secret refs in launchd env
* fix(install): preserve secretref env render sources

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-07-01 14:04:33 -07:00
Ayaan Zaidi
bc7f9a36ec fix(cron): detach session-targeted cron runs (#98755)
* fix(cron): detach session-targeted runs
* fix(tasks): cancel stale childless cron rows

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-07-01 14:04:25 -07:00
Ayaan Zaidi
44e88f550b fix(telegram): keep media retry policy local 2026-07-01 13:05:42 -07:00
luoyanglang
f9d7afda10 fix(telegram): narrow durable inbound media retry to transient + abort (#98076)
Review on #98102: the durable-retry classifier treated every MediaFetchError
`fetch_failed` as retryable, but `fetch_failed` also covers permanent failures
(SSRF/guard denials, local Bot API path/read errors). On spooled replay those
would requeue forever with the user-facing warning suppressed.

Move the policy to its owner: add `isDurablyRetryableMediaFetchError` to
`src/media/fetch.ts`, defined as `shouldRetryMediaFetch` (the canonical in-loop
transient policy) plus shutdown/abort `fetch_failed`. A restart-window abort is
the primary inbound-media loss vector and is recoverable on replay, whereas
in-loop retry mid-shutdown is futile; permanent `fetch_failed`, other 4xx, and
size limits stay non-retryable so they cannot loop in the spool.

Telegram reuses the shared helper instead of a local classifier
(`isAbortError`/`isTransientNetworkError` live in core; the classification must
not drift). Adds permanent-`fetch_failed` regression coverage at the unit and
behavioral level. Media-group partial delivery (#55216) unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:05:42 -07:00
luoyanglang
14a6cd9ee6 fix(telegram): durably retry inbound media dropped during restart (#98076)
A single-message inbound media fetch failure was handled best-effort: warn
and let the update complete, so bot-core acked the spooled update. During a
restart window the warning send also failed and the document was silently
lost with no durable retry.

Classify transient media fetch failures (network/abort fetch_failed and
408/429/5xx HTTP) and record them as failed-retryable, so spooled-replay
updates are kept and re-driven by the ingress spool with backoff instead of
acked. Live updates still ack and warn; permanent failures (size limit, 4xx)
stay best-effort. The retry notice is suppressed on spooled replay to avoid
repeating it on each replay.

The durable-retry classifier deliberately diverges from media/fetch.ts
shouldRetryMediaFetch on shutdown aborts: in-loop retry of a shutdown abort
is futile, but durable re-spool must retry it -- that abort is the primary
restart-window loss vector. Media-group partial delivery (#55216) is left
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:05:42 -07:00
fsdwen
44cb3f7b98 fix(agents): prevent duplicate subagent announce sends
Fixes the subagent announce prompt-lock race by treating lock-change failures with visible-send evidence as terminal, while keeping pre-send failures retryable.

Scoped proof:
- node scripts/run-vitest.mjs src/agents/subagent-announce-delivery.test.ts src/agents/subagent-announce.test.ts src/agents/subagent-registry-lifecycle.test.ts
- node scripts/run-tsgo.mjs -p tsconfig.core.json
- node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.agents.json
- oxfmt --check on touched agent files
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local

Thanks @fsdwen!
2026-07-01 12:55:15 -07:00
Peter Steinberger
ab2f6f5642 feat: prepare scoped conversation capability profiles (#98536)
* feat(agents): prepare scoped conversation capability profiles

* fix: satisfy scoped profile lint

* test: update compaction harness agent-scope mock
2026-07-01 20:28:58 +01:00
Peter Steinberger
24d94a54a5 fix: migrate QQBot credential backups to SQLite KV (#89597)
* fix: migrate qqbot credential backups to sqlite kv

* fix: complete qqbot sqlite migration cleanup

* fix: harden qqbot doctor state migration
2026-07-01 20:03:59 +01:00
Mark
5db7c3797d Fix Telegram plugin callback routing (#97174)
* fix telegram plugin callback routing

* Add Telegram callback proof coverage

* Fix proof script lint

* Fix Telegram proof CI regressions

* test: fix telegram callback proof CI regressions

* fix: retire registry-owned callbacks

* fix: retire registry-owned callbacks

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-01 19:49:54 +01:00
Omar Shahine
d0b30e0deb fix(imessage): shed emoji anywhere in poll-vote echo match (#98691)
* fix(imessage): shed emoji anywhere in poll-vote echo match

iMessage native poll options carry a trailing emoji ("Lobster 🦞 ") while the
agent echoes its vote with a leading one ("🦞 Lobster.") under message_tool_only
reply mode. normalizePollEchoText stripped only a leading emoji prefix, so
"lobster 🦞" never matched "lobster" and the redundant text leaked past the
poll_vote_echo guard (shipped in #98421).

Shed emoji anywhere across every class: pictographic, regional-indicator flags
(🇺🇸), subdivision-flag tag chars, ZWJ, skin-tone, and keycap sequences cleared
as a unit (so "1️⃣" -> "" not "1", while a plain "1"/"#"/"*" survives). Internal
punctuation stays so C#/C++/Node.js remain distinct; emoji-only labels normalize
to empty and the guard's existing empty-option check fails open. Re-exports
normalizePollEchoText with a focused unit test across every emoji class plus a
message-tool integration test for the emoji-suffixed-option case.

* fix(imessage): make poll-echo emoji regex lint-safe

ClawSweeper/CI check-lint flagged no-misleading-character-class: combining
marks (VS16, U+20E3), ZWJ, and skin-tone modifiers are misleading inside a
single character class. Rewrite the emoji strip as an alternation using
property escapes (\p{Regional_Indicator}, \p{Emoji_Modifier}) plus standalone
atoms so the same normalization behavior passes lint. Behavior unchanged;
poll-echo unit + integration tests still green.

* fix(imessage): preserve poll option emoji identity

---------

Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-01 19:49:43 +01:00
Agustin Rivera
fe43343af0 fix(nvidia): use Nemotron Super 1M context (#98726)
* fix(nvidia): correct Nemotron Super context
2026-07-01 11:46:06 -07:00
Dallin Romney
24ce672e06 refactor(qa): use transport-native actions in flow scenarios (#97962)
* Add QA channel scenario driver contracts

* Route DM baseline through channel scenario driver

* Simplify channel behavior flow runtime helper

* test(qa): use native YAML for DM channel scenario

* test(qa): add conversation flow action

* test(qa): break channel scenario import cycle

* test(qa): fix channel scenario lint

* Unify QA channel scenario transport adapter

* Fix QA transport test type expectations

* refactor(qa): use native transport flow actions

* test(qa): derive direct reply session from transport
2026-07-01 11:39:06 -07:00
Ayaan Zaidi
477b27b6f8 refactor(telegram): reuse rich message extraction 2026-07-01 11:27:52 -07:00
Ayaan Zaidi
404e86f09a test(telegram): cover inbound rich message text 2026-07-01 11:27:52 -07:00
Ayaan Zaidi
8c7050423e fix(telegram): extract inbound rich message text 2026-07-01 11:27:52 -07:00
Ayaan Zaidi
53fe2e4bc3 refactor(auth): simplify codex login follow-up 2026-07-01 11:16:49 -07:00
Josh Lehman
26a756ee84 fix: preserve plugin login command precedence 2026-07-01 11:16:49 -07:00
Josh Lehman
bde0e4541e refactor: share codex login flow helpers 2026-07-01 11:16:49 -07:00
Eva
236626fffd Avoid object stringification in login surface checks 2026-07-01 11:16:49 -07:00
Eva
c188dbbbf7 Wire Codex login SDK entrypoint inventory 2026-07-01 11:16:49 -07:00