Commit Graph

70539 Commits

Author SHA1 Message Date
Peter Steinberger
593ac4ae0c feat(apps): rewind and fork a session from native chat bubbles (#110886)
* feat(apps): rewind and fork a session from native chat bubbles

* docs(apps): note lease-parity contract on message fork dispatch

* fix(apps): native i18n inventory sync and doc-comment style for bubble actions

* fix(apps): translate native bubble action strings across locales

* fix(apps): refresh generated iOS localization catalog after rebase
2026-07-18 17:52:03 -07:00
Peter Steinberger
47afe8f88f refactor(discord): split message process tests (#111066)
* refactor(discord): split message process tests

* test(discord): register split suite lifecycle

* test(discord): keep process harness internals private
2026-07-18 17:49:19 -07:00
qingminlong
fc30a6c67d fix(oc-path): reject oversized multibyte JSONC input (#104140)
* fix(oc-path): enforce JSONC byte limit for multibyte input

* fix(oc-path): surface JSONC size diagnostics in CLI

* fix(oc-path): classify oversized JSONC as parse error

* test(oc-path): cover JSONC byte cap boundaries

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:47:15 -07:00
Peter Steinberger
aad27e2629 test(worktrees): honor host umask in mode assertions (#111075) 2026-07-18 17:44:39 -07:00
Peter Steinberger
6c2973dee4 feat(ui): automatic session attention states in the sidebar (#111035)
* feat(ui): automatic session attention states in the sidebar (question, approval, failed run)

* test(ui): split attention presentation and read-marker cases under line budgets

* fix(ui): restore precise chat-pane test-support signatures
2026-07-18 17:43:59 -07:00
Yuval Dinodia
0a588fa795 fix(acp): /acp sessions exposes every gateway session to non-owner senders (#110745)
* fix(acp): scope /acp sessions listing for non-owner senders

/acp sessions listed every ACP session on the gateway for any sender
allowlisted via commands.allowFrom, exposing other senders' session
labels, agent ids, runtime state, and thread bindings. The handler now
returns only the current bound or requester session for non-owner
senders, while owner identity and operator.admin clients keep the full
gateway-wide listing, matching the documented contract.

Fixes #103055

* test(acp): cover empty and missing-session cases for /acp sessions scoping

* fix(acp): avoid non-owner session scans

* docs(acp): remove duplicated session scope text

* test(acp): cover internal session visibility

* fix(acp): require current ACP metadata

* test(acp): reject sessions target tokens

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 18:38:48 -06:00
Peter Steinberger
c745e7d66c fix(gateway): reject unsafe explicit approval IDs (#111055)
* fix(gateway): validate explicit approval ids

* fix(gateway): reject trailing approval controls

* test(gateway): cover embedded approval controls

* fix(gateway): reject empty explicit approval ids

* test(gateway): align approval projections with safe ids

* style(gateway): format approval id validation

* fix(gateway): reject approval url dot segments
2026-07-18 17:38:21 -07:00
Peter Steinberger
20677baf76 feat(android): copy or save rendered widgets as images from the chat transcript (#111030)
* feat(android): copy or save rendered widgets as images from the chat transcript

* chore(i18n): sync native app i18n inventory for widget export strings

* chore(i18n): regenerate native locale artifacts for widget export strings
2026-07-18 17:31:30 -07:00
Peter Steinberger
ec740e79a4 fix(agents): honor Anthropic retry-after cooldowns (#111072) 2026-07-18 17:28:04 -07:00
mushuiyu886
7abcd6c691 fix(skills): distinguish duplicate ClawHub search results by publisher (#110903)
* fix(skills): distinguish duplicate search results by publisher

* test(skills): cover owner-qualified search output

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:27:25 -07:00
Peter Steinberger
fdf44edf4d docs: document channel ingress guarantees (#111069) 2026-07-18 17:26:41 -07:00
Peter Steinberger
dcffb3f66f fix(ui): restore Control UI E2E coverage (#111036)
* fix(ui): restore control ui e2e coverage

* test(ui): align e2e coverage with thread labels

* test(ui): wait for fake talk channel readiness

* chore: keep release note in PR body
2026-07-18 17:26:26 -07:00
Peter Steinberger
e3ae52b792 feat(ui): microphone picker on the composer talk button (#111043)
* feat(ui): add composer microphone picker

* fix(ui): single check indicator in mic picker, matching house radio-menu pattern

* fix(ui): keep System default focusable during mic discovery; update composer contract test for picker caret
2026-07-18 17:25:55 -07:00
shaoohh
e669e97194 fix(acp): persist confirmed output from cancelled turns (#110300)
* fix(acp): persist cancelled partial replies

* fix(acp): persist delivered output for cancelled turns

Normalize terminal status at the ACP manager boundary and settle routed/direct delivery outcomes before persisting cancelled bound turns.

Co-authored-by: shaoohh <150606856+shaoohh@users.noreply.github.com>

* fix(acp): require confirmed cancelled-turn delivery

Persist cancelled-turn output only when the core dispatcher reports successful delivery. Keep canonical ACP history independent of outbound-only hook rewrites and prove backend cancellation with the real dispatcher.

Co-authored-by: shaoohh <150606856+shaoohh@users.noreply.github.com>

* test(acp): satisfy cancellation proof lint

Keep the pending-delivery race assertion behavior while avoiding a return value from the Promise executor.

Co-authored-by: shaoohh <150606856+shaoohh@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:24:42 -07:00
Peter Steinberger
45f6543c9a feat(macos): Quick Chat power features — voice dictation, paste-to-app, model/reasoning control (#110994)
* feat(macos): add Quick Chat power features

* docs(macos): document Quick Chat power features

* chore(i18n): refresh native locale artifacts for Quick Chat power features

* fix(macos): update DEBUG test helper sendProvider to the reasoning-threaded arity
2026-07-18 17:21:03 -07:00
Kris Wu
e5b2ca3c6b feat(config): add compaction.thinkingLevel to override thinking level during compaction (#98074)
* feat(config): add compaction.thinkingLevel to override thinking during compaction

* fix: make compaction.thinkingLevel override inherited session thinking

* fix: warn on compaction.thinkingLevel ignored by Codex native runtime

* feat(config): add compaction thinking override

Co-authored-by: wu.duozhen@xydigit.com <wu.duozhen@xydigit.com>

* test(agents): remove duplicate compaction harness

Co-authored-by: wu.duozhen@xydigit.com <wu.duozhen@xydigit.com>

* test(plugin-sdk): account for thinking level export

Co-authored-by: wu.duozhen@xydigit.com <wu.duozhen@xydigit.com>

* chore: keep release note in PR metadata

* chore: reconcile plugin SDK surface budgets

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:18:28 -07:00
mushuiyu886
9fe92cf5ce fix(nostr): profile imports no longer crash on invalid fields (#110684)
* fix(nostr): profile imports no longer crash on invalid fields

* test(nostr): define invalid profile import policy

* test(nostr): cover invalid imported URL types

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:18:23 -07:00
Peter Steinberger
b4187ced90 feat: add live-validated Zoom meeting guest plugin (#111048)
* feat(zoom-meetings): add browser guest transport

* fix(zoom-meetings): type reusable refresh result

* test(meeting-bot): bind reusable refresh callback

* chore(zoom-meetings): use existing plugin label

* chore(zoom-meetings): defer changelog to release

* test(zoom-meetings): cover node setup through public host
2026-07-18 17:17:26 -07:00
Yuval Dinodia
4e8f035912 fix(agents): keep run-mode subagent bundle MCP runtimes alive for approved follow-up turns (#101830)
Run-mode subagent cleanup retired the session bundle MCP runtime even when an
approved exec follow-up turn still held an active materialization lease, so the
follow-up turn failed with "bundle-mcp runtime disposed for session ...".

Retire run-mode subagent runtimes with preserveActiveLeases so retirement defers
while a lease is held, and complete the deferred retirement when the run's
materialized tool runtime releases its lease.
2026-07-18 17:15:25 -07:00
xingzhou
9b42782f76 fix(plugins): agent runs hang when tool-result middleware never settles (#110731)
* fix(plugins): prevent tool-result middleware from freezing runs

* test(plugins): cover middleware timeout policy

* test(plugins): provide hook context in timeout test

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:11:59 -07:00
Peter Steinberger
b550c2cf9a feat(ui): add realtime Talk camera controls (#111042) 2026-07-18 17:03:32 -07:00
Peter Steinberger
68ec50d643 fix(android): show conversation in screenshot fixture (#111000)
* fix(android): seed screenshot chat history

* fix(android): update screenshot chat readiness

* fix(android): use visible screenshot chat marker

* style(android): format screenshot script test

* fix(android): pin screenshot timezone

* fix(android): restore screenshot timezone
2026-07-18 17:02:29 -07:00
zengLingbiao
a68fdad8f5 fix(usage-bar): clear dead watcher reference after transient error (#109462)
* fix(usage-bar): clear dead watcher reference after transient error

When a usage bar template file watcher hits a transient error, the error
handler closes the FSWatcher but leaves entry.watcher pointing to the
closed instance.  loadUsageBarTemplate treats a truthy cached.watcher
as "still watching" and never re-reads the file, so a template that
became invalid stays stuck at the default forever.

Clear entry.watcher after closing so the next access that needs a
re-read can create a fresh watcher.

This matches the pattern from #109682 (config hot-reload watcher
recovery).

* fix(usage-bar): invalidate cached template on watcher error

Clear both entry.watcher and entry.template when the FSWatcher errors
so the next loadUsageBarTemplate call re-reads from disk and creates a
fresh watcher.  Previously only the watcher reference was cleared,
leaving a valid cached template that never observed future file edits.

This addresses the remaining valid-cache recovery gap from #109682.

* fix(usage-bar): fix no-promise-executor-return lint in test
2026-07-18 17:02:20 -07:00
zengLingbiao
0c221d2b4f fix(config): bound state-directory .env file reads with size limit (#109487)
* fix(config): bound state-directory .env file reads with size limit

Replace unbounded fs.readFileSync with readRegularFileSync capped at
1 MiB (MAX_STATE_DIR_DOTENV_BYTES) so an oversized .env file is
rejected before loading the entire file into memory.

Resolve symlinks via fs.realpathSync before the bounded read so
symlinked .env files keep working — matching the marketplace.ts
pattern for bounded manifest reads.

* fix(config): add diagnostic when oversized state .env is skipped

Log a warning when the state-directory .env file exceeds the 1 MiB
limit so operators know a configured file was skipped — matching the
pattern from #108200 (plugin catalog bounded read diagnostic).

* fix(config): bound global runtime dotenv file reads with size limit

Replace unbounded fs.readFileSync in readDotEnvFile with readRegularFileSync
capped at 1 MiB so CLI/Gateway startup dotenv loading also gets the bounded
read protection — not just the state-dir service-env path.

This addresses the P1 review finding that the original fix only capped the
helper-level reader while the shared readDotEnvFile used by
loadGlobalRuntimeDotEnvFiles was still unbounded.
2026-07-18 17:02:11 -07:00
NIO
86b5e279fb fix(voice-call): clamp continue poll RPCs to remaining deadline (#109053)
* fix(voice-call): clamp continue poll RPCs to remaining deadline

* test(voice-call): prove continue deadline bound

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:01:59 -07:00
zengLingbiao
c28284cb31 fix(config): bound external catalog file reads with size limit (#108200)
* fix(config): bound external catalog file reads with size limit

Replace unbounded fs.readFileSync with readRegularFileSync capped at
16 MiB (MAX_EXTERNAL_CATALOG_BYTES) to prevent memory exhaustion from
oversized or malicious plugin catalog files.

Resolve symlinks via fs.realpathSync before the bounded read so
symlinked catalog files keep working — matching the marketplace.ts
pattern for bounded manifest reads.

* fix(config): add diagnostic when oversized catalog is skipped

Log a warning when an external catalog file exceeds the 16 MiB limit
so operators know a configured file was skipped. Add regression test
verifying the oversized catalog is skipped and selection continues.

* fix(config): fix false-positive oversized catalog test

Replace the broken spy-on-object-literal mock with a real sparse file
that genuinely triggers readRegularFileSync rejection via stat.size.
The previous vi.spyOn({ readRegularFileSync }, ...) intercepted a
throwaway object, never the actual module import, so the test passed
regardless of whether the fix was applied or not.

Also fix the no-unused-expressions lint error on the env-primary
assertion that used a discarded ternary (? undefined : undefined)
instead of a proper expect assertion.
2026-07-18 17:01:54 -07:00
Peter Steinberger
a040f10e85 fix(gateway): reconcile config after watcher recovery (#111049)
Reload the current on-disk config once replacement native or polling watchers finish their initial scan, so edits made during recovery backoff are not lost.
2026-07-18 17:00:40 -07:00
Peter Steinberger
4b7d6fa3bf docs: align interactive client behavior (#111047) 2026-07-18 17:00:14 -07:00
Ted Li
10f5a7ac58 fix(groq): keep default Llama agent turns within TPM limit (#104904)
* fix(groq): recover oversized requests safely

* fix(groq): clear parallel tool aliases on fallback

* fix(groq): require provenance-aware host

* fix(groq): preserve configured request budgets

---------
authored-by: @MonkeyLeeT
Co-authored-by: Colin <colin@solvely.net>
2026-07-18 20:00:12 -04:00
Peter Steinberger
9a94beace7 fix(process): preserve descendant output under event-loop stalls (#111040)
* fix(process): drain buffered descendant output after exit

* test(process): cover deferred output release phase
2026-07-18 17:00:08 -07:00
Peter Steinberger
8853217ec7 fix(gateway): cancel run-bound approvals on abort and expose approval-park lifecycle (#110993)
* fix: harden approval abort lifecycle

* fix(gateway): recheck abort before committing detached exec authorization

* fix(gateway): recheck abort after inline exec authorization commit

* fix(gateway): propagate run-abort cancellation on the inline approval path

* fix(ci): refresh approval protocol bindings
2026-07-19 00:52:21 +01:00
lsr911
3d03b60da9 fix(litellm): guard loopback hostname auto-allow with isIP to prevent DNS SSRF bypass (#110693)
* fix(litellm): guard loopback hostname auto-allow with isIP to prevent DNS bypass

The isAutoAllowedLitellmHostname helper auto-enables private-network access
for loopback-style hosts. Before this fix, lowered.startsWith("127.")
matched DNS hostnames like 127.evil.com, letting remote endpoints bypass
the explicit allowPrivateNetwork opt-in — a SSRF risk.

Add isIP(host)===4 guard so only literal IPv4 loopback addresses qualify.
Same canonical pattern as extensions/slack/src/monitor/relay-source.ts:271
and the codex loopback fix.

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

* test(litellm): cover loopback endpoint policy

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-19 00:51:50 +01:00
cxbAsDev
8899940d5a fix(cron): support current and session: targets in initial delivery resolution (#99115)
* fix(cron): support current and session: targets in initial delivery resolution

resolveInitialCronDelivery only checked sessionTarget === 'isolated' for
default announce delivery. All other cron paths (delivery-plan.ts:106-114,
normalize.ts:680-684, jobs.ts:288-298) already treat 'isolated', 'current',
and 'session:' as equivalent. This gap meant cron jobs created with
--session-target current or --session-target session:... would not get
default announce delivery at creation time.

Real behavior proof:
  Input:  sessionTarget='current', payload.kind='agentTurn'
  OLD:    undefined  <- missing default announce delivery
  NEW:    {mode:'announce'}  <- consistent with other cron code paths

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

* test(cron): add typed initial delivery resolution tests for all session targets

* test(cron): document direct-service delivery contract and cover service callers

* refactor(cron): centralize detached-delivery-target predicate into shared helper

Extract isDetachedDeliveryTarget(sessionTarget, payloadKind) in normalize.ts
and use it from all three callers:

- normalizeCronJobInput (write-time default, normalize.ts)
- resolveCronDeliveryPlan (read-time default, delivery-plan.ts)
- resolveInitialCronDelivery (service-bypass default, initial-delivery.ts)

This removes the third manually synchronized copy that the original PR
added, addressing ClawSweeper P1 finding.

* fix(cron): align initial delivery targets

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* test(cron): consolidate initial delivery coverage

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* test(cron): keep delivery matrix type-safe

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* chore: keep release note in PR metadata

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-19 00:51:05 +01:00
Jason (Json)
7c070d6df6 feat: allow standalone MCP Apps to use bound tools and resources (#110515)
* Gateway: enable ticketed MCP App bridge

* Gateway: make MCP App operation switch exhaustive

* refactor(gateway): drop no-op MCP App route change

* fix(gateway): enforce standalone MCP App tool authority

* docs(gateway): clarify standalone MCP App ticket authority

* fix(gateway): require standalone MCP App initialization

* refactor(gateway): keep standalone route load explicit
2026-07-18 17:50:37 -06:00
Omar Shahine
8b720729d2 fix(imessage): keep fast progress out of chat (#110052)
* fix(imessage): keep fast progress out of chat

* test(imessage): require fast progress callback

---------

Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
2026-07-18 16:45:10 -07:00
Peter Steinberger
56eef79989 fix(channels): recover dead-lettered inbound events (#111029)
* feat(channels): add ingress dead-letter recovery

* fix(channels): preserve dead-letter compatibility

* docs: refresh CLI map for channel dead letters
2026-07-19 00:44:23 +01:00
Peter Steinberger
65915bcd26 fix(ui): openknot/dash dark theme AA contrast for text-bearing fills (#111003) 2026-07-19 00:42:37 +01:00
Peter Steinberger
7562b79465 refactor(channels): share durable ingress monitor (#111017)
* refactor(channels): share durable ingress monitor

* fix(channels): harden ingress monitor shutdown

* docs: refresh SDK documentation map
2026-07-19 00:42:08 +01:00
Alexzhu
e5e93e8169 fix(whatsapp): evaluate mention patterns when other members are @-mentioned (#110412)
* fix(whatsapp): evaluate mention patterns when other members are @-mentioned

isBotMentionedFromTargets returned false as soon as a group message
carried native @-mentions that did not include the bot, so the
configured mentionPatterns were never evaluated and a message like
'marlow, look at @SomeoneElse's message' was silently dropped by the
requireMention gate (#109488).

Fall through to the configured text mentionPatterns when the native
@-mention JIDs do not include the bot. The loose self-number digit
fallback stays suppressed in that shape: an @-tag of another member
injects that member's number into the body, so substring digit
matching is unreliable there.

Fixes #109488

* refactor(whatsapp): unify mention pattern gating

---------

Co-authored-by: Marcus Castro <mcaxtr@openclaw.ai>
2026-07-18 20:40:34 -03:00
Peter Steinberger
c1e714e3df refactor(agents): shared spawn orchestration pipeline behind backend adapters (#111007)
* refactor(agents): share spawn orchestration pipeline

* fix(agents): preserve ACP spawn failure contract

* fix(agents): progress hooks keep per-backend session-key semantics

* fix(agents): ACP registration keeps the resolved requester agent id

* chore(agents): drop orphaned exports surfaced by the spawn dedup
2026-07-19 00:40:22 +01:00
Peter Steinberger
ec998a0f3f feat(canvas): export widgets as PNG — copy or download from the card menu (#110992)
* feat(canvas): export widgets as PNG — copy to clipboard or download from the card menu

* fix(ui): widget-export lint, knip, and lines-budget cleanup
2026-07-19 00:39:59 +01:00
Peter Steinberger
941ed4fd4a fix(memory-wiki): preserve unavailable source pages (#111034)
Preserve imported unsafe-local wiki pages and human annotations while configured source scopes are temporarily unreadable.
2026-07-19 00:39:23 +01:00
mushuiyu886
d411559dfb fix(acp): reject malformed session list cursors (#107895)
* fix(acp): reject malformed session list cursors

* fix(session-catalog): validate pagination cursors exactly

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

* refactor(session-catalog): align search normalization owner

* refactor(session-catalog): keep parsing helpers private

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-19 00:38:02 +01:00
tzy-17
828bcd8231 fix(scripts): bound GHSA patch GitHub lookups (#110756)
* fix(scripts): bound GHSA patch subprocesses

Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com>

* fix(scripts): satisfy GHSA runner control-flow lint

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-19 00:37:06 +01:00
Peter Steinberger
ed458f14dc test(scripts): wait for Knip pid file content (#111001) 2026-07-19 00:36:15 +01:00
Peter Steinberger
9275837f41 docs: explain managed Gateway heap sizing (#111027) 2026-07-19 00:36:03 +01:00
Peter Steinberger
f7024690ac refactor(gateway): split chat handlers by workflow (#111022) 2026-07-19 00:35:42 +01:00
Peter Steinberger
4362e1a4fe fix(agents): recognize nested message delivery receipts (#111012) 2026-07-19 00:33:33 +01:00
Peter Steinberger
dc8f90197e fix(tui): guarantee exit after drained teardown (#111015) 2026-07-19 00:33:16 +01:00
Jason (Json)
0483001ef6 fix(scripts): dedupe release checklist declaration (#111024) 2026-07-18 17:21:15 -06:00