Commit Graph

66940 Commits

Author SHA1 Message Date
Peter Steinberger
f698703934 fix(sandbox): reap orphaned container processes (#103441)
Co-authored-by: hobo <hobo.l@binance.com>
Co-authored-by: aaajiao <aaajiao@gmail.com>
2026-07-10 07:09:57 +01:00
Peter Steinberger
7f5dce8bbf fix(xai): discover TTS voices dynamically (#103446) 2026-07-10 07:05:45 +01:00
chengzhichao-xydt
5b916cb319 fix(voice-call): add timeout to guardedJsonApiRequest (#102884)
* fix(voice-call): add timeout to guardedJsonApiRequest

* fix(voice-call): bound provider JSON requests

---------

Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 07:05:24 +01:00
Peter Steinberger
54009c15bb improve(qa): verify native Slack chart delivery (#103337)
* test(qa): prove Slack native chart delivery

* test(qa): exercise Slack chart verifier through scenario

* fix(build): bound private QA SDK declarations separately

* fix(qa): normalize Slack chart history whitespace
2026-07-10 06:58:33 +01:00
Ayaan Zaidi
08b6996cd5 fix(mcp): redact secrets from /mcp show in group chats (#103396)
* fix(mcp): redact secrets in /mcp show replies

Prevent owner /mcp show from dumping raw headers/env credentials into
group chats. Mark MCP env values sensitive, restore redaction sentinels
on set so show→set cannot overwrite real secrets.

Fixes #103053

* test(mcp): e2e redaction of /mcp show secrets on live gateway

Spin up an ephemeral gateway process, chat.send /mcp show with live
credential-bearing config, and prove secrets never leave the reply path.
Also prove show→set sentinel restore on disk via chat and CLI.
2026-07-10 11:28:23 +05:30
pick-cat
7eb163d905 fix(synology-chat): strip internal tool-trace banners from outbound text (#102925)
* fix(synology-chat): strip internal tool-trace banners from outbound text

* fix(synology-chat): satisfy eslint curly rule

* fix(synology-chat): add sanitizeText to outbound type contract

* fix(synology-chat): use canonical outbound sanitizer type

---------

Co-authored-by: Pick-cat <266665499+Pick-cat@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:56:20 +01:00
Peter Steinberger
7bb3df9b89 feat(webchat): lobster pet sentience - gaze, petting, honest reactions, vigil (#103344)
The pet watches your pointer between acts (facing follows the cursor,
throttled, reduced-motion inert). Press-and-hold now pets it - content
closed eyes and a floating heart - while a quick tap stays a poke.
Run endings are honest: resolveLobsterRunOutcome picks the most recently
ended session (endedAt first, activity stamps as fallback) so successes
cheer, failures earn a sympathetic droop with sagging antennae, and
user-aborted runs just get an acknowledging startle. Runs longer than
ten minutes summon the pet into a settled vigil pose that pauses all
acts until the run ends.
2026-07-10 06:54:29 +01:00
tzy-17
2f7e2aee15 fix(queue): prevent applyQueueDropPolicy from selecting in-flight items as overflow victims (#103284)
* fix(queue): prevent applyQueueDropPolicy from selecting in-flight items as overflow victims

When a burst of inbound messages hits the followup queue cap while the
head item is mid-delivery, applyQueueDropPolicy can select that same
in-flight item as an overflow victim. With the default
dropPolicy: "summarize", the in-flight item ends up recorded in the
overflow summary as dropped even though it is still being delivered,
producing a contradictory record where the same message is both
answered and reported as unanswered-due-to-overflow.

The fix introduces an optional `inFlight` Set parameter to
applyQueueDropPolicy and drainNextQueueItem. The followup queue state
now owns a shared inFlight set that is:
- Populated by drainNextQueueItem during the await run(next) window
- Populated by the collect-merge drain path for activeGroupItems
- Passed to applyQueueDropPolicy in enqueueFollowupRun

The drop policy now computes an effective queue length that excludes
in-flight items, and skips them when selecting splice victims.

Fixes #103246

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

* fix(queue): align pending depth with active deliveries

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:53:29 +01:00
Peter Steinberger
477b2860d5 feat(macos): add tabs to the dashboard link browser sidebar (#103438)
Each inline link opens in its own tab (exact-URL dedupe); sidebar
target=_blank links open new tabs. Tab strip on top with click to
activate, close buttons, middle-click close, pointer-drag reorder, and
a per-tab context menu (Open in Default Browser, Copy Link, Reload,
Close Tab, Close Other Tabs). Navigation controls sit below the tabs
and follow the active tab. Closing the last tab collapses the sidebar
with no lingering webviews or history.
2026-07-10 06:51:49 +01:00
Peter Steinberger
120385a88a fix(media-core): detect encoded URL extensions (#103410)
Co-authored-by: VectorPeak <73048950+VectorPeak@users.noreply.github.com>
2026-07-10 06:50:01 +01:00
krissding
1a0dc9b83f fix(opencode-go): remove deprecated mimo-v2-omni and mimo-v2-pro model aliases (#103329)
* fix(opencode-go): remove deprecated mimo-v2-omni and mimo-v2-pro model aliases

These deprecated aliases reject agent requests from the OpenCode Go gateway.
Remove them from the provider catalog and clean up all references in probe
skip lists, CI workflows, and tests.

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

* fix(opencode-go): complete deprecated MiMo cleanup

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:49:09 +01:00
Peter Steinberger
461772868d fix(computer): prevent stale, replayed, and post-cancel desktop actions (#103422)
* fix(ai): preserve streamed tool-call identity

* fix(computer): bind actions to current tool authority

* fix(macos): serialize computer control lifecycle

* docs(computer): document hardened control contract

* chore: follow release-owned changelog policy

* test(agents): cover node list cancellation
2026-07-10 06:47:56 +01:00
Pavan Kumar Gondhi
c70f3d0dae fix: block unspecified trusted DNS targets (#103075) 2026-07-10 11:16:26 +05:30
Peter Steinberger
e1c144a003 fix(xai): preserve Grok thinking through the x-ai alias (#103340)
* fix(xai): honor provider alias runtime policy

* fix(xai): preserve alias billed tool defaults
2026-07-10 06:45:10 +01:00
Peter Steinberger
9d4fb60e90 fix: harden exec auto-review approvals (#103430) 2026-07-10 06:44:03 +01:00
sunlit-deng
8711f6108a fix(config): cap legacy toolsBySender deprecation warning cache with shared dedupe helper (#101696)
* fix(config): use shared dedupe cache for legacy toolsBySender warnings

Replace unbounded Set with createDedupeCache({ ttlMs: 0, maxSize: 4096 })
from src/infra/dedupe.ts. The shared helper provides check() with
touch-on-read and max-size pruning — no custom LRU stack needed.
Tests verify eviction and hot-key retention through the public
resolveToolsBySender API without a testing-only cache export.

* test(config): tighten legacy warning cache proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:43:17 +01:00
lsr911
2cd831a0e3 fix(agents): use Buffer.byteLength for bash output rolling buffer accounting (#103272)
* fix(agents): use Buffer.byteLength for bash output rolling buffer accounting

The outputBytes variable tracks the rolling output buffer size for
bash command execution, but it used string .length (UTF-16 code units)
instead of Buffer.byteLength (UTF-8 bytes). When command output
contains multi-byte UTF-8 characters (emoji, CJK, etc.), the .length
undercount causes the rolling buffer to exceed maxOutputBytes.

Replace .length with Buffer.byteLength() at both increment and
decrement sites to correctly track byte-level buffer size.

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

* refactor(agents): unify bash output accumulation

* refactor(agents): unify bash output accumulation

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:41:50 +01:00
LZY3538
939d0ef45d fix(ai): cache and case-insensitively match Azure deployment map (#103005)
* fix(ai): cache and case-insensitively match Azure deployment map

resolveAzureDeploymentNameFromMap re-parsed the deployment-map string into
a new Map on every call (a hot path: streams and lifecycle hooks) and
looked model ids up case-sensitively. A request for `GPT-4o` against a
`gpt-4o=deployment-gpt-4o` map therefore fell back to the raw model id and
404'd on Azure ("deployment not found").

Cache the parsed lookup map keyed by the raw deployment-map string (bounded
so memory stays flat) and normalize keys to lowercase so lookups are
case-insensitive. Deployment names (the values) stay verbatim because Azure
requires the exact deployment name, and the fallback still returns the
original-cased model id.

Fixes #102936

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix(ai): prefer exact-case match, case-insensitive only as fallback

Addresses review: lowercasing every key regressed configs whose deployment
map distinguishes keys by case (e.g. `GPT-4o=prod-a,gpt-4o=prod-b`), where an
exact `GPT-4o` request previously resolved to `prod-a` but would now collapse
to the last lowercased entry.

Cache an exact-case lookup alongside the lowercased one and resolve exact
first, using the case-insensitive map only as a fallback. Every previously
working exact mapping is preserved; the case-insensitive path only rescues
ids that would otherwise 404. Adds a regression test for exact-case
precedence.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* test(ai): prove Azure deployment map resolves on the real provider path

Adds an integration test that drives the real streamSimpleAzureOpenAIResponses
path against a loopback server (via the AI transport host fetch) and asserts the
deployment name resolved from AZURE_OPENAI_DEPLOYMENT_NAME_MAP is what lands in
the outgoing request `model` field — the value Azure routes on, and the source
of the reported 404 when it fell back to a mixed-case model id.

Covers the mixed-case fix (GPT-4o -> deployment-gpt-4o on the wire) and the
exact-case no-regression case (GPT-4o -> prod-a).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* test(ai): use block-body promise executors to satisfy oxlint

no-promise-executor-return flagged the arrow executors around server
listen/close; use statement bodies so nothing is returned from the executor.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor(ai): simplify Azure deployment lookup

* refactor(ai): simplify Azure deployment lookup

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:38:39 +01:00
maweibin
f15f2d1092 fix(ui): normalize Unicode line/paragraph separators in markdown rendering (#102169)
* fix(ui): normalize Unicode line/paragraph separators in markdown

LLM outputs can contain U+2028/U+2029 chars that split() ignores,
causing content to render as one unbroken line in the chat UI.

Define LINE_SEP_RE using String.fromCodePoint() and apply it
alongside existing \r\n normalization in all five markdown
processing entry points. Mirrors normalizeDisplayLineBreaks()
in exec-approval-command-display.

* fix(ui): normalize markdown line breaks once

---------

Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:38:07 +01:00
Peter Steinberger
ffa3d9a336 fix(slack): restore folded IDs at Web API boundaries (#103214)
* fix(slack): preserve delivery target case

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

* fix(slack): restore API IDs at Web API boundaries

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

---------

Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com>
2026-07-10 06:37:57 +01:00
Peter Steinberger
fa3eb673cd feat(slack): accept spoken mentions in audio clips (#103416)
* feat(slack): support spoken audio mentions

* chore: keep release notes in PR body
2026-07-09 22:33:26 -07:00
Peter Steinberger
e7b652798f fix(xai): remove synthetic batch STT model (#103419) 2026-07-10 06:32:45 +01:00
neilofneils404
dc783bbde8 fix(restart): ignore missing lsof during startup (#76364)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:31:50 +01:00
Peter Steinberger
c7909ead5c fix(update): prevent build workers surviving timeouts (#103406)
* fix(update): terminate timed-out process trees

* chore: leave changelog to release generation
2026-07-10 06:30:07 +01:00
Peter Steinberger
a39a3ee1d0 fix(ui): reserve the pointer cursor for real links across the Control UI (#103411) 2026-07-10 06:29:19 +01:00
saju01
f0534c5b71 fix(github-copilot): honor live prompt token limits (#103275)
* fix(github-copilot): honor live prompt token limits

* fix(github-copilot): align prompt token budgets

* fix(github-copilot): align prompt token budgets

---------

Co-authored-by: saju01 <saju@coderedcorp.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-10 06:27:14 +01:00
Peter Steinberger
0e4c7cd155 feat(ios): render native markdown headings (#103404) 2026-07-10 06:21:46 +01:00
lsr911
a3f9f3567f fix(terminal): strip C1 control characters (0x80-0x9f) in renderTerminalBufferText (#103274)
renderTerminalBufferText filters C0 control characters (0x00-0x1f)
and DEL (0x7f) but did not filter C1 controls (0x80-0x9f). The C1
range includes the CSI (Control Sequence Introducer) at 0x9b, an
alternative ANSI escape prefix that stripAnsiSequences() may miss.

Add the C1 range to CONTROL_BYTES_REGEX to strip all C1 bytes.

Same pattern as the C1 fix in sanitizeForConsole (#103226).

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-10 06:21:29 +01:00
mikasa
541c9f0bf0 fix(cli): bound node camera URL downloads (#103266)
* fix(cli): bound node camera URL downloads

* refactor(cli): enforce camera download policy at guard

* refactor(cli): enforce camera download policy at guard

* refactor(cli): enforce camera download policy at guard

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-10 06:21:01 +01:00
mikasa
20e1368787 fix(mattermost): cap opaque target cache (#103258)
* fix(mattermost): cap opaque target cache

* refactor(mattermost): clarify bounded target cache

* chore: keep release notes in PR

* chore: keep release notes in PR

* refactor(mattermost): clarify bounded target cache

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-10 06:20:30 +01:00
Peter Steinberger
617f59ccd0 test: guard bundled probe PID cleanup (#103399) 2026-07-10 06:20:21 +01:00
mikasa
1e3dea750b fix(github-copilot): bound device flow requests (#103255)
* fix(github-copilot): bound device flow requests

* docs(changelog): note Copilot login timeout

* fix(github-copilot): bound device flow requests

* fix(github-copilot): bound device flow requests

* fix(github-copilot): bound device flow requests

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-10 06:19:51 +01:00
iloveleon19
70a7e6e658 feat(mattermost): add opt-in DM threading by chat type (#98111)
* feat(mattermost): add opt-in DM threading via dmReplyToMode

Resolves #93203.

Mattermost direct messages are hardcoded non-threaded: resolveMattermostReplyToMode
returns "off" for direct chats before consulting config, and the reply-root /
effective-reply resolvers short-circuit for direct chats. So every DM accretes into
one ever-growing session with unbounded per-session token usage, with no way to
isolate each DM topic the way groups/channels (and Slack) can.

Add channels.mattermost.dmReplyToMode (same enum as replyToMode), default "off" so
existing flat-DM deployments are unchanged. When set to "first"/"all", a DM @mention
starts an independent, thread-scoped session:

- resolveMattermostReplyToMode: direct chats return config.dmReplyToMode ?? "off".
- resolveMattermostEffectiveReplyToId: direct early-return gated on replyToMode "off"
  (the value already reflects dmReplyToMode for direct chats).
- resolveMattermostReplyRootId: direct early-return gated on the absence of a thread
  root (a DM carries one only when DM threading is enabled).
- New DM threads start fresh (no parent-session inheritance) so each topic is isolated;
  a threaded DM keeps its own history key while a flat DM root keeps none.

Default-off preserves the documented flat-DM contract, so this changes no existing
behavior. Adds unit coverage and documents the opt-in. The only open question is the
knob shape (dmReplyToMode enum vs a boolean dmThreading) — happy to adjust.

Refs #65729.

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

* fix(mattermost): register dmReplyToMode in config schema

dmReplyToMode was wired into the account config type and reply
resolution but never added to MattermostConfigSchema, so setting it in
openclaw.json failed config validation ("must not have additional
properties: dmReplyToMode") and the gateway refused to start — the knob
could not actually be enabled. Register it in the schema, regenerate the
bundled channel config metadata and doc baseline, and add a
config-schema test.

* fix(mattermost): thread direct reply transport when dmReplyToMode is on

resolveReplyTransport nulled the direct reply root/thread id
unconditionally, so routed replies and message-tool follow-ups in an
opted-in DM thread were still sent flat even when the effective
replyToMode was first/all. Keep direct transport flat only when the mode
is off (the historical contract) and preserve the thread root otherwise,
matching the monitor-level DM threading gates. Adds channel.test.ts
coverage for resolveReplyTransport.

* fix(mattermost): use per-chat reply mode overrides

* fix(mattermost): bound direct thread history

* chore(config): refresh docs baseline

---------

Co-authored-by: leon <leon@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:19:03 +01:00
Peter Steinberger
d9f9d339ea fix(google): retry transient Lyria no-audio responses (#103326)
* fix(google): retry transient Lyria no-audio responses

* fix(google): bound Lyria retry timeout
2026-07-10 06:18:37 +01:00
xingzhou
87a652bc37 fix(fal): image generation hangs on slow generated-image downloads (#103071)
* fix(fal): timeout generated image downloads

* fix(fal): honor image operation timeout budget

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 06:08:03 +01:00
Peter Steinberger
a7c5b2c6e6 fix(onboarding): preserve plugin ownership from included config (#103372)
* fix(onboarding): preserve included plugin install records

* fix(config): validate inherited plugin install records

* fix(onboarding): preserve canonical plugin install ownership

* test(onboarding): cover completed install migrations
2026-07-10 06:07:41 +01:00
Peter Steinberger
4a40f5d7f0 fix(xai): align image and video capability contracts (#103384)
* fix(xai): align media capability contracts

* chore: move xai media release note to pr
2026-07-10 06:06:50 +01:00
Peter Steinberger
b6a86b34ce improve: retry transient live image probe mismatches (#103327)
* test: retry transient live image probe mismatches

* test: keep live probe test in unit-fast shard

* test: harden live image probe retry
2026-07-10 05:58:21 +01:00
Peter Steinberger
2541720773 fix(ui): prevent stale locale elements in shared test runs (#103345)
* test(ui): isolate locale-sensitive custom elements

* chore: keep release notes in PR
2026-07-10 05:46:23 +01:00
Peter Steinberger
cd9db5ed9a fix(doctor): keep automated repair from moving approval state (#103353)
* fix(doctor): isolate automated cross-state imports

* test(update): cover isolated doctor finalization
2026-07-10 05:42:36 +01:00
Sahil Satralkar
4e3d91a020 feat: iOS Privacy screen location controls (#103096)
* Fix iOS privacy location card presentation

* Refine iOS location privacy controls

* fix(ios): restore location access chooser

* style(ios): format location access dialog

* chore: keep release note in PR body

* test(ios): keep privacy coverage focused

* fix(ios): clear unresolved location mode

* chore(ios): refresh native strings

* fix(ios): localize location status copy

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 05:42:04 +01:00
Peter Steinberger
d3fae3c783 fix(ui): use default cursor for sidebar sessions, reserve pointer for links (#103357) 2026-07-10 05:41:01 +01:00
Peter Steinberger
d7d210f7e0 test(gateway): prove Claude CLI warm-session continuity (#103343)
* test(gateway): prove Claude CLI warm-session continuity

Co-authored-by: Brad Reaves <reaves.brad@gmail.com>

* test(gateway): satisfy continuity helper lint

---------

Co-authored-by: Brad Reaves <reaves.brad@gmail.com>
2026-07-10 05:31:37 +01:00
krissding
5ebe040eaa fix(xai): require consent for cross-provider billed tools (#97629)
* fix(xai): gate billed tools by active provider

Co-authored-by: 丁宇婷0668001435 <ding.yuting@xydigit.com>

* chore: remove contributor changelog entry

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 05:30:23 +01:00
Peter Steinberger
a4d2d676f1 fix(ui): stabilize locale-reactivity tests (#103338) 2026-07-10 05:26:42 +01:00
Peter Steinberger
ef555b13c1 fix(agents): contain progress callback failures (#103351)
Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
2026-07-10 05:26:02 +01:00
Peter Steinberger
98b8c8c4ae feat(memory-wiki): isolate vaults per agent (#103349)
* feat(memory-wiki): isolate per-agent vaults

Refs #63829.

Co-authored-by: SunnyShu <shu.zongyu@xydigit.com>

* fix(memory-wiki): scope agent status metadata

Refs #103088 and #103196.

Co-authored-by: SunnyShu <shu.zongyu@xydigit.com>

---------

Co-authored-by: SunnyShu <shu.zongyu@xydigit.com>
2026-07-10 05:19:13 +01:00
Peter Steinberger
6fd9c1df69 fix(status): keep diagnostics config reads read-only (#103252)
* fix: keep status config reads non-observing

Co-authored-by: Sascha Kuhlmann <coolmanns@users.noreply.github.com>

* fix: keep status preflight non-observing

* fix: keep status-all diagnosis non-observing

* chore: leave release changelog to maintainers

---------

Co-authored-by: Sascha Kuhlmann <coolmanns@users.noreply.github.com>
2026-07-10 05:16:44 +01:00
Peter Steinberger
a2d5f32cef fix(browser): make node action downloads usable (#103328)
* fix(browser): transfer plural node downloads

* test(browser): avoid proxy test path shadowing
2026-07-10 05:11:22 +01:00
Peter Steinberger
1f12e7fc87 fix(ios): replace dead-end discovered gateway connects (#103289)
* fix(ios): clarify insecure discovered gateways

* fix(ios): finish discovered gateway guidance

* fix(ios): preserve gateway failure expression
2026-07-10 05:08:58 +01:00