Commit Graph

67697 Commits

Author SHA1 Message Date
Vincent Koc
890f4efc88 fix(qa-channel): handle metadata-free final replies
Fix qa-channel final reply preview delivery when a harness or plugin path calls deliver without dispatcher metadata. Verified with remote Testbox proof plus hosted PR checks.
2026-07-04 17:23:52 -07:00
Hana Chang
4ec7842be0 feat(slack): add ignoreOtherMentions channel config (#53467)
* feat(slack): add ignoreOtherMentions channel config

Mirrors the existing Discord `ignoreOtherMentions` option for Slack
channels. When set on a channel entry, drop channel/group/MPIM messages
that mention another user or subteam but not this bot — the inverse of
`requireMention`. Useful in busy channels where the bot would otherwise
reply to side conversations.

Implementation lives in `prepareSlackMessage` right after the
`allowBots: "mentions"` bot-drop gate and before the `shouldRequireMention`
non-mention drop, so it integrates with the new `messageIngress` ingress
pipeline. The gate is conditional on `canDetectMention` (botUserId
resolvable via `auth.test` or explicit mention regexes configured) to
avoid false drops when we have no reliable way to tell bot vs non-bot
mentions apart.

Slack implicit mentions (thread participation) are intentionally NOT
respected here — they fire for every message in a bot-participated
thread, so honoring them would defeat the feature in any active thread.
The gate matches on `wasMentioned` (explicit) and `hasAnyMention`, with
the existing `shouldBypassMention` override (e.g. authorized commands)
also respected.

Includes config types, zod schema, channel-config resolution,
prepare-message implementation, full test coverage in
`prepare.test.ts`, regenerated channel + docs baselines, and Slack
docs entry.

* refactor(slack): harden other-mention filtering

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 20:08:14 -04:00
Rohang2005
03fe813d1e fix(slack): forward per-agent identity overlay on heartbeat and runtimeSend (#84297) (#84335)
* fix(slack): preserve agent identity on heartbeat sends

Co-authored-by: Rohang2005 <rohan.ganesh05@gmail.com>

* fix(slack): preserve identity when custom icons fail

* fix(slack): reuse accepted identity across chunks

* fix(slack): narrow identity fallback input

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 20:05:47 -04:00
TwinsLee
568237b3ab fix(feishu): emit non-empty value schema for bitable write tools (#94547) (#94990)
Type.Record(Type.String(), Type.Any()) serializes via TypeBox to an empty nested value schema (patternProperties: { "^.*$": {} }). AWS Bedrock's strict tool-schema validation rejects the empty sub-schema, breaking all agent turns for Bedrock-backed Anthropic users with Feishu bitable tools enabled.

Replace the three affected free-form field maps (create_record, update_record, create_field) with an explicit non-empty FlexibleFieldValue value schema that still accepts any JSON value. Type.Unknown() is avoided because it also serializes to an empty schema. Adds regression coverage asserting the emitted value schema is non-empty.

Co-authored-by: TwinsLee <1460694+TwinsLee@users.noreply.github.com>
2026-07-04 17:05:32 -07:00
Dallin Romney
bfffa950d7 refactor(plugin-sdk): consolidate tool result helpers (#99740)
* refactor(plugin-sdk): consolidate tool result helpers

* docs(plugin-sdk): tighten tool result guidance

* refactor(feishu): use tool results directly
2026-07-04 16:50:44 -07:00
Dallin Romney
c2fc7aa28a refactor: consolidate exact keyed async queues (#99691)
* refactor: consolidate keyed async queues

* chore: refresh merge-ref CI

* refactor: encapsulate keyed queue ownership
2026-07-04 16:45:07 -07:00
Peter Steinberger
7608d38597 improve(ui): flatten chat tool-call rows into scannable list (#99763)
Tool calls in Control UI chat rendered as triple-nested cards: activity
group card + tool-shell bubble chrome + gradient summary pill with a
0 8px 22px drop shadow. Collapsed rows now render as flat single-line
rows with ellipsis, the activity group uses a flat header plus a left
rule, and expanded detail keeps soft tinted blocks without card chrome.
Also deletes the dead legacy .chat-tool-card__details/__output CSS and
the unused renderToolCardSidebar path with its never-taken
renderToolDataBlock branches.

Closes #99760
2026-07-04 19:42:59 -04:00
Vincent Koc
3d64efbd3d test(ui): stabilize Control UI suite routing
Keep moved Control UI browser layout tests routed in both UI Vitest configs and stabilize chat suite-order assertions. Verified with Testbox UI proof and changed gate; final PR CI remains the merge gate.
2026-07-04 16:38:36 -07:00
Dallin Romney
194dd6fe50 refactor(security): consolidate secret primitives (#99746)
* refactor(security): consolidate secret primitives

* fix(plugin-sdk): align secret display metadata

* chore(plugin-sdk): refresh API baseline after rebase

* refactor(security): trim secret primitive consolidation
2026-07-04 16:38:13 -07:00
qingminlong
3adfaf0394 fix: detect localized Windows netstat listeners (#100012)
* fix: parse localized Windows netstat listeners

* fix: share Windows netstat PID fallback

* test: relax native command QA timeout

* test: wait for native stop cleanup before recovery

* fix(windows): harden localized netstat parsing

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-04 16:35:29 -07:00
Dallin Romney
dc3b5df684 refactor(types): remove redundant local aliases (#100061)
* refactor(models): remove redundant generation model ref alias

* refactor(types): remove redundant local aliases

* refactor(types): preserve shipped model ref type
2026-07-04 16:34:47 -07:00
Dallin Romney
cf14b27d81 refactor: consolidate safe json parsing (#99688) 2026-07-04 16:33:27 -07:00
Ayaan Zaidi
4682364fa6 fix(agents): compact on aggregate tool-result pressure 2026-07-04 16:21:08 -07:00
Ayaan Zaidi
168a4890bb fix(agents): scale aggregate tool-result budget by context 2026-07-04 16:21:08 -07:00
Marvinthebored
6445a0632d feat(cli): render claude CLI native thinking with /reasoning gating
The claude-cli (claude-stdio) live-session backend emits native
reasoning on stream-json (`thinking_delta` + a snapshot `thinking`
block), but the CLI parser had no thinking handling at all, so it was
silently dropped on every surface in every /reasoning mode.

- cli-output.ts: parse thinking_delta/snapshot into stream:"thinking"
  with replace-style per-content-block-index dedupe
  (assembleThinkingTextByIndex), robust to tool-interleaved multi-block
  turns (snapshot replaces per-index rather than assuming a streamed
  prefix). signature_delta/redacted_thinking stay skipped.
- agent-runner-cli-dispatch.ts: bridge stream:"thinking" into
  onReasoningStream via a new createReasoningTextBridge (mirrors the
  existing assistant-text bridge), replacing the old
  assistant-text-as-reasoning heuristic. Track the final reasoning
  snapshot and, when present, prepend a durable
  `{text, isReasoning: true}` payload before the answer — mirroring
  the embedded-runner durable reasoning payload
  (embedded-agent-runner/run/payloads.ts).
- agent-runner-execution.ts: thread isReasoningSnapshot through to
  onReasoningStream, still passing requiresReasoningProgressOptIn:true
  so CLI reasoning rides the exact same channel gates as embedded
  reasoning (Discord/Telegram): /reasoning off -> nothing on any
  surface, stream -> window preview only, on -> durable payload too.
  The bridge is suppressed under the same conditions as the assistant
  bridge (e.g. silentExpected follow-ups), so no durable payload is
  synthesized for turns that are expected to stay silent.

Supersedes this branch's prior commit (a straight port of
af7eb48e05's emit-always model, no gating and no durable mode) with
the above gated/durable design per product decision.

Also, in cli-output.ts: reset the per-content-block-index thinking
tracker on every new Anthropic message (message_start, or a fresh
top-level "assistant" snapshot's message.id) instead of leaving it
scoped to the whole CLI turn. Content-block indices restart at 0 per
Anthropic message, so a tool round-trip within one turn (message A:
thinking + tool_use; tool result fed back; message B: a fresh
message_start) was letting message A's stale index-0 thinking text
bleed into message B's index-0 delta.

And in agent-runner-cli-dispatch.ts: attach the durable reasoning
payload whenever any thinking was bridged, not only when the CLI also
produced a visible final answer, so a thinking-only turn (no visible
reply) doesn't silently drop its reasoning.

Round 2: the durable `{isReasoning: true}` payload synthesized above
was also reaching the QUEUED FOLLOW-UP delivery path
(followup-runner.ts -> resolveFollowupDeliveryPayloads) with no gate
at all, so a claude-cli queued follow-up with /reasoning off would
leak internal reasoning to the channel as an ordinary visible message.
resolveFollowupDeliveryPayloads (followup-delivery.ts) now takes a
reasoningPayloadsEnabled flag and drops isReasoning payloads unless
it is true; followup-runner.ts threads opts?.reasoningPayloadsEnabled
through at both call sites, from the same GetReplyOptions the direct
path already reads (dispatch-from-config.ts:2054). This makes the
queued-follow-up path apply the identical isReasoning/
reasoningPayloadsEnabled gate that direct dispatch already enforces
(dispatch-from-config.ts:3347, :3537) — no new mechanism, CLI
follow-ups now go through the exact same gate embedded follow-ups do.

Scope note: routeReply's own unconditional suppression of isReasoning
payloads on the origin-routing branch (route-reply.ts:131,
shouldSuppressReasoningPayload) is pre-existing, shared with the
embedded runner, and unchanged by this commit — that gate governs
whether a kept-and-routed reasoning payload is actually rendered on a
cross-channel queued follow-up, and is out of scope here. This commit
closes the leak (off -> never eligible on any path); it does not
change what happens to an eligible payload once it reaches routeReply.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-04 16:19:10 -07:00
github-actions[bot]
1c9e998d98 chore(ui): refresh control ui locales 2026-07-04 23:07:17 +00:00
Peter Steinberger
dd6bc2ec32 fix(ui): repair router refactor regressions (#100106) 2026-07-04 19:00:54 -04:00
Peter Steinberger
f5d446e483 chore(ui): translate terminal.detached across locales 2026-07-04 15:58:18 -07:00
Peter Steinberger
e57bcbca50 docs: fold terminal reattach into the hardened terminal docs (opt-in default) 2026-07-04 15:58:18 -07:00
Peter Steinberger
619fee1b4f fix(control-ui): never close live sessions from bulk teardown; reattach owns recovery 2026-07-04 15:58:18 -07:00
Peter Steinberger
2b89a9b14d docs(control-ui): document why teardown close RPCs cannot kill reattachable sessions 2026-07-04 15:58:18 -07:00
Peter Steinberger
ad6d55159a fix(control-ui): keep the terminal open preference across disconnects 2026-07-04 15:58:18 -07:00
Peter Steinberger
009d7354b8 fix(gateway): route terminal.attach/list/text through the lazy handler table 2026-07-04 15:58:18 -07:00
Peter Steinberger
b33f09b40d feat(control-ui): reattach terminal sessions after reload/reconnect with replay 2026-07-04 15:58:18 -07:00
Peter Steinberger
5938c7809a feat(gateway): terminal detach/reattach with output replay, terminal.list/text 2026-07-04 15:58:17 -07:00
Peter Steinberger
be8b5f6c4f fix(slack): preserve custom identity while streaming (#100084)
Use supported chat.startStream authorship and avoid edit-based previews when custom identity cannot stream.

Co-authored-by: MoerAI <friendnt@g.skku.edu>
2026-07-04 18:56:36 -04:00
Peter
526c024fc0 fix(slack): preserve interaction thread status (#82895)
* fix(slack): preserve interaction thread status

Co-authored-by: Intern Dev <dev@wukongai.io>

* test(slack): type message thread timestamps

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Intern Dev <dev@wukongai.io>
2026-07-04 18:56:11 -04:00
NianJiu
efe4a59ceb fix(gateway): read usage-cost cache once per agent in sessions.usage (#100054)
The sessions.usage RPC loaded each visible session's summary via
loadSessionCostSummaryFromCache, which re-reads and re-parses the entire
.usage-cost-cache.json on every call. At the dashboard's default limit=50
that is ~50 full parses per connect, spiking RSS 200-600 MiB and tripping
the gateway rss_growth memory-pressure alarm with a false positive.

Unify the visible and hidden session paths onto the batched
loadSessionCostSummariesFromCache loader, which reads and parses the cache
at most once per agent regardless of limit.

Fixes #100041
2026-07-04 15:41:33 -07:00
Shakker
65e12328aa feat: refactor the Control UI architecture
Refactor the Control UI around route-owned page lifecycle and state while preserving existing behavior and design.

Prepared head SHA: bd51b6fa76
Co-authored-by: Shakker <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
2026-07-04 23:19:38 +01:00
Gio Della-Libera
832cb3c488 policy: track node deny command coverage 2026-07-04 15:06:10 -07:00
Gio Della-Libera
ef083b9389 test: stabilize policy PR CI guardrails 2026-07-04 15:06:10 -07:00
Gio Della-Libera
fa8f10e6cd docs(policy): document gateway node command policy 2026-07-04 15:06:10 -07:00
Gio Della-Libera
144e5894f6 fix(policy): honor node command deny overrides 2026-07-04 15:06:10 -07:00
Gio Della-Libera
997f74f42b policy: cover gateway node commands 2026-07-04 15:06:10 -07:00
xingzhou
27d6c88167 feat: add utility models and generated session titles (#87643)
* feat: add utility model session titles

* docs: clarify utility model calls

* fix: budget utility title reasoning

* docs: refresh config baseline

* docs: refresh plugin sdk baseline

* docs: refresh plugin sdk baseline

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 17:24:51 -04:00
Peter Steinberger
bbb744269f test: make the local pnpm test gate green on macOS hosts (#100069)
Fixes 21 macOS-only failing test cases across three classes: canonicalized fixture roots (macOS /var -> /private/var tmpdir symlink vs production realpathing), load-tolerant process-spawn tests (content-gated pid files, readiness-sequenced kill windows, bounded-window timer assertions), and cross-file worker leak guards (skip-channel env, gateway token env, imessage runtime singleton). Test-only; no production changes. Fixes #100025.
2026-07-04 17:17:42 -04:00
Jason (Json)
0221544190 fix(release): block stale Codex runtime pins (#100015)
Prevents opted-in plugin runtime dependencies from being published with stale
registry pins. The same freshness assertion now guards both npm and ClawHub
release paths, including the managed Codex runtime.

Prepared head SHA: d5d0ecba4b
Reviewed-by: @fuller-stack-dev

Closes #99951
2026-07-04 15:13:31 -06:00
Dizesales
ff58d23e8f fix(telegram): resolve local Bot API container file paths against trustedLocalFileRoots [AI-assisted] (#91984)
* fix(telegram): resolve local Bot API container file paths against trustedLocalFileRoots

When the self-hosted telegram-bot-api server runs with --local inside a
container, getFile returns absolute file_path values rooted at the
container data dir (/var/lib/telegram-bot-api/...). The host process
mounts that volume at a different path, so the absolute path never
matches a trustedLocalFileRoots entry and inbound media fails to
materialize (messages reach the agent as bare <media:document>
placeholders without bytes).

Map container-absolute paths back to relative candidates and resolve
them under each trusted root, trying both with and without the
per-token directory segment the local server uses. Relative file_path
values are now also resolved against trusted roots before falling back
to the HTTP file endpoint, which keeps large-file (>20MB) local-mode
downloads working.

Path traversal protections: candidates are normalized, NUL bytes and
dot-segments are rejected, and reads stay behind the trusted-roots
file-access sandbox.

AI-assisted (Claude Code), validated with targeted vitest run.

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

Co-Authored-By: Dizesales <269209351+Dizesales@users.noreply.github.com>

* fix(telegram): map local Bot API container media paths

Co-authored-by: Lucas Magalhaes <ellucasrj@gmail.com>

* chore(config): refresh channel metadata

---------

Co-authored-by: Lucas Magalhaes <ellucasrj@gmail.com>
Co-authored-by: Dizesales <269209351+Dizesales@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 17:07:51 -04:00
Peter Steinberger
ed098c6550 refactor(test): drop redundant linked-worktree bundled-plugins pin from run-vitest
The node_modules package-root boundary fix anchors bundled plugin
discovery to the running checkout in nested worktrees, so the wrapper
no longer needs to pin OPENCLAW_BUNDLED_PLUGINS_DIR for symlinked
node_modules layouts. Verified live in a .claude worktree: with the
boundary fix and no pin, vitest workers resolve the worktree's own
extensions in both no-node_modules and symlinked layouts, and linked
worktrees now follow the same canonical dist-preferred discovery as
normal checkouts. The trust env remains owned by test/setup.shared.ts.

Must land together with or after the boundary fix commit directly below.
2026-07-04 21:52:09 +01:00
Vincent Koc
260c9c4589 fix(tooling): accept pnpm separator in web fetch benchmark
Accept the documented package-manager separator for the web fetch benchmark CLI and add a process-level regression test. Verified with rebased Testbox check:changed, prior targeted Testbox benchmark/test smokes, and AWS macOS install/build/gateway probes.
2026-07-04 13:47:14 -07:00
Peter Steinberger
0427fa35fb chore: update oxlint tsgolint (#100083)
* chore: update oxlint tsgolint

* chore: sync Canvas A2UI bundle
2026-07-04 16:41:15 -04:00
qingminlong
b30278895c fix: roll rounded durations into seconds (#100006)
Summary:
- The branch updates the shared duration helpers to branch on rounded millisecond values and adds 999.6ms expectations for compact, human, and precise duration output.
- PR surface: Source +3, Tests +2. Total +5 across 2 files.
- Reproducibility: yes. Current main source branches on raw `ms < 1000` before rounding in all three helpers, and the linked issue plus prior review include direct module proof that 999.6ms returned `1000ms`.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 9e06973112.
- Required merge gates passed before the squash merge.

Prepared head SHA: 9e06973112
Review: https://github.com/openclaw/openclaw/pull/100006#issuecomment-4882739452

Co-authored-by: qingminlong <qing.minlong@xydigit.com>
Approved-by: takhoffman
2026-07-04 20:34:57 +00:00
Peter Steinberger
7e8ea61b08 fix(gateway): harden embedded terminal policy (#100081)
* fix(gateway): harden operator terminal policy

* test(gateway): complete terminal context coverage

* test(gateway): narrow terminal policy mock

* test(gateway): satisfy CSP header lint

* docs: refresh terminal docs map

* test: route terminal temp helper importer
2026-07-04 16:34:07 -04:00
grifjef
7a0188cbd2 fix(memory-core): treat dreaming fence marker lines as inside-fence in promotion guard (#83718)
The lineRangeOverlapsDreamingFence guard tracked insideFence state from
the marker lines but did not flag ranges that included the marker lines
themselves. A relocated promotion range that ended on a start marker,
began on an end marker, or covered only a marker line passed the guard,
and the snippet built from those raw lines carried the marker text into
MEMORY.md.

Treat marker lines as inside-fence content for range overlap purposes
and add unit + integration coverage. The integration test exercises the
real applyShortTermPromotions path: pre-patch a recall whose stored
snippet is the start-marker text produces a 'Promoted From Short-Term
Memory' entry containing the literal marker; post-patch the same input
yields applied=0 and no MEMORY.md write. Refs #80613.
2026-07-04 13:01:04 -07:00
Gio Della-Libera
d5badb9e36 Keep legacy WhatsApp crontab lint opt-in (#99250)
Keep the legacy WhatsApp crontab Doctor lint check opt-in by marking the existing core check default-disabled. Default `doctor --lint` no longer reads the user crontab for this narrow legacy diagnostic, while `--all` and `--only core/doctor/legacy-whatsapp-crontab` still run the detector.

Validation:
- focused Doctor contribution Vitest passed 70/70
- changed-file oxfmt and oxlint passed
- git diff --check passed
- pnpm build passed before the final rebase
- hosted exact-head CI/Testbox gates passed on 8964ccb239 after QA Smoke rerun
- PR body includes real lint-module proof for default skip and explicit selected warning behavior

Maintainer note: accepted ClawSweeper's default-output compatibility tradeoff for this legacy crontab probe; no public SDK/plugin/config contract changes.

Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
2026-07-04 12:48:05 -07:00
Vincent Koc
2f6459093a improve(web-fetch): speed up provider fallback loading (#98559)
* perf(web-fetch): add web fetch benchmark

* perf(web-fetch): cache provider fallback resolution

* perf(firecrawl): avoid duplicate scrape payload wrapping

* perf(web-readability): reuse void tag lookup

* fix(web-fetch): keep provider cache live

* fix(web-fetch): invalidate provider cache on registry swap

* perf(web-fetch): reduce html extraction overhead

* fix(web-fetch): bound provider discovery cache

* perf(web-fetch): avoid full plugin load on fallback
2026-07-04 12:47:10 -07:00
Dallin Romney
1d839d3339 refactor: consolidate unique string lists (#99785) 2026-07-04 12:38:23 -07:00
Kevin Lin
d214622320 feat(update): support extended-stable package updates (#99811)
* feat(update): add extended-stable channel contract

* feat(update): implement extended-stable package flow

* docs(update): document extended-stable behavior

* fix(update): preserve extended-stable preflight guarantees

* fix(update): reject extended-stable Git repair

* fix(update): support loopback extended-stable canaries

* fix(update): preserve scoped package roots
2026-07-04 12:34:29 -07:00
Masato Hoshino
fe3215cbb0 fix(cron): roll back live scheduler state when persisting add/update/remove fails (#99960)
* fix(cron): roll back live store when persist fails during add/update/remove

* fix(cron): restore catch-up deferral markers on failed persists

* fix(cron): defer rollback-sensitive notifications

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-04 12:34:02 -07:00
Peter Steinberger
fb8f62d8e4 fix(ui): localize mobile pairing in Hindi and Russian (#100040)
* fix(ui): localize mobile pairing fallbacks

* test(ui): typecheck pairing localization guard

* test(ui): typecheck pairing localization guard

* test(ui): typecheck pairing localization guard

* test(ui): typecheck pairing localization guard

* test(ui): typecheck pairing localization guard
2026-07-04 15:30:48 -04:00