Commit Graph

16723 Commits

Author SHA1 Message Date
Echo dde00aef62 fix(mattermost): await slash cleanup on monitor shutdown 2026-03-03 07:07:19 +00:00
Echo f03358edb0 fix(mattermost): harden callback auth bypass and default callback port 2026-03-03 07:07:19 +00:00
Echo 1a2fb8fc20 fix(mattermost): fail closed on ambiguous slash token routing 2026-03-03 07:07:19 +00:00
Echo 4f99f0e663 fix: harden mattermost auth bypass + labeler 2026-03-03 07:07:19 +00:00
Echo b0d703158f fix(mattermost): ignore wildcard bind hosts for slash callback URLs 2026-03-03 07:07:19 +00:00
Echo 8c64b726fd fix(mattermost): fail closed if listing slash commands fails 2026-03-03 07:07:19 +00:00
Echo 994dcf7bdc fix(mattermost): default unknown slash channel kind to channel 2026-03-03 07:07:19 +00:00
Echo 66cfba8221 fix(mattermost): merge commands config + be lenient on DM channel lookup 2026-03-03 07:07:19 +00:00
Echo 5e62c4a3eb fix(gateway): bypass auth for configured mattermost slash callback paths 2026-03-03 07:07:19 +00:00
Echo c67d5277c3 fix(mattermost): derive slash callback port from runtime env 2026-03-03 07:07:19 +00:00
Echo 1c1027634f fix: tighten commands.allowFrom override + IPv6-safe callback URL 2026-03-03 07:07:19 +00:00
Echo 5771f483fc fix(mattermost): don't hard-fail loopback slash callback URL 2026-03-03 07:07:19 +00:00
Echo 57e29cae5c fix(gateway): allow Mattermost slash callback without bearer auth 2026-03-03 07:07:19 +00:00
Echo 434dc0ffd5 fix(mattermost): deactivate slash state before async cleanup to prevent race
Snapshot registered commands, then deactivate state immediately on abort.
Prevents race where new monitor activates fresh state that gets wiped
by the delayed .then() of the old monitor's cleanup promise.
2026-03-03 07:07:19 +00:00
Echo 5bbe16f2ce fix(mattermost): export skill-commands via plugin-sdk + thread triggerMap for accurate command name resolution
- Export listSkillCommandsForAgents and SkillCommandSpec from plugin-sdk/index.ts
  (removes deep relative import in monitor.ts)
- Add originalName field to MattermostCommandSpec for preserving pre-prefix names
- Build trigger→originalName map in monitor.ts, thread through slash-state → slash-http
- resolveCommandText() now uses triggerMap for accurate name lookup
  (oc_report → /oc_report correctly, not /report)
2026-03-03 07:07:19 +00:00
Echo 81087ecb6b fix(mattermost): align slash allowlist normalization + register callbackUrl pathname
- normalizeAllowList/isSenderAllowed in slash-http.ts now matches the
  websocket monitor: strips mattermost:/user:/@  prefixes and supports
  the '*' wildcard, so configs that work for WS also work for slash cmds
- registerSlashCommandRoute extracts pathname from explicit callbackUrl
  and registers it alongside callbackPath, so callbacks hit a registered
  route even when callbackUrl uses a non-default pathname

Addresses Codex review round 5 (P1 + P2).
2026-03-03 07:07:19 +00:00
Echo d486f208a2 fix(mattermost): reachable callbackUrl guard, nativeSkills support, URL reconciliation
- Reject slash command registration when callbackUrl resolves to
  loopback but Mattermost baseUrl is remote; log actionable error
  directing user to set commands.callbackUrl explicitly
- Honor commands.nativeSkills: when enabled, dynamically list skill
  commands and register them with oc_ prefix alongside built-in commands
- Reconcile existing commands on callback URL change: attempt PUT update,
  fallback to delete+recreate for stale commands with mismatched URLs
- Add updateMattermostCommand() for PUT /api/v4/commands/{id}

Addresses Codex review round 4 (P1 + P2 items).
2026-03-03 07:07:19 +00:00
Echo f0a0766d99 fix(mattermost): validate JSON payload fields + normalize callbackPath
- parseSlashCommandPayload JSON branch now validates required fields
  (token, team_id, channel_id, user_id, command) like the form-encoded
  branch, preventing runtime exceptions on malformed JSON payloads
