47 Commits

Author SHA1 Message Date
Yi-Cheng Wang
4682f3cace
Fix/Complete LINE requireMention gating behavior (#35847)
* fix(line): enforce requireMention gating in group message handler

* fix(line): scope canDetectMention to text messages, pass hasAnyMention

* fix(line): fix TS errors in mentionees type and test casts

* feat(line): register LINE in DOCKS and CHAT_CHANNEL_ORDER

- Add "line" to CHAT_CHANNEL_ORDER and CHAT_CHANNEL_META in registry.ts
- Export resolveLineGroupRequireMention and resolveLineGroupToolPolicy
  in group-mentions.ts using the generic resolveChannelGroupRequireMention
  and resolveChannelGroupToolsPolicy helpers (same pattern as iMessage)
- Add "line" entry to DOCKS in dock.ts so resolveGroupRequireMention
  in the reply stage can correctly read LINE group config

Fixes the third layer of the requireMention bug: previously
getChannelDock("line") returned undefined, causing the reply-stage
resolveGroupRequireMention to fall back to true unconditionally.

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

* fix(line): pending history, requireMention default, mentionPatterns fallback

- Default requireMention to true (consistent with other channels)
- Add mentionPatterns regex fallback alongside native isSelf/@all detection
- Record unmentioned group messages via recordPendingHistoryEntryIfEnabled
- Inject pending history context in buildLineMessageContext when bot is mentioned

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

* test(line): update tests for requireMention default and pending history

- Add requireMention: false to 6 group tests unrelated to mention gating
  (allowlist, replay dedup, inflight dedup, error retry) to preserve
  their original intent after the default changed from false to true
- Add test: skips group messages by default when requireMention not configured
- Add test: records unmentioned group messages as pending history

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

* fix(line): use undefined instead of empty string as historyKey sentinel

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

* fix(line): deliver pending history via InboundHistory, not Body mutation

- Remove post-hoc ctxPayload.Body injection (BodyForAgent takes priority
  in the prompt pipeline, so Body was never reached)
- Pass InboundHistory array to finalizeInboundContext instead, matching
  the Telegram pattern rendered by buildInboundUserContextPrefix

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

* fix(line): pass agentId to buildMentionRegexes for per-agent mentionPatterns

- Resolve route before mention gating to obtain agentId
- Pass agentId to buildMentionRegexes, matching Telegram behavior

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

* fix(line): clear pending history after handled group turn

- Call clearHistoryEntriesIfEnabled after processMessage for group messages
- Prevents stale skipped messages from replaying on subsequent mentions
- Matches Discord, Signal, Slack, iMessage behavior

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

* style(line): fix import order and merge orphaned JSDoc in bot-handlers

- Move resolveAgentRoute import from ./local group to ../routing group
- Merge duplicate JSDoc blocks above getLineMentionees into one

Addresses Greptile review comments r2888826724 and r2888826840 on PR #35847.

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

* fix(line): read historyLimit from config and guard clear with has()

- bot.ts: resolve historyLimit from cfg.messages.groupChat.historyLimit
  with fallback to DEFAULT_GROUP_HISTORY_LIMIT, so setting historyLimit: 0
  actually disables pending history accumulation
- bot-handlers.ts: add groupHistories.has(historyKey) guard before
  clearHistoryEntriesIfEnabled to prevent writing empty buckets for
  groups that have never accumulated pending history (memory leak)

Addresses Codex review comments r2888829146 and r2888829152 on PR #35847.

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

* style(line): apply oxfmt formatting to bot-handlers and bot

Auto-formatted by oxfmt to fix CI format:check failure on PR #35847.

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

* fix(line): add shouldLogVerbose to globals mock in bot-handlers test

resolveAgentRoute calls shouldLogVerbose() from globals.js; the mock
was missing this export, causing 13 test failures.

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

* Address review findings for #35847

---------

Co-authored-by: Kaiyi <me@kaiyi.cool>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Yi-Cheng Wang <yicheng.wang@heph-ai.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-07 14:06:07 -06:00
Josh Avant
0e4245063f
CLI: make read-only SecretRef status flows degrade safely (#37023)
* CLI: add read-only SecretRef inspection

* CLI: fix read-only SecretRef status regressions

* CLI: preserve read-only SecretRef status fallbacks

* Docs: document read-only channel inspection hook

* CLI: preserve audit coverage for read-only SecretRefs

* CLI: fix read-only status account selection

* CLI: fix targeted gateway fallback analysis

* CLI: fix Slack HTTP read-only inspection

* CLI: align audit credential status checks

* CLI: restore Telegram read-only fallback semantics
2026-03-05 23:07:13 -06:00
Peter Steinberger
ad8d766f65 refactor(extensions): dedupe channel config, onboarding, and monitors 2026-03-02 08:54:20 +00:00
Peter Steinberger
0183610db3 refactor: de-duplicate channel runtime and payload helpers 2026-02-23 21:25:28 +00:00
LI SHANXIN
c1b75ab8e2
fix(telegram): make reaction handling soft-fail and message-id resilient (#20236)
* Telegram: soft-fail reactions and fallback to inbound message id

* Telegram: soft-fail missing reaction message id

* Update CHANGELOG.md

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-02-23 10:25:14 -05:00
Vincent Koc
89a1e99815
fix(slack): finalize replyToMode off threading behavior (#23799)
* fix: make replyToMode 'off' actually prevent threading in Slack

Three independent bugs caused Slack replies to always create threads
even when replyToMode was set to 'off':

1. Typing indicator created threads via statusThreadTs fallback (#16868)
   - resolveSlackThreadTargets fell back to messageTs for statusThreadTs
   - 'is typing...' was posted as thread reply, creating a thread
   - Fix: remove messageTs fallback, let statusThreadTs be undefined

2. [[reply_to_current]] tags bypassed replyToMode entirely (#16080)
   - Slack dock had allowExplicitReplyTagsWhenOff: true
   - Reply tags from system prompt always threaded regardless of config
   - Fix: set allowExplicitReplyTagsWhenOff to false for Slack

3. Contradictory replyToMode defaults in codebase (#20827)
   - monitor/provider.ts defaulted to 'all'
   - accounts.ts defaulted to 'off' (matching docs)
   - Fix: align provider.ts default to 'off' per documentation

Fixes: openclaw/openclaw#16868, openclaw/openclaw#16080, openclaw/openclaw#20827

* fix(slack): respect replyToMode in DMs even with typing indicator thread

When replyToMode is 'off' in DMs, replies should stay in the main
conversation even when the typing indicator creates a thread context.

Previously, when incomingThreadTs was set (from the typing indicator's
thread), replyToMode was forced to 'all', causing all replies to go
into the thread.

Now, for direct messages, the user's configured replyToMode is always
respected. For channels/groups, the existing behavior is preserved
(stay in thread if already in one).

This fix:
- Keeps the typing indicator working (statusThreadTs fallback preserved)
- Prevents DM replies from being forced into threads
- Maintains channel thread continuity

Fixes #16868

* refactor(slack): eliminate redundant resolveSlackThreadContext call

- Add isThreadReply to resolveSlackThreadTargets return value
- Remove duplicate call in dispatch.ts
- Addresses greptile review feedback with cleaner DRY approach

* docs(slack): add JSDoc to resolveSlackThreadTargets

Document return values including isThreadReply distinction between
genuine user thread replies vs bot status message thread context.

* docs(changelog): record Slack replyToMode off threading fixes

---------

Co-authored-by: James <jamesrp13@gmail.com>
Co-authored-by: theoseo <suhong.seo@gmail.com>
2026-02-22 13:27:50 -05:00
Peter Steinberger
66f814a0af refactor(channels): dedupe plugin routing and channel helpers 2026-02-22 14:08:51 +00:00
Peter Steinberger
75c1bfbae8 refactor(channels): dedupe message routing and telegram helpers 2026-02-22 07:44:57 +00:00
Peter Steinberger
ad1c07e7c0 refactor: eliminate remaining duplicate blocks across draft streams and tests 2026-02-22 07:44:57 +00:00
Kirill Shchetynin
ee519086f6
Feature/default messenger delivery target (openclaw#16985) thanks @KirillShchetinin
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: KirillShchetinin <13061871+KirillShchetinin@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-02-19 22:37:19 -06:00
Peter Steinberger
1f5cd65d60 refactor(channels): share case-insensitive account lookup in dock 2026-02-18 19:04:57 +00:00
Peter Steinberger
b8b43175c5 style: align formatting with oxfmt 0.33 2026-02-18 01:34:35 +00:00
Peter Steinberger
31f9be126c style: run oxfmt and fix gate failures 2026-02-18 01:29:02 +00:00
Josh Avant
b20339a232
fix(signal): canonicalize message targets in tool and inbound flows 2026-02-17 14:17:22 -08:00
Sebastian
dff8692613 fix(discord): normalize command allowFrom prefixes 2026-02-17 08:45:41 -05:00
cpojer
d0cb8c19b2
chore: wtf. 2026-02-17 13:36:48 +09:00
Sebastian
ed11e93cf2 chore(format) 2026-02-16 23:20:16 -05:00
cpojer
01ea808876
chore: Format files. 2026-02-17 10:57:31 +09:00
Peter Steinberger
2992639f88 Revert "feat: add Linq channel — real iMessage via API, no Mac required"
This reverts commit d4a142fd8f1cc2e2d5f634c919a20cc9bf864475.
2026-02-17 02:30:55 +01:00
cpojer
90ef2d6bdf
chore: Update formatting. 2026-02-17 09:18:40 +09:00
Clawdbot
1fca7c3928 fix(discord): strip user:/discord:/pk: prefixes in command allowFrom
Discord's formatAllowFrom now strips these prefixes before matching,
aligning with normalizeDiscordAllowList behavior used in DM admission.

Before: commands.allowFrom: ["user:123"] → no match (senderCandidates: ["123", "discord:123"])
After: commands.allowFrom: ["user:123"] → "123" → matches sender "123"

Fixes #17937
2026-02-17 00:00:30 +01:00
George McCain
d4a142fd8f feat: add Linq channel — real iMessage via API, no Mac required
Adds a complete Linq iMessage channel adapter that replaces the existing
iMessage channel's Mac Mini + dedicated Apple ID + SSH wrapper + Full Disk
Access setup with a single API key and phone number.

Core implementation (src/linq/):
- types.ts: Linq webhook event and message types
- accounts.ts: Multi-account resolution from config (env/file/inline token)
- send.ts: REST outbound via Linq Blue V3 API (messages, typing, reactions)
- probe.ts: Health check via GET /v3/phonenumbers
- monitor.ts: Webhook HTTP server with HMAC-SHA256 signature verification,
  replay protection, inbound debouncing, and full dispatch pipeline integration

Extension plugin (extensions/linq/):
- ChannelPlugin implementation with config, security, setup, outbound,
  gateway, and status adapters
- Supports direct and group chats, reactions, and media

Wiring:
- Channel registry, dock, config schema, plugin-sdk exports, and plugin
  runtime all updated to include the new linq channel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:52:56 +01:00
Peter Steinberger
d9c891eb90 refactor(channels): share threading tool context 2026-02-15 18:30:34 +00:00
Peter Steinberger
cf04208cb9 fix(allowlist): canonicalize Slack/Discord allowFrom 2026-02-15 03:46:16 +01:00
Peter Steinberger
ef70a55b7a
refactor(reply): clarify explicit reply tags in off mode (#16189)
* refactor(reply): clarify explicit reply tags in off mode

* fix(plugin-sdk): alias account-id subpath for extensions
2026-02-14 14:15:37 +01:00
Pejman Pour-Moezzi
9475791d98 fix: update remaining replyToMode "first" defaults to "off"
- src/channels/dock.ts: core channel dock fallback
- src/auto-reply/reply/reply-routing.test.ts: test expectation
- docs/zh-CN/channels/telegram.md: Chinese docs reference

Comprehensive grep confirms no remaining Telegram-specific "first"
defaults after this commit.
2026-02-13 23:31:17 -08:00
Vignesh
fa906b26ad
feat: IRC — add first-class channel support
Adds IRC as a first-class channel with core config surfaces (schema/hints/dock), plugin auto-enable detection, routing/policy alignment, and docs/tests.

Co-authored-by: Vignesh <vigneshnatarajan92@gmail.com>
2026-02-10 17:33:57 -06:00
Peter Steinberger
53273b490b fix(auto-reply): prevent sender spoofing in group prompts 2026-02-10 00:44:38 -06:00
max
ec910a235e
refactor: consolidate duplicate utility functions (#12439)
* refactor: consolidate duplicate utility functions

- Add escapeRegExp to src/utils.ts and remove 10 local duplicates
- Rename bash-tools clampNumber to clampWithDefault (different signature)
- Centralize formatError calls to use formatErrorMessage from infra/errors.ts
- Re-export formatErrorMessage from cli/cli-utils.ts to preserve API

* refactor: consolidate remaining escapeRegExp duplicates

* refactor: consolidate sleep, stripAnsi, and clamp duplicates
2026-02-08 23:59:43 -08:00
ironbyte-rgb
02842bef91
fix(slack): add mention stripPatterns for /new and /reset commands (#9971)
* fix(slack): add mention stripPatterns for /new and /reset commands

Fixes #9937

The Slack dock was missing mentions.stripPatterns that Discord has.
This caused /new and /reset to fail when sent with a mention
(e.g. @bot /reset) because <@USERID> wasn't stripped before matching.

* fix(slack): strip mentions for /new and /reset (#9971) (thanks @ironbyte-rgb)

---------

Co-authored-by: ironbyte-rgb <amontaboi76@gmail.com>
Co-authored-by: George Pickett <gpickett00@gmail.com>
2026-02-05 16:29:07 -08:00
cpojer
f06dd8df06
chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cpojer
5ceff756e1
chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
Peter Steinberger
9a7160786a refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
Peter Steinberger
6d16a658e5 refactor: rename clawdbot to moltbot with legacy compat 2026-01-27 12:21:02 +00:00
iHildy
b76cd6695d feat: add beta googlechat channel 2026-01-24 23:30:45 +00:00
Adam Holt
c07949a99c Channels: add per-group tool policies 2026-01-24 05:49:39 +00:00
Stefan Galescu
7b40d1b261
feat(slack): add dm-specific replyToMode configuration (#1442)
Adds support for separate replyToMode settings for DMs vs channels:

- Add channels.slack.dm.replyToMode for DM-specific threading
- Keep channels.slack.replyToMode as default for channels
- Add resolveSlackReplyToMode helper to centralize logic
- Pass chatType through threading resolution chain

Usage:
```json5
{
  channels: {
    slack: {
      replyToMode: "off",     // channels
      dm: {
        replyToMode: "all"    // DMs always thread
      }
    }
  }
}
```

When dm.replyToMode is set, DMs use that mode; channels use the
top-level replyToMode. Backward compatible when not configured.
2026-01-23 05:13:23 +00:00
Peter Steinberger
0f7f7bb95f fix: msteams attachments + plugin prompt hints
Co-authored-by: Christof <10854026+Evizero@users.noreply.github.com>
2026-01-22 03:37:29 +00:00
Peter Steinberger
45c1ccdfcf refactor: unify threading contexts 2026-01-21 20:35:12 +00:00
Peter Steinberger
9a2bf57e1c refactor: extend channel plugin boundary 2026-01-20 12:07:54 +00:00
Tyler Yust
1eab8fa9b0 Step 5 + Review 2026-01-20 12:07:54 +00:00
Peter Steinberger
ee6e534ccb refactor: route channel runtime via plugin api 2026-01-18 11:01:16 +00:00
Peter Steinberger
d9f9e93dee feat!: move msteams to plugin 2026-01-16 02:59:43 +00:00
Peter Steinberger
725a6b71dc feat: add matrix channel plugin 2026-01-15 08:40:37 +00:00
Peter Steinberger
2b4a68e276 feat: load channel plugins 2026-01-15 02:42:44 +00:00
Peter Steinberger
c379191f80 chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
2026-01-14 15:02:19 +00:00
Peter Steinberger
90342a4f3a refactor!: rename chat providers to channels 2026-01-13 08:40:39 +00:00