The group-mentions ack gate returned false whenever a group did not require mentions, conflating group policy with whether this message mentioned the agent. Under the default scope, mentioning the agent in a group configured to answer everything produced no ack at all, so the user had no signal the turn was picked up until the reply arrived.
Behavior change on a default path: those groups now show the 👀 ack (and the lifecycle status reactions when messages.statusReactions.enabled is true) on mentions. Mention-required groups, group-all, unmentioned messages, and off/none are unchanged. The gate no longer reads requireMention, so the parameter is gone from the shared type and all channel call sites.
Proven live on Telegram across three configurations, including a no-mention control confirming group-mentions did not become group-all.
A status headline replaced the rolling tool lines instead of sitting above
them, so a default Discord draft showed one preamble sentence for an entire
tool-heavy turn. Operators reached for `/verbose` to see any activity, which
delivers durable per-tool-call messages and floods the channel.
- Render the headline above the lines; both stay visible in one message.
- Shorten the start gate from 5s to 1.5s. The gate only creates the draft
when the timer fires and finalize cancels it, so quick answers still post
no draft while a 3s tool turn stops being silent.
- Drop Discord's label-gated tool-progress default so
resolveChannelStreamingPreviewToolProgress is the single owner. An explicit
`toolProgress: false` still silences the lines.
- Resolve that toggle against a "progress" mode guess when `streaming.mode`
is unset, so the progress-draft channels stop ignoring an explicit
`progress.toolProgress` opt-out.
Telegram now defaults to `streaming.mode: "progress"` like Discord; set
`"partial"` to keep streamed answer text. Its renderer draws work lines from
the compositor's structured lines, so `rendersRollingLinesNatively` keeps
them out of the composed text rather than printing every line twice.
Restore the explicitly shipped Matrix approval mode without changing omitted, boolean, invalid, or non-strict configuration behavior. Regenerate the canonical channel metadata and prove native Matrix approvals against a real homeserver.
Co-authored-by: mingdideng <deng.mingdi@xydigit.com>
Fixes#101420. Preserve Matrix-native JSON fields while projecting readable message and pin tables. Apply only valid same-sender edits, honor homeserver replacement aggregates, and preserve cross-page updates, redactions, and original thread relationships.
* feat(matrix): add configurable apiPrefix for non-standard homeserver API paths
* fix(matrix): remove public apiPrefix config, keep transport path fix
The apiPrefix config surface was incomplete: it was not carried through
resolveMatrixConfigForAccount, MatrixAuth, shared client keying, or
createMatrixClient, making it a no-op in normal runtime paths.
Following ClawSweeper review direction, this narrow fix:
- Removes apiPrefix from MatrixConfigSchema and MatrixConfig types
- Keeps apiPrefix as a private internal constant in MatrixAuthedHttpClient
for bare-path resolution (DEFAULT_API_PREFIX = /_matrix/client/v3)
- Stops MatrixClient from accepting/passing apiPrefix
- Retains the transport.ts normalizeEndpoint() fix for homeserver URLs
behind reverse proxies (avoids losing path segments on trailing-slash
mismatches)
Test: 1393 tests pass across 121 matrix extension test files.
* fix(matrix): ensure homeserver URL ends with slash for new URL() resolution
Without a trailing slash, new URL(relPath, homeserver) treats the final
path segment as a filename, losing the reverse-proxy prefix path.
For example:
new URL('_matrix/...', 'https://host/proxy')
-> https://host/_matrix/... (wrong, 'proxy' dropped)
With trailing slash:
new URL('_matrix/...', 'https://host/proxy/')
-> https://host/proxy/_matrix/... (correct)
* test(matrix): add URL resolution coverage for path-prefixed homeservers
* fix(matrix): preserve reverse-proxy homeserver paths
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* build(deps): remove npm shrinkwrap; mirror pnpm lock into transient package locks
npm 12 removed shrinkwrap (command + tarball/root loading). Delete all 82
committed npm-shrinkwrap.json files and stop publishing lockfiles; keep
pnpm-lock.yaml as the single reviewed dependency boundary. The generator
becomes scripts/generate-npm-package-lock.mjs and feeds plugin bundling via
a transient package-lock.json + npm ci (works on npm 11 and 12). Tarball
validation treats the published 2026.7.2 beta train as a shrinkwrap
transition; self-update npm detection now uses install topology instead of
the shipped shrinkwrap.
* fix(deps): repair lint, deadcode, and test-type lanes for the npm 12 migration
- sort integrity comparisons with an explicit comparator (oxlint)
- keep resolveBunGlobalNodeModules module-local (knip unused-export gate)
- model npm pack --json as npm<=11 array / npm 12 name-keyed object
- default calver destructuring in the tarball test fixture
Replace non-existent 'openclaw plugin add' with the correct
'openclaw plugins install' command in 14 extension README files.
The CLI only registers 'openclaw plugins install' (src/cli/plugins-cli.ts),
and the previous command would fail for users following the docs.
Co-authored-by: hilbert <xuxiaojing@tojoy.com>
* refactor(channels): remove flat streaming compat
maintainer-approved early removal of v2026.7.2-gated compat
* refactor(channels): remove group intro hint adapter
maintainer-approved early removal of v2026.7.2-gated compat
Plugin SDK surface baseline update is maintainer-approved for this intentional removal.