- normalizeCallbackPath() ensures leading '/' to prevent malformed URLs
  like 'http://host:portapi/...' when callbackPath lacks a leading slash
- Applied in resolveSlashCommandConfig and resolveCallbackUrl

Addresses Codex review round 3 (P2 items).
2026-03-03 07:07:19 +00:00
Echo a59b27f2e6 fix(mattermost): harden native slash commands
Address Codex follow-up feedback:

- Enforce DM/group allowlist + control-command gating for native slash commands
  (no unconditional CommandAuthorized=true).
- Register callback HTTP routes for all configured callbackPath values
  (top-level + per-account overrides).
- Track whether slash commands were created by this process; only delete
  managed commands on shutdown, leaving pre-existing commands intact.
2026-03-03 07:07:19 +00:00
Echo fb720193d9 fix(mattermost): fail closed on empty tokens + per-account slash state
Address Codex review findings:

1. slash-http.ts: Token validation now rejects when commandTokens set is
   empty (e.g. registration failure). Previously an empty set meant any
   token was accepted — fail-open vulnerability.

2. slash-state.ts: Replaced global singleton with per-account state Map
   keyed by accountId. Multi-account deployments no longer overwrite each
   other's tokens, registered commands, or handlers. The HTTP route
   dispatcher matches inbound tokens to the correct account.

3. monitor.ts: Updated getSlashCommandState/deactivateSlashCommands calls
   to pass accountId.
2026-03-03 07:07:19 +00:00
Echo 220d9775d8 feat(mattermost): add native slash command support
Register custom slash commands via Mattermost REST API at startup,
handle callbacks via HTTP endpoint on the gateway, and clean up
commands on shutdown.

- New modules: slash-commands.ts (API + registration), slash-http.ts
  (callback handler), slash-state.ts (shared state bridge)
- Config schema extended with commands.{native,nativeSkills,callbackPath,callbackUrl}
- Uses oc_ prefix for triggers (oc_status, oc_model, etc.) to avoid
  conflicts with Mattermost built-in commands
- Opt-in via channels.mattermost.commands.native: true
- Capability nativeCommands: true exposed for command registry

