62748 Commits

Author SHA1 Message Date
SunnyShu
1289abddcb fix(memory-wiki): gracefully handle unparsable YAML frontmatter in vault scans (#96125) (#97177)
* [AI] fix(memory-wiki): gracefully handle unparsable YAML frontmatter in vault scans (#96125)

toWikiPageSummary now catches YAML parse errors during vault-wide scans
(compile/lint/query/status) and returns a degraded WikiPageSummary with
frontmatterError set instead of letting the error propagate through
readPageSummaries -> compileMemoryWikiVault, which previously caused one
bad page to crash the entire vault.

Edit paths (apply, chatgpt-import) still throw on bad frontmatter to
prevent silent metadata loss on write.

- markdown.ts: add frontmatterError field to WikiPageSummary, extract
  splitWikiFrontmatterBlock, catch YAML.parse in toWikiPageSummary
- lint.ts: add invalid-frontmatter lint code, skip frontmatter-derived
  checks when frontmatterError is present
- markdown.test.ts: test degraded parse preserves body, empty frontmatter
- lint.test.ts: test invalid-frontmatter lint on broken page, healthy
  page unaffected

Related to #96125

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

* fix(memory-wiki): isolate invalid frontmatter scans

* fix(memory-wiki): keep malformed lint reports fail-closed

* fix(memory-wiki): reject non-mapping frontmatter

* fix(memory-wiki): validate generated index targets

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 17:21:19 -07:00
Yuval Dinodia
82871fe21b fix(doctor): merge colliding model-ref map keys instead of dropping (#96544)
* fix(doctor): merge colliding model-ref map keys instead of dropping

When two retired model-ref keys in a models map upgrade to the same
current ref, rewriteModelRefMapKeys dropped the second entry silently
and still logged a success line, so doctor --fix lost one entry's
params/streaming/alias/agentRuntime tuning while falsely reporting it
as upgraded.

Mirror the sibling provider-models-array merge path (#90047): deep-merge
the colliding entries preserving disjoint fields, keep the existing
value deterministically on a true field conflict, and push a merge or
collision change-log line instead of dropping.

* fix(doctor): block prototype keys when merging colliding model-ref map entries

mergeModelRefMapEntries copied arbitrary incoming config fields into a
plain object, so a colliding model entry carrying a __proto__ field could
mutate the merged entry prototype during legacy config migration. Skip
isBlockedObjectKey fields before assigning or recursing, matching the
shared config merge guard. Disjoint-field merging is unchanged.

* fix(doctor): preserve canonical model migration values

* fix(doctor): filter blocked keys on both merge sides and report retired source key

* fix(doctor): preserve colliding retired model settings

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 17:20:49 -07:00
ZOOWH
5a73361ed2 fix(plugins): apply output text transforms to toolcall_delta and toolcall_end events (#97769)
* fix(plugins): apply output text transforms to toolcall_delta and toolcall_end events

toolcall_delta and toolcall_end events bypassed the output replacement
pipeline, leaking masked tokens (e.g. PII placeholders) into tool call
arguments and external systems.

Closes #97761

* fix(plugins): transform nested tool call arguments in output replacements

Add recursive transformToolCallArgumentText to handle strings, arrays,
and nested objects in tool call arguments, not just the name field.

* fix(plugins): keep tool names unchanged and cover result path

- Remove toolCall.name transformation to prevent breaking tool routing
- Add arguments transform to stream.result()/done.message via
  transformContentText for tool-call content blocks

* fix(plugins): narrow argument transform to toolCall content blocks only

Only transform arguments on content blocks with type=toolCall to avoid
touching non-tool-call blocks that happen to have an arguments field.

* test(plugins): assert stream.result() tool-call content block is transformed

* test(plugins): fix result-path fixture to actually contain toolCall block

The previous fixture used makeAssistantMessage('final') which produces
a plain text content block, not a toolCall block. The stream.result()
assertion was vacuously passing.

* style(plugins): fix type cast in result-path test assertion

* fix(agents): preserve tool argument transforms after repair

* refactor(agents): keep tool transform boundary narrow

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 17:15:01 -07:00
weiqinl
5e572dcf78 fix(slack): prefer current thread session for inherited outbound replies (#97168)
* fix(slack): prefer current thread session for inherited outbound replies to avoid delivery-mirror session sprawl

* fix(slack): require explicit replyToIsExplicit===false for current-session precedence

* fix(slack): canonicalize inherited thread replies

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 16:38:34 -07:00
Vincent Koc
a841c27882 ci(release): stabilize anthropic live smoke selection
(cherry picked from commit e085fa1a3f)
2026-06-30 15:54:12 -07:00
Vincent Koc
cb00045afc test(qa): make memory channel scenario wait for final answer
(cherry picked from commit cf64cf788e)
2026-06-30 15:54:12 -07:00
Vincent Koc
3e2646a786 fix(release): use workspace host deps in release lockfile
(cherry picked from commit d377c0f910)
2026-06-30 15:54:12 -07:00
Vincent Koc
51e0997c2b test(qa): accept async image fixture coverage
(cherry picked from commit 9b703d0cd6)
2026-06-30 15:54:11 -07:00
Vincent Koc
31f58cd9de test(codex): harden run-attempt temp cleanup
(cherry picked from commit 5f4fa97835)
2026-06-30 15:54:11 -07:00
Vincent Koc
e03f12ef3b ci(release): restore plugin npm token env
(cherry picked from commit 9c154ffa46)
2026-06-30 15:54:11 -07:00
Vincent Koc
ccb515fa69 ci(release): restore trusted plugin npm publishing
(cherry picked from commit 866fc34e30)
2026-06-30 15:54:11 -07:00
Vincent Koc
4355e719b8 ci(release): allow token plugin npm recovery
(cherry picked from commit faa99eeb63)
2026-06-30 15:54:11 -07:00
Vincent Koc
2499b64f9b fix(parallels): stabilize Windows beta smoke transport
(cherry picked from commit 0a4d0daa8c)
2026-06-30 15:54:11 -07:00
Vincent Koc
6528912e90 fix(telegram): recover stalled ingress spool claims
Backport of #97118 to release/2026.6.11.

(cherry picked from commit 8346e87808)
2026-06-30 15:54:11 -07:00
Agustin Rivera
3811001d27 fix(exec): bind Windows allowlist execution path (#98260)
* fix(exec): bind windows allowlist execution path

* fix(exec): add windows shadow execution proof

* fix(exec): preserve wildcard allowlist behavior

* fix(exec): correct blocked plan test fixture
2026-06-30 14:33:08 -07:00
Dallin Romney
44ec7580e2 fix(cli): stop pairing list crashing with empty channel enum (#98142)
When no chat DM pairing channels are configured, `openclaw pairing list`
(no channel argument) threw `Channel required ... (expected one of: )`
with an empty enum that reads like a bug. Users who hit this are usually
trying to approve a TUI/device or scope-upgrade request, which lives under
`openclaw devices`, not `openclaw pairing` (which only handles chat DM
pairing).

- Guard the channel hint in help text and errors so an empty channel list
  no longer renders a bare `()` / `(expected one of: )`.
- When no pairing channels exist, redirect to `openclaw devices list` /
  `openclaw devices approve` instead of failing opaquely.

AI-assisted (Claude Code).
2026-06-30 14:15:19 -07:00
Agustin Rivera
b885c81479 fix(mcp): require owner for Claude permission replies (#98256)
* fix(mcp): require owner for Claude permission replies

* fix(mcp): prove owner-gated permission replies
2026-06-30 13:58:02 -07:00
Gio Della-Libera
9f07b21e62 Doctor: expose auth profile findings (#97125)
Expose `core/doctor/auth-profiles` as a default-disabled structured Doctor lint check.

This maps the existing auth-profile health diagnostics into structured findings while preserving legacy Doctor repair behavior. The check remains opt-in through `--only core/doctor/auth-profiles` or `--all`; default `doctor --lint` behavior is unchanged.

Validation:
- focused auth-profile/hints/contribution Vitest passed
- changed-file oxfmt and oxlint passed
- core tsgo passed
- git diff --check passed
- exact-head hosted CI/Testbox gates passed

Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
2026-06-30 13:28:26 -07:00
Alix-007
640258d7b3 fix(usage): reject inverted startDate-endDate range in usage.cost and sessions.usage (#94096)
* fix(usage): reject inverted startDate-endDate range

* chore: retrigger CI for real behavior proof check

* refactor(usage): resolve validated date ranges once

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 12:55:43 -07:00
Alix-007
076da567f4 fix(imessage): recognize MiniMax mm: reasoning tags in reflection guard (completes #93767) (#93820)
* fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard

The iMessage reflection guard's THINKING_TAG_RE only matched bare
`<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning
tags (and Anthropic's `antml:` prefix) were not recognized as reflected
assistant content. When such reasoning leaked back inbound, the guard
treated it as a normal user message instead of dropping it, allowing
recursive echo amplification.

Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on
the think/thought alternatives, mirroring the shared reasoning-tag
contract in src/shared/text/reasoning-tags.ts (PR #93767). This is the
remaining channel-monitor complement of #93767 for the iMessage path;
the optional prefix is a pure recognition enhancement with no change to
the bare-tag, code-region exemption, or other reflection patterns.

Verified by driving the real detectReflectedContent export:
  <mm:think>secret</mm:think>visible  -> isReflection=true (was false)
  <think>...</think>       -> isReflection=true
  <think>secret</think>                -> isReflection=true (no regression)
  "thinking about minimax algorithms"  -> isReflection=false (no false-positive)
  `<mm:think>x</mm:think>` in code     -> isReflection=false (code exemption kept)

* chore: retrigger CI for real behavior proof check

* refactor(imessage): tighten reflection guard coverage

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 12:41:42 -07:00
Patrick Erichsen
5a89484eb3 fix: preserve legacy ClawHub plugin family (#98249) 2026-06-30 12:20:08 -07:00
NIO
765d05c2e4 fix(moonshot): bound video description JSON response reads (#96502)
* fix(moonshot): bound video description JSON response reads

The Moonshot video description endpoint used an unbounded await res.json()
to parse the media understanding response. Route through
readProviderJsonResponse (16 MiB cap) to match the bound already in
place for other media understanding providers (xai, openrouter).

AI-assisted.

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

* test(moonshot): add bounds and malformed-JSON coverage for video description

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 12:12:46 -07:00
Vincent Koc
66e676d29b chore(release): close out 2026.6.11 on main 2026-06-30 11:31:08 -07:00
Patrick Erichsen
5e0652f284 fix: bump ClawHub publish CLI pin (#98233) 2026-06-30 11:26:51 -07:00
Jason (Json)
786abe78df Streamline OpenClaw onboarding (#98218)
* feat: streamline onboarding setup flow

* fix: harden onboarding preflight installs

* test: isolate gateway preflight safety env

* fix: keep local gateway probes on loopback

* fix: honor onboarding node manager installs

* docs: align setup onboarding reference

* fix: harden bare gateway probe fallback

* fix: honor env gateway auth in bare TUI probe

* test: isolate wizard TUI hatch mocks
2026-06-30 11:22:26 -07:00
Ayaan Zaidi
3f147ae5ca test(provider-transport-fetch): cover split large SSE event 2026-06-30 11:08:38 -07:00
Peter Lindsey
81d60ca30d fix(provider-transport-fetch): raise SSE sanitize buffer cap to 16 MiB
The 64 KiB inter-event SSE sanitize buffer added in #96989 rejects a single
legitimate event larger than 64 KiB — e.g. a large gpt-5.5 reasoning summary on
the openai-chatgpt-responses API — throwing "SSE response exceeded max buffer
size (65536 bytes) without event boundary" and failing the whole request. The
default ChatGPT-subscription gpt-5.5 path is unusable (present in v2026.6.11-beta.1).

Decouple the two bounds: keep the non-OK error-body cap tight at 64 KiB
(SSE_NONOK_BODY_MAX_BYTES), and raise the inter-event sanitize buffer to the same
16 MiB ceiling as the JSON-synthesis path. The guard still trips on a genuinely
boundary-less (hostile/broken) stream, just not on a real large event.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 11:08:38 -07:00
Vincent Koc
c16bb8725a fix(channels): keep text previews UTF-16 safe 2026-06-30 11:04:32 -07:00
Ayaan Zaidi
68c533cfb3 fix(config): preserve unreadable write rejection for exported writes 2026-06-30 10:52:44 -07:00
Ayaan Zaidi
c1605064d0 test(config): distill unreadable config write guard cases 2026-06-30 10:52:44 -07:00
yetval
14198836b2 fix(config): fail closed when config is unreadable before a full-file write
A present-but-unreadable openclaw.json (for example EACCES after a sudo
command leaves it root-owned) returns an empty best-effort fallback
snapshot. A later full-file write (openclaw doctor, including the update
doctor pass) then serialized a skeletal config over the still-rich file,
dropping gateway.mode and bricking gateway startup.

The fallback base has no raw bytes and an empty resolved config, so the
existing size-drop and gateway-mode-removed guards never fired, and the
update path passes allowConfigSizeDrop=true.

Record the read failure on the snapshot (readError) and treat an
unreadable base as an always-blocking write reason
(unreadable-config-before-write) that allowConfigSizeDrop does not bypass.
The allowDestructiveWrite escape hatch and the rejected-artifact path are
preserved, so explicit recovery still works and the blocked payload is
saved to openclaw.json.rejected.<timestamp>.

Refs #78493.
2026-06-30 10:52:44 -07:00
lsr911
7d98ad2a92 fix(signal): guard containerRestRequest JSON.parse against malformed responses (#98073)
* fix(signal): guard containerRestRequest JSON.parse against malformed responses

Wrap JSON.parse(text) in containerRestRequest with try/catch to prevent a malformed Signal REST container response from throwing an unhandled SyntaxError.

On parse failure, throw a descriptive Error. The success body is already bounded by readProviderTextResponse (16 MiB cap, D1 protection).

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

* fix(signal): add real HTTP server proof for malformed JSON guard

Starts a local node:http server returning malformed JSON, then calls
containerRestRequest against it.  This exercises the actual changed
try/catch code path through the real fetch stack (no mock override).

Proof output:
  PASS  malformed JSON: throws Error :: type=Error
  PASS  malformed JSON: message describes malformed JSON
  PASS  malformed JSON: NOT raw SyntaxError

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

* test(signal): remove committed proof script

---------

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-30 10:50:59 -07:00
Ayaan Zaidi
8829dc4aae fix(gateway): reject deleted-agent exec followups before dedupe 2026-06-30 10:49:23 -07:00
Ayaan Zaidi
35d06e6356 refactor(gateway): distill deleted-agent RPC guard 2026-06-30 10:49:23 -07:00
Pick-cat
afe137d839 fix(gateway): reject deleted-agent sessions before dedupe and attachment offload 2026-06-30 10:49:23 -07:00
Pick-cat
379756fc92 fix(gateway): guard deleted-agent sessions before agent reset commands 2026-06-30 10:49:23 -07:00
Pick-cat
8cf599cb93 test(gateway): model ops as configured in voice-wake agent fixture 2026-06-30 10:49:23 -07:00
Pick-cat
60f30be526 test(gateway): add live agent RPC deleted-agent integration proof 2026-06-30 10:49:23 -07:00
Pick-cat
71e6505fb1 fix(gateway): reject agent RPC runs for deleted-agent sessions
Related #65524
2026-06-30 10:49:23 -07:00
Ayaan Zaidi
86bdfec6b7 refactor(telegram): simplify album prompt selection 2026-06-30 10:45:44 -07:00
NianJiuZst
44f3c3e43a test(telegram): satisfy album context lint 2026-06-30 10:45:44 -07:00
NianJiuZst
bba63d3fe0 fix(telegram): omit skipped album context 2026-06-30 10:45:44 -07:00
NianJiuZst
9aec0f089b fix(telegram): hydrate album sibling media context 2026-06-30 10:45:44 -07:00
openclaw-release-bot
8d1a31c9a4 chore(release): update appcast for 2026.6.11 2026-06-30 17:44:59 +00:00
Ayaan Zaidi
f078962d17 fix(feishu): require explicit reply send target 2026-06-30 10:40:48 -07:00
xydigit-zt
62fa674a39 fix(feishu): route non-thread p2p DM replies to user:<open_id>
Add sendTarget param to createFeishuReplyDispatcher that overrides
the to: field for visible sends. Fix streaming card delivery target
by stripping routing prefixes (user:, chat:) before the Feishu
streaming API call. Route streaming card reply metadata through
suppressed sendReplyToMessageId.

Closes #83730
2026-06-30 10:40:48 -07:00
Masato Hoshino
5c4e478df4 fix(slack): expose sender bot status in context (#97822)
* fix(slack): expose sender bot status in context

* fix(slack): expose sender bot status in context

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-30 10:29:42 -07:00
Masato Hoshino
37341a7032 fix(googlechat): expose sender bot status in context (#97825)
* fix(googlechat): expose sender bot status in context

* fix(googlechat): expose sender bot status in context

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-30 10:28:47 -07:00
Masato Hoshino
984f5a51ca fix(discord): expose sender bot status in context (#97824)
* fix(discord): expose sender bot status in context

* fix(discord): expose sender bot status in context

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-30 10:27:53 -07:00
liuhao1024
c896718acb fix(memory-wiki): strip fenced code blocks before wikilink extraction (fixes #97945) (AI-assisted) (#97954)
* fix(memory-wiki): strip fenced code blocks before wikilink extraction

extractWikiLinks runs OBSIDIAN_LINK_PATTERN against full markdown
including fenced code blocks and inline code spans, causing false
positive 'Broken wikilink target' warnings for bash [[...]] test
syntax and Scala generics inside code blocks.

Strip fenced code blocks and inline code before running the wikilink
regex to eliminate code-block false positives while preserving real
wikilinks in prose.

Fixes #97945

* fix(memory-wiki): strip fenced code blocks before wikilink extraction

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-30 10:26:55 -07:00