Closes openclaw/openclaw#16515
2026-03-03 07:07:19 +00:00
Eugene 5341b5c71c
Diffs: Migrate tool usage guidance from before_prompt_build to a plugin skill (#32630)
Merged via squash.

Prepared head SHA: 585697a4e1
Co-authored-by: sircrumpet <4436535+sircrumpet@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-03 01:50:59 -05:00
Henry Loenwind 997197c6c9
bug: Workaround for QMD upstream bug (#27028)
Merged via squash.

Prepared head SHA: 939f9f4574
Co-authored-by: HenryLoenwind <1485873+HenryLoenwind@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-03 01:48:43 -05:00
JT de9031da22
fix: improve compaction summary instructions to preserve active work (#8903)
fix: improve compaction summary instructions to preserve active work

Expand staged-summary merge instructions to preserve active task status, batch progress, latest user request, and follow-up commitments so compaction handoffs retain in-flight work context.

Co-authored-by: joetomasone <56984887+joetomasone@users.noreply.github.com>
Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-03-02 22:36:19 -08:00
Henry Loenwind 75775f2fe6
chore: Updated Brave documentation (#26860)
Merged via squash.

Prepared head SHA: f8fc4bf01e
Co-authored-by: HenryLoenwind <1485873+HenryLoenwind@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-03 01:34:15 -05:00
Tak Hoffman dbccc73d7a
security(line): synthesize strict LINE auth boundary hardening
LINE auth boundary hardening synthesis for inbound webhook authn/z/authz:
- account-scoped pairing-store access
- strict DM/group allowlist boundary separation
- fail-closed webhook auth/runtime behavior
- replay and duplicate handling with in-flight continuity for concurrent redeliveries

Source PRs: #26701, #26683, #25978, #17593, #16619, #31990, #26047, #30584, #18777
Related continuity context: #21955

Co-authored-by: bmendonca3 <208517100+bmendonca3@users.noreply.github.com>
Co-authored-by: davidahmann <46606159+davidahmann@users.noreply.github.com>
Co-authored-by: harshang03 <58983401+harshang03@users.noreply.github.com>
Co-authored-by: haosenwang1018 <167664334+haosenwang1018@users.noreply.github.com>
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: coygeek <65363919+coygeek@users.noreply.github.com>
Co-authored-by: lailoo <20536249+lailoo@users.noreply.github.com>
2026-03-03 00:21:15 -06:00
Peter Steinberger fe92113472 test(e2e): isolate module mocks across harnesses 2026-03-03 05:52:14 +00:00
Peter Steinberger 1d7a287cf6 fix(telegram): debounce forwarded media-only bursts 2026-03-03 05:52:14 +00:00
Peter Steinberger 094140bdb1 test(live): harden gateway model profile probes 2026-03-03 05:52:14 +00:00
Peter Steinberger b52c9f2575 fix(ci): handle disabled systemd units in docker doctor flow 2026-03-03 05:52:14 +00:00
Peter Steinberger de62ccbf81 fix(test): stabilize appcast version assertion 2026-03-03 05:51:50 +00:00
Tak Hoffman 9a5bfb1fe5
fix(line): synthesize media/auth/routing webhook regressions (openclaw#32546) thanks @Takhoffman
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 23:47:56 -06:00
Viz 0b3bbfec06
fix(gateway+acp): thread stopReason through final event to ACP bridge (#24867)
Complete the stop reason propagation chain so ACP clients can
distinguish end_turn from max_tokens:

- server-chat.ts: emitChatFinal accepts optional stopReason param,
  includes it in the final payload, reads it from lifecycle event data
- translator.ts: read stopReason from the final payload instead of
  hardcoding end_turn

Chain: LLM API → run.ts (meta.stopReason) → agent.ts (lifecycle event)
→ server-chat.ts (final payload) → ACP translator (PromptResponse)
2026-03-03 00:40:54 -05:00
Peter Steinberger b34530a05d docs(changelog): reattribute duplicated PR credits 2026-03-03 05:40:05 +00:00
Peter Steinberger e1503349c3 fix: scope extension runtime deps to plugin manifests 2026-03-03 05:33:12 +00:00
Shadow 2a888c5703
ci: enable stale workflow 2026-03-02 23:21:34 -06:00
Peter Steinberger 786ff6afca chore(release): bump to 2026.3.3 and seed changelog 2026-03-03 05:12:23 +00:00
Peter Steinberger 2d67c9b2a0 fix: repair Feishu reset hook typing and stabilize secret resolver timeout 2026-03-03 05:06:08 +00:00
Viz a9ec75fe81
fix(gateway): flush throttled delta before emitChatFinal (#24856)
* fix(gateway): flush throttled delta before emitChatFinal

The 150ms throttle in emitChatDelta can suppress the last text chunk
before emitChatFinal fires, causing streaming clients (e.g. ACP) to
receive truncated responses. The final event carries the complete text,
but clients that build responses incrementally from deltas miss the
tail end.

Flush one last unthrottled delta with the complete buffered text
immediately before sending the final event. This ensures all streaming
consumers have the full response without needing to reconcile deltas
against the final payload.

* fix(gateway): avoid duplicate delta flush when buffer unchanged

Track the text length at the time of the last broadcast. The flush in
emitChatFinal now only sends a delta if the buffer has grown since the
last broadcast, preventing duplicate sends when the final delta passed
the 150ms throttle and was already broadcast.

* fix(gateway): honor heartbeat suppression in final delta flush

* test(gateway): add final delta flush and dedupe coverage

* fix(gateway): skip final flush for silent lead fragments

* docs(changelog): note gateway final-delta flush fix credits

---------

Co-authored-by: Jonathan Taylor <visionik@pobox.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-02 23:45:46 -05:00
dongdong 0566845b71
fix(feishu): validate outbound renderMode routing with tests (#31562)
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 22:41:01 -06:00
Jealous 9083a3f2e3
fix(feishu): normalize all mentions in inbound agent context (#30252)
* fix(feishu): normalize all mentions in inbound agent context

Convert Feishu mention placeholders to explicit <at user_id="..."> tags (including bot mentions), add mention semantics hints for the model, and remove unused mentionMessageBody parsing to keep context handling consistent.

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

* fix(feishu): use replacer callback and escape only < > in normalizeMentions

Switch String.replace to a function replacer to prevent $ sequences in
display names from being interpolated as replacement patterns. Narrow
escaping to < and > only — & does not need escaping in LLM prompt tag
bodies and escaping it degrades readability (e.g. R&D → R&amp;D).

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

* fix(feishu): only use open_id in normalizeMentions tag, drop user_id fallback

When a mention has no open_id, degrade to @name instead of emitting
<at user_id="uid_...">. This keeps the tag user_id space exclusively
open_id, so the bot self-reference hint (which uses botOpenId) is
always consistent with what appears in the tags.

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

* fix(feishu): register mention strip pattern for <at> tags in channel dock

Add mentions.stripPatterns to feishuPlugin so that normalizeCommandBody
receives a slash-clean string after normalizeMentions replaces Feishu
placeholders with <at user_id="...">name</at> tags. Without this,
group slash commands like @Bot /help had their leading / obscured by
the tag prefix and no longer triggered command handlers.

Pattern mirrors the approach used by Slack (<@[^>]+>) and Discord (<@!?\d+>).

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

* fix(feishu): strip bot mention in p2p to preserve DM slash commands

In p2p messages the bot mention is a pure addressing prefix; converting
it to <at user_id="..."> breaks slash commands because buildCommandContext
skips stripMentions for DMs. Extend normalizeMentions with a stripKeys
set and populate it with bot mention keys in p2p, so @Bot /help arrives
as /help. Non-bot mentions (mention-forward targets) are still normalized
to <at> tags in both p2p and group contexts.

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

* Changelog: note Feishu inbound mention normalization

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 22:40:17 -06:00
Peter Steinberger 85377a2817 chore(release): cut 2026.3.2 2026-03-03 04:35:46 +00:00
Vincent Koc d45aa68ae8 CI: disable flaky sticky disk mount for Windows pnpm setup 2026-03-02 20:34:10 -08:00
Vincent Koc be5de30de5 CI: start push test lanes earlier and drop check gating 2026-03-02 20:29:06 -08:00
挨踢小茶 406e7aba75
fix(feishu): guard against false-positive @mentions in multi-app groups (#30315)
* fix(feishu): guard against false-positive @mentions in multi-app groups

When multiple Feishu bot apps share a group chat, Feishu's WebSocket
event delivery remaps the open_id in mentions[] per-app. This causes
checkBotMentioned() to return true for ALL bots when only one was
actually @mentioned, making requireMention ineffective.

Add a botName guard: if the mention's open_id matches this bot but the
mention's display name differs from this bot's configured botName, treat
it as a false positive and skip.

botName is already available via account.config.botName (set during
onboarding).

Closes #24249

* fix(feishu): support @all mention in multi-bot groups

When a user sends @all (@_all in Feishu message content), treat it as
mentioning every bot so all agents respond when requireMention is true.

Feishu's @all does not populate the mentions[] array, so this needs
explicit content-level detection.

* fix(feishu): auto-fetch bot display name from API for reliable mention matching

Instead of relying on the manually configured botName (which may differ
from the actual Feishu bot display name), fetch the bot's display name
from the Feishu API at startup via probeFeishu().

This ensures checkBotMentioned() always compares against the correct
display name, even when the config botName doesn't match (e.g. config
says 'Wanda' but Feishu shows '绯红女巫').

Changes:
- monitor.ts: fetchBotOpenId → fetchBotInfo (returns both openId and name)
- monitor.ts: store botNames map, pass botName to handleFeishuMessage
- bot.ts: accept botName from params, prefer it over config fallback

* Changelog: note Feishu multi-app mention false-positive guard

---------

Co-authored-by: Teague Xiao <teaguexiao@TeaguedeMac-mini.local>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 22:27:35 -06:00
Andy Tien cad06faafe
fix: add session-memory hook support for Feishu provider (#31437)
* fix: add session-memory hook support for Feishu provider

Issue #31275: Session-memory hook not triggered when using /new command in Feishu

- Added command handler to Feishu provider
- Integrated with OpenClaw's before_reset hook system
- Ensures session memory is saved when /new or /reset commands are used

* Changelog: note Feishu session-memory hook parity

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 22:19:24 -06:00
Huaqing.Hao a5a7239182
fix(feishu): non-blocking WS ACK and preserve full streaming card content (#29616)
* fix(feishu): non-blocking ws ack and preserve streaming card full content

* fix(feishu): preserve fragmented streaming text without newline artifacts

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 22:17:15 -06:00
Vincent Koc a5a6952bf2 CI: reduce critical path for check build and windows jobs 2026-03-02 20:11:28 -08:00
Vincent Koc d28fa50f8b CI: make node deps install optional in setup action 2026-03-02 20:11:28 -08:00
Vincent Koc 5ef04d2822 CI: speed up Windows dependency warmup 2026-03-02 20:11:12 -08:00