@openclaw/matrix 2026.9.2 → 2026.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/{account-selection-DA-jfx22.js → account-selection-Bbtc483D.js} +9 -1
  2. package/dist/{accounts-DR1c4xF_.js → accounts-GwSAk9vY.js} +2 -2
  3. package/dist/api.js +6 -6
  4. package/dist/{approval-handler.runtime-BJCD4dLf.js → approval-handler.runtime-tJLn5JFB.js} +6 -6
  5. package/dist/{approval-ids-Bst7HM_o.js → approval-ids-DJZ9ZTuS.js} +1 -1
  6. package/dist/{approval-reaction-auth-DhH8QOSe.js → approval-reaction-auth-Cd0sKHFc.js} +2 -2
  7. package/dist/{channel-Bs8VLb6q.js → channel-BpYiqmx-.js} +10 -39
  8. package/dist/channel-plugin-api.js +1 -1
  9. package/dist/{channel.runtime-CCJRhdH5.js → channel.runtime-dfEvRdLQ.js} +6 -11
  10. package/dist/{channel.setup-DhmDXwPp.js → channel.setup-oxd8RsIr.js} +3 -3
  11. package/dist/{cli-IvDUuiDH.js → cli-_49Vsqs4.js} +9 -9
  12. package/dist/{cli-metadata-BGryAl2e.js → cli-metadata-D19lmKmz.js} +1 -1
  13. package/dist/cli-metadata.js +1 -1
  14. package/dist/{client-oNOlldJI.js → client-BXQCQDfY.js} +2 -2
  15. package/dist/{client-Dj4mcf-s.js → client-COLiUdWe.js} +6 -6
  16. package/dist/{client-bootstrap-n1Rqc8Go.js → client-bootstrap-CQwf9qrm.js} +1 -6
  17. package/dist/contract-api.js +2 -2
  18. package/dist/{credentials-DJj2xs3q.js → credentials-DysXbkv2.js} +2 -2
  19. package/dist/{credentials-read-mexhw-Ur.js → credentials-read-WWpqi88V.js} +1 -1
  20. package/dist/{credentials-write.runtime-DQt-kgJq.js → credentials-write.runtime-D22lPwRO.js} +1 -1
  21. package/dist/{crypto-runtime-m1eplj3b.js → crypto-runtime-BvunIYVn.js} +2 -2
  22. package/dist/{crypto-snapshot-doctor.runtime-D0v841D_.js → crypto-snapshot-doctor.runtime-DxgUMXUy.js} +2 -2
  23. package/dist/{directory-live-DLUgWBhA.js → directory-live-DABCxf8j.js} +2 -2
  24. package/dist/doctor-contract-api.js +41 -21
  25. package/dist/{draft-stream-DglwxWzJ.js → draft-stream-DSwgyyBi.js} +16 -5
  26. package/dist/{encryption-guidance-BNcZNQZI.js → encryption-guidance-mDyxJV9U.js} +1 -1
  27. package/dist/{event-helpers-XRfAbOIh.js → event-helpers-CspuhE9k.js} +9 -1
  28. package/dist/helper-api.js +3 -3
  29. package/dist/{http-client-DOmFvKvB.js → http-client-BfPeF4CE.js} +1 -1
  30. package/dist/{idb-persistence-CU7CNLlX.js → idb-persistence-DBdwHSWg.js} +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/{messages-Czn8lNEh.js → messages-H4mi9Cap.js} +6 -99
  33. package/dist/{monitor-DouG43FJ.js → monitor-3Fw96uiE.js} +61 -92
  34. package/dist/{outbound-Co_tJyE6.js → outbound-UPI45TD_.js} +1 -1
  35. package/dist/plugin-entry.handlers.runtime.js +1 -1
  36. package/dist/probe.runtime-DdXTrrmo.js +2 -0
  37. package/dist/{profile-update-CAl8nZNG.js → profile-update-DWEg8Ylt.js} +1 -1
  38. package/dist/{reaction-events-C_7G7bvI.js → reaction-events-D-iSW0iM.js} +5 -7
  39. package/dist/{resolve-targets-B64O69Nd.js → resolve-targets-BpnALDzR.js} +1 -1
  40. package/dist/{resolver.runtime-TRmePJDV.js → resolver.runtime-B83WkznZ.js} +1 -1
  41. package/dist/{room-info-6viLR3NH.js → room-info-CjnbX52D.js} +7 -4
  42. package/dist/runtime-api.js +2 -2
  43. package/dist/{sdk-C1yfda1L.js → sdk-CX9b0N8Q.js} +13 -6
  44. package/dist/{send-B5XChnvB.js → send-B9l1lKau.js} +196 -88
  45. package/dist/session-binding-contract-api.js +1 -1
  46. package/dist/{setup-bootstrap-S_loyUyM.js → setup-bootstrap-CSI1L1lm.js} +2 -2
  47. package/dist/{setup-core-XkIfQ65J.js → setup-core-DuTlyqRz.js} +3 -3
  48. package/dist/setup-plugin-api.js +1 -1
  49. package/dist/{setup-surface-B2yZ8KGc.js → setup-surface-fZing1WZ.js} +6 -6
  50. package/dist/{startup-verification-1Ney1mmI.js → startup-verification-BTSf31hS.js} +2 -1
  51. package/dist/storage-CV-pfV_2.js +320 -0
  52. package/dist/{storage-BVf4uucD.js → storage-metadata-DYArLcq1.js} +14 -319
  53. package/dist/{storage-paths-gUmSydsW.js → storage-paths-DVCANXTc.js} +13 -1
  54. package/dist/{sync-cache-state-d-A_OhbU.js → sync-cache-state-C-mhj3xb.js} +9 -3
  55. package/dist/{thread-bindings-BkBnn4te.js → thread-bindings-CRyf5on_.js} +3 -2
  56. package/dist/{tool-actions.runtime-a5L5xGSP.js → tool-actions.runtime-D5-hTkDu.js} +10 -10
  57. package/dist/types-DzSc7Sqm.js +32 -0
  58. package/dist/{verification-XJtTc5DI.js → verification-B_aqtbx-.js} +2 -2
  59. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/package.json +1 -1
  60. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm.d.ts +69 -4
  61. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.cjs +526 -432
  62. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.js +358 -265
  63. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.wasm +0 -0
  64. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.wasm.d.ts +8 -7
  65. package/openclaw.plugin.json +23 -1
  66. package/package.json +5 -5
  67. package/dist/probe.runtime-B1YPxG9x.js +0 -2
  68. package/dist/runtime-BefyhPWv.js +0 -6
@@ -2,24 +2,28 @@ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
2
  import { a as resolveMatrixAccountConfig } from "./account-config-CRsKoMqJ.js";
3
3
  import { t as getMatrixRuntime } from "./runtime-6S3DNFNv.js";
4
4
  import { i as normalizeMatrixResolvableTarget, t as isMatrixQualifiedUserId } from "./target-ids-Nwx7cMVE.js";
5
- import { n as MATRIX_REACTION_EVENT_TYPE, r as buildMatrixReactionContent, t as MATRIX_ANNOTATION_RELATION_TYPE } from "./reaction-common-DkrQdBSZ.js";
6
5
  import { a as isStrictDirectRoom, r as inspectMatrixDirectRoomEvidence } from "./direct-room-RinHjtqX.js";
6
+ import { r as buildMatrixReactionContent } from "./reaction-common-DkrQdBSZ.js";
7
+ import { a as RelationType, i as MsgType, r as MSC4357_LIVE_KEY, t as EventType } from "./types-DzSc7Sqm.js";
8
+ import { n as getMatrixEventProjection } from "./event-helpers-CspuhE9k.js";
7
9
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
8
10
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
9
- import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
11
+ import { asNullableObjectRecord, asNullableRecord, asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
10
12
  import { FormatCapabilityProfile, convertMarkdownTables, findCodeRegions, isInsideCode, markdownToIR, renderMarkdownWithMarkers, tokenizeHtmlTags } from "openclaw/plugin-sdk/text-chunking";
11
13
  import { createHash } from "node:crypto";
14
+ import path from "node:path";
12
15
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
13
16
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
14
17
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
15
18
  import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
19
+ import { M_POLL_KIND_DISCLOSED } from "matrix-js-sdk/lib/@types/polls.js";
16
20
  import { normalizePollInput } from "openclaw/plugin-sdk/poll-runtime";
17
21
  import MarkdownIt from "markdown-it";
18
22
  import { isAutoLinkedFileRef } from "openclaw/plugin-sdk/text-autolink-runtime";
19
23
  import { isVoiceMessageCompatibleAudio } from "openclaw/plugin-sdk/media-runtime";
20
24
  import { parseBuffer } from "music-metadata";
21
25
  //#region extensions/matrix/src/matrix/send/client.ts
22
- const loadMatrixSendClientRuntime = createLazyRuntimeModule(() => import("./client-bootstrap-n1Rqc8Go.js").then((n) => n.t));
26
+ const loadMatrixSendClientRuntime = createLazyRuntimeModule(() => import("./client-bootstrap-CQwf9qrm.js").then((n) => n.t));
23
27
  function resolveMediaMaxBytes(accountId, cfg) {
24
28
  if (!cfg) throw new Error("Matrix media limits requires a resolved runtime config. Load and resolve config at the command or gateway boundary, then pass cfg through the runtime path.");
25
29
  const resolvedCfg = requireRuntimeConfig(cfg, "Matrix media limits");
@@ -47,36 +51,6 @@ async function withResolvedMatrixClient(opts, run, shutdownBehavior) {
47
51
  return await withResolvedRuntimeMatrixClient(opts, run, shutdownBehavior);
48
52
  }
49
53
  //#endregion
50
- //#region extensions/matrix/src/matrix/send/types.ts
51
- const MsgType = {
52
- Text: "m.text",
53
- Image: "m.image",
54
- Audio: "m.audio",
55
- Video: "m.video",
56
- File: "m.file",
57
- Notice: "m.notice"
58
- };
59
- const RelationType = {
60
- Annotation: MATRIX_ANNOTATION_RELATION_TYPE,
61
- Replace: "m.replace",
62
- Thread: "m.thread"
63
- };
64
- const EventType = {
65
- Direct: "m.direct",
66
- Reaction: MATRIX_REACTION_EVENT_TYPE,
67
- RoomMessage: "m.room.message"
68
- };
69
- const MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY = "com.openclaw.finalized_preview";
70
- /**
71
- * MSC4357 live marker key.
72
- * When present on event content, signals that the message is still being
73
- * streamed (e.g. an LLM generating a response). Supporting clients render
74
- * the message with a streaming animation until an edit without this marker
75
- * arrives, indicating the stream is complete.
76
- * @see https://github.com/matrix-org/matrix-spec-proposals/pull/4357
77
- */
78
- const MSC4357_LIVE_KEY = "org.matrix.msc4357.live";
79
- //#endregion
80
54
  //#region extensions/matrix/src/matrix/direct-management.ts
81
55
  var direct_management_exports = /* @__PURE__ */ __exportAll({
82
56
  inspectMatrixDirectRooms: () => inspectMatrixDirectRooms,
@@ -659,7 +633,7 @@ function parsePollStart(content) {
659
633
  return {
660
634
  question,
661
635
  answers,
662
- kind: poll.kind ?? "m.poll.disclosed",
636
+ kind: M_POLL_KIND_DISCLOSED.matches(poll.kind ?? "m.poll.disclosed") ? "m.poll.disclosed" : "m.poll.undisclosed",
663
637
  maxSelections: Math.min(Math.max(maxSelections, 1), answers.length)
664
638
  };
665
639
  }
@@ -816,6 +790,34 @@ function buildPollResponseContent(pollEventId, answerIds) {
816
790
  };
817
791
  }
818
792
  //#endregion
793
+ //#region extensions/matrix/src/matrix/relations.ts
794
+ function relatedReplyEventId(relation) {
795
+ const reply = asOptionalRecord(relation?.["m.in_reply_to"]);
796
+ return typeof reply?.event_id === "string" ? reply.event_id : void 0;
797
+ }
798
+ function buildMatrixMessageRelation(params) {
799
+ const threadId = params.threadId?.trim();
800
+ const replyToId = params.replyToId?.trim();
801
+ const relatedId = replyToId || (threadId ? params.fallbackReplyToId?.trim() : void 0);
802
+ const reply = relatedId ? { "m.in_reply_to": { event_id: relatedId } } : void 0;
803
+ if (!threadId) return reply;
804
+ return {
805
+ rel_type: RelationType.Thread,
806
+ event_id: threadId,
807
+ ...reply,
808
+ ...relatedId && !replyToId ? { is_falling_back: true } : {}
809
+ };
810
+ }
811
+ function resolveMatrixReplyToEventId(content) {
812
+ const relation = asOptionalRecord(content["m.relates_to"]);
813
+ return relation?.rel_type === RelationType.Thread && relation.is_falling_back === true ? void 0 : relatedReplyEventId(relation);
814
+ }
815
+ function resolveMatrixThreadRootId(content) {
816
+ const relation = asOptionalRecord(content["m.relates_to"]);
817
+ if (relation?.rel_type !== RelationType.Thread) return;
818
+ return typeof relation.event_id === "string" ? relation.event_id : relatedReplyEventId(relation);
819
+ }
820
+ //#endregion
819
821
  //#region extensions/matrix/src/matrix/format-profile.ts
820
822
  function createMatrixPrivateMarkers(markdown, exhaustedMessage) {
821
823
  const used = new Set(Array.from(markdown, (character) => character.charCodeAt(0)));
@@ -854,15 +856,7 @@ function isMarkdownEscaped(markdown, index) {
854
856
  return slashCount % 2 === 1;
855
857
  }
856
858
  function projectMatrixMarkdown(markdown) {
857
- const normalized = (markdown ?? "").replace(/\r\n?/gu, "\n");
858
- return renderMarkdownWithMarkers({
859
- text: normalized,
860
- styles: [],
861
- links: []
862
- }, {
863
- styleMarkers: {},
864
- escapeText: (text) => text
865
- }, MATRIX_FORMAT_PROFILE);
859
+ return (markdown ?? "").replace(/\r\n?/gu, "\n");
866
860
  }
867
861
  function renderMatrixMarkdownTables(markdown, mode) {
868
862
  return MATRIX_FORMAT_PROFILE.constructs.table === "native" && (mode === "off" || mode === "block") ? markdown : convertMarkdownTables(markdown, mode);
@@ -1010,6 +1004,7 @@ function findMatrixMarkdownMetadataRanges(markdown) {
1010
1004
  }
1011
1005
  function findMatrixSpoilerDelimiterOffsets(markdown) {
1012
1006
  const projected = projectMatrixMarkdown(markdown);
1007
+ if (!projected.includes("||")) return [];
1013
1008
  const tokens = spoilerParser.parse(projected, {});
1014
1009
  const lineStarts = [0];
1015
1010
  for (let index = 0; index < projected.length; index += 1) if (projected[index] === "\n") lineStarts.push(index + 1);
@@ -1042,6 +1037,7 @@ function findMatrixSpoilerDelimiterOffsets(markdown) {
1042
1037
  }
1043
1038
  function hasMatrixSpoilerMetadataCollision(markdown) {
1044
1039
  const projected = projectMatrixMarkdown(markdown);
1040
+ if (!projected.includes("||")) return false;
1045
1041
  const ordinary = new Set(findMatrixSpoilerDelimiterOffsets(projected));
1046
1042
  const underlineTags = [...tokenizeHtmlTags(projected)].filter((tag) => (tag.name === "u" || tag.name === "ins") && !isMarkdownEscaped(projected, tag.start));
1047
1043
  const literalRanges = [...findMatrixTableSourceRanges(projected), ...findCodeRegions(projected).filter((code) => !underlineTags.some((tag) => code.start > tag.start && code.start < tag.end))];
@@ -1656,6 +1652,144 @@ function chunkMatrixText(text, opts) {
1656
1652
  };
1657
1653
  }
1658
1654
  //#endregion
1655
+ //#region extensions/matrix/src/matrix/media-text.ts
1656
+ const MATRIX_MEDIA_KINDS = {
1657
+ "m.audio": "audio",
1658
+ "m.file": "file",
1659
+ "m.image": "image",
1660
+ "m.sticker": "sticker",
1661
+ "m.video": "video"
1662
+ };
1663
+ function resolveMatrixMediaKind(msgtype) {
1664
+ return MATRIX_MEDIA_KINDS[msgtype ?? ""] ?? null;
1665
+ }
1666
+ function resolveMatrixMediaLabel(kind, fallback = "media") {
1667
+ return `${kind ?? fallback} attachment`;
1668
+ }
1669
+ function formatMatrixAttachmentMarker(params) {
1670
+ const label = resolveMatrixMediaLabel(params.kind);
1671
+ if (params.tooLarge) return `[matrix ${label} too large]`;
1672
+ return params.unavailable ? `[matrix ${label} unavailable]` : `[matrix ${label}]`;
1673
+ }
1674
+ function isLikelyBareFilename(text) {
1675
+ const trimmed = text.trim();
1676
+ if (!trimmed || trimmed.includes("\n") || /\s/.test(trimmed)) return false;
1677
+ if (path.basename(trimmed) !== trimmed) return false;
1678
+ return path.extname(trimmed).length > 1;
1679
+ }
1680
+ function resolveCaptionOrFilename(params) {
1681
+ const body = params.body?.trim() ?? "";
1682
+ const filename = params.filename?.trim() ?? "";
1683
+ if (filename) {
1684
+ if (!body || body === filename) return { filename };
1685
+ return {
1686
+ caption: body,
1687
+ filename
1688
+ };
1689
+ }
1690
+ if (!body) return {};
1691
+ if (isLikelyBareFilename(body)) return { filename: body };
1692
+ return { caption: body };
1693
+ }
1694
+ function resolveMatrixReplacementContent(event, replacementEvent = event.unsigned?.["m.relations"]?.["m.replace"]) {
1695
+ return resolveMatrixReplacement(event, replacementEvent)?.content;
1696
+ }
1697
+ function resolveMatrixReplacement(event, replacementEvent = event.unsigned?.["m.relations"]?.["m.replace"]) {
1698
+ const replacement = asNullableObjectRecord(replacementEvent);
1699
+ if (!replacement || event.state_key !== void 0 || event.unsigned?.redacted_because) return;
1700
+ const content = asNullableObjectRecord(replacement.content);
1701
+ const relation = asNullableObjectRecord(content?.["m.relates_to"]);
1702
+ const unreadable = getMatrixEventProjection(replacement)?.decryptionFailure === true || replacement.type === "m.room.encrypted";
1703
+ if (replacement.sender !== event.sender || !unreadable && replacement.type !== event.type || replacement.state_key !== void 0 || asNullableObjectRecord(replacement.unsigned)?.redacted_because || !relation || relation.rel_type !== "m.replace" || relation.event_id !== event.event_id) return;
1704
+ if (unreadable) return { kind: "unreadable" };
1705
+ const newContent = asNullableRecord(content?.["m.new_content"]);
1706
+ return newContent ? {
1707
+ kind: "content",
1708
+ content: newContent
1709
+ } : void 0;
1710
+ }
1711
+ function resolveMatrixMessageAttachment(params) {
1712
+ const kind = resolveMatrixMediaKind(params.msgtype);
1713
+ if (!kind) return;
1714
+ const resolved = resolveCaptionOrFilename(params);
1715
+ return {
1716
+ kind,
1717
+ caption: resolved.caption,
1718
+ filename: resolved.filename
1719
+ };
1720
+ }
1721
+ function formatMatrixAttachmentText(params) {
1722
+ if (!params.attachment) return;
1723
+ return formatMatrixAttachmentMarker({
1724
+ kind: params.attachment.kind,
1725
+ tooLarge: params.tooLarge,
1726
+ unavailable: params.unavailable
1727
+ });
1728
+ }
1729
+ function formatMatrixMessageText(params) {
1730
+ const attachment = resolveMatrixMessageAttachment(params);
1731
+ const body = attachment ? attachment.caption ?? "" : params.body?.trim() ?? "";
1732
+ const marker = formatMatrixAttachmentText({
1733
+ attachment,
1734
+ tooLarge: params.tooLarge,
1735
+ unavailable: params.unavailable
1736
+ });
1737
+ if (!marker) return body || void 0;
1738
+ if (!body) return marker;
1739
+ return `${body}\n\n${marker}`;
1740
+ }
1741
+ function formatMatrixMediaUnavailableText(params) {
1742
+ return formatMatrixMessageText({
1743
+ ...params,
1744
+ unavailable: true
1745
+ }) ?? "";
1746
+ }
1747
+ function formatMatrixMediaTooLargeText(params) {
1748
+ return formatMatrixMessageText({
1749
+ ...params,
1750
+ tooLarge: true
1751
+ }) ?? "";
1752
+ }
1753
+ //#endregion
1754
+ //#region extensions/matrix/src/matrix/send/edit-content.ts
1755
+ const MAX_EDIT_RELATION_PAGES = 100;
1756
+ const EDIT_RELATION_PAGE_SIZE = 100;
1757
+ const EDIT_DECRYPTION_ERROR = "Matrix edit history is not fully decrypted; restore encryption keys before editing.";
1758
+ async function resolveMatrixEditContent(params) {
1759
+ const { client, roomId, event } = params;
1760
+ if (!event || event.unsigned?.redacted_because || event.state_key !== void 0) return event?.content;
1761
+ const projection = getMatrixEventProjection(event);
1762
+ if (projection?.decryptionFailure || event.type === "m.room.encrypted") throw new Error(EDIT_DECRYPTION_ERROR);
1763
+ const originalContent = projection?.originalContent ?? event.content;
1764
+ const embedded = resolveMatrixReplacementContent(event) ?? asNullableObjectRecord(originalContent?.["m.new_content"]);
1765
+ if (embedded) return embedded;
1766
+ let latest;
1767
+ let latestReplacement;
1768
+ let from;
1769
+ const seenCursors = /* @__PURE__ */ new Set();
1770
+ for (let pageIndex = 0; pageIndex < MAX_EDIT_RELATION_PAGES; pageIndex++) {
1771
+ const page = await client.getRelations(roomId, event.event_id, "m.replace", void 0, {
1772
+ from,
1773
+ limit: EDIT_RELATION_PAGE_SIZE
1774
+ });
1775
+ for (const replacement of page.events) {
1776
+ const replacementContent = resolveMatrixReplacement(event, replacement);
1777
+ if (replacementContent && (!latest || replacement.origin_server_ts > latest.origin_server_ts || replacement.origin_server_ts === latest.origin_server_ts && replacement.event_id > latest.event_id)) {
1778
+ latest = replacement;
1779
+ latestReplacement = replacementContent;
1780
+ }
1781
+ }
1782
+ from = page.nextBatch ?? void 0;
1783
+ if (!from) {
1784
+ if (latestReplacement?.kind === "unreadable") throw new Error(EDIT_DECRYPTION_ERROR);
1785
+ return latestReplacement?.content ?? originalContent;
1786
+ }
1787
+ if (seenCursors.has(from)) break;
1788
+ seenCursors.add(from);
1789
+ }
1790
+ throw new Error("Matrix edit history could not be fully read; send a new message instead.");
1791
+ }
1792
+ //#endregion
1659
1793
  //#region extensions/matrix/src/matrix/send/formatting.ts
1660
1794
  async function renderMatrixFormattedContent(params) {
1661
1795
  const markdown = params.markdown ?? "";
@@ -1732,24 +1866,6 @@ function diffMatrixMentions(current, previous) {
1732
1866
  if (current.room && !previous.room) delta.room = true;
1733
1867
  return delta;
1734
1868
  }
1735
- function buildReplyRelation(replyToId) {
1736
- const trimmed = replyToId?.trim();
1737
- if (!trimmed) return;
1738
- return { "m.in_reply_to": { event_id: trimmed } };
1739
- }
1740
- function buildThreadRelation(threadId, replyToId) {
1741
- const trimmed = threadId.trim();
1742
- const relation = {
1743
- rel_type: RelationType.Thread,
1744
- event_id: trimmed
1745
- };
1746
- const fallbackReplyToId = replyToId?.trim();
1747
- if (fallbackReplyToId) {
1748
- relation.is_falling_back = true;
1749
- relation["m.in_reply_to"] = { event_id: fallbackReplyToId };
1750
- }
1751
- return relation;
1752
- }
1753
1869
  function resolveMatrixMsgType(contentType, _fileName) {
1754
1870
  switch (getMatrixRuntime().media.mediaKindFromMime(contentType ?? "")) {
1755
1871
  case "image": return MsgType.Image;
@@ -1961,14 +2077,6 @@ function normalizeMatrixClientResolveOpts(opts) {
1961
2077
  accountId: opts.accountId
1962
2078
  };
1963
2079
  }
1964
- function resolvePreviousEditContent(previousEvent) {
1965
- if (!previousEvent || typeof previousEvent !== "object") return;
1966
- const eventRecord = previousEvent;
1967
- if (!eventRecord.content || typeof eventRecord.content !== "object") return;
1968
- const content = eventRecord.content;
1969
- const newContent = content["m.new_content"];
1970
- return newContent && typeof newContent === "object" ? newContent : content;
1971
- }
1972
2080
  function resolvePreviousThreadId(previousEvent) {
1973
2081
  if (!previousEvent || typeof previousEvent !== "object") return;
1974
2082
  const content = previousEvent.content;
@@ -1979,9 +2087,6 @@ function resolvePreviousThreadId(previousEvent) {
1979
2087
  if (relationRecord.rel_type !== RelationType.Thread || typeof relationRecord.event_id !== "string") return;
1980
2088
  return normalizeThreadId(relationRecord.event_id) ?? void 0;
1981
2089
  }
1982
- function hasMatrixMentionsMetadata(content) {
1983
- return Boolean(content && Object.hasOwn(content, "m.mentions"));
1984
- }
1985
2090
  function withMatrixExtraContentFields(content, extraContent) {
1986
2091
  if (!extraContent) return content;
1987
2092
  return {
@@ -1990,8 +2095,9 @@ function withMatrixExtraContentFields(content, extraContent) {
1990
2095
  };
1991
2096
  }
1992
2097
  async function resolvePreviousEditMentions(params) {
1993
- if (hasMatrixMentionsMetadata(params.content)) return extractMatrixMentions(params.content);
1994
- const body = typeof params.content?.body === "string" ? params.content.body : "";
2098
+ const content = await resolveMatrixEditContent(params);
2099
+ if (content && Object.hasOwn(content, "m.mentions")) return extractMatrixMentions(content);
2100
+ const body = typeof content?.body === "string" ? content.body : "";
1995
2101
  if (!body) return {};
1996
2102
  return await resolveMatrixMentionsForBody({
1997
2103
  client: params.client,
@@ -2031,7 +2137,10 @@ async function sendMessageMatrix(to, message, opts) {
2031
2137
  preserveWhitespace: true
2032
2138
  });
2033
2139
  const singleEventBody = fitsInSingleEvent ? preparedBody : void 0;
2034
- const relation = threadId ? buildThreadRelation(threadId, opts.replyToId) : buildReplyRelation(opts.replyToId);
2140
+ const relation = buildMatrixMessageRelation({
2141
+ ...opts,
2142
+ threadId
2143
+ });
2035
2144
  let pendingExtraContent = opts.extraContent;
2036
2145
  const events = [];
2037
2146
  const prepareContent = (content, receiptKind) => {
@@ -2157,7 +2266,7 @@ async function sendMessageMatrix(to, message, opts) {
2157
2266
  } : void 0);
2158
2267
  lastMessageId = eventId || lastMessageId;
2159
2268
  if (!eventId) continue;
2160
- const eventReplyToId = planned.content["m.relates_to"]?.["m.in_reply_to"]?.event_id;
2269
+ const eventReplyToId = resolveMatrixReplyToEventId(planned.content);
2161
2270
  const acceptedEvent = {
2162
2271
  messageId: eventId,
2163
2272
  kind: planned.receiptKind,
@@ -2209,7 +2318,7 @@ async function sendPollMatrix(to, poll, opts) {
2209
2318
  const threadId = normalizeThreadId(opts.threadId);
2210
2319
  const pollPayload = threadId ? {
2211
2320
  ...pollContent,
2212
- "m.relates_to": buildThreadRelation(threadId)
2321
+ "m.relates_to": buildMatrixMessageRelation({ threadId })
2213
2322
  } : { ...pollContent };
2214
2323
  pollPayload["m.mentions"] = mentions;
2215
2324
  return {
@@ -2259,7 +2368,10 @@ async function sendSingleTextMessageMatrix(roomId, text, opts) {
2259
2368
  }, async (client) => {
2260
2369
  const resolvedRoom = await resolveMatrixRoomId(client, roomId);
2261
2370
  const normalizedThreadId = normalizeThreadId(opts.threadId);
2262
- const relation = normalizedThreadId ? buildThreadRelation(normalizedThreadId, opts.replyToId) : buildReplyRelation(opts.replyToId);
2371
+ const relation = buildMatrixMessageRelation({
2372
+ ...opts,
2373
+ threadId: normalizedThreadId
2374
+ });
2263
2375
  const content = withMatrixExtraContentFields(buildTextContent(convertedText, relation, { msgtype: opts.msgtype }), opts.extraContent);
2264
2376
  await enrichMatrixFormattedContent({
2265
2377
  client,
@@ -2271,7 +2383,7 @@ async function sendSingleTextMessageMatrix(roomId, text, opts) {
2271
2383
  });
2272
2384
  if (opts.live) content[MSC4357_LIVE_KEY] = {};
2273
2385
  const eventId = await client.sendMessage(resolvedRoom, content);
2274
- const replyToId = content["m.relates_to"]?.["m.in_reply_to"]?.event_id;
2386
+ const replyToId = resolveMatrixReplyToEventId(content);
2275
2387
  return {
2276
2388
  messageId: eventId ?? "unknown",
2277
2389
  roomId: resolvedRoom,
@@ -2289,11 +2401,6 @@ async function sendSingleTextMessageMatrix(roomId, text, opts) {
2289
2401
  };
2290
2402
  });
2291
2403
  }
2292
- async function getPreviousMatrixEvent(client, roomId, eventId) {
2293
- const getEvent = client.getEvent;
2294
- if (typeof getEvent !== "function") return null;
2295
- return await Promise.resolve(getEvent.call(client, roomId, eventId)).catch(() => null);
2296
- }
2297
2404
  async function editMessageMatrix(roomId, originalEventId, newText, opts) {
2298
2405
  return await withResolvedMatrixSendClient({
2299
2406
  client: opts.client,
@@ -2316,16 +2423,17 @@ async function editMessageMatrix(roomId, originalEventId, newText, opts) {
2316
2423
  includeMentions: opts.includeMentions,
2317
2424
  tableMode
2318
2425
  });
2319
- const previousEvent = await getPreviousMatrixEvent(client, resolvedRoom, originalEventId);
2426
+ const threadId = normalizeThreadId(opts.threadId);
2427
+ const previousEvent = opts.includeMentions !== false || threadId ? await client.getEvent(resolvedRoom, originalEventId) : null;
2320
2428
  const replaceMentions = opts.includeMentions === false ? void 0 : diffMatrixMentions(extractMatrixMentions(newContent), await resolvePreviousEditMentions({
2321
2429
  client,
2322
- content: resolvePreviousEditContent(previousEvent)
2430
+ roomId: resolvedRoom,
2431
+ event: previousEvent
2323
2432
  }));
2324
2433
  const replaceRelation = {
2325
2434
  rel_type: RelationType.Replace,
2326
2435
  event_id: originalEventId
2327
2436
  };
2328
- const threadId = normalizeThreadId(opts.threadId);
2329
2437
  if (threadId) {
2330
2438
  if (resolvePreviousThreadId(previousEvent) !== threadId) throw new Error("Matrix edit cannot add or change the original event thread relation.");
2331
2439
  }
@@ -2358,4 +2466,4 @@ async function reactMatrixMessage(roomId, messageId, emoji, opts) {
2358
2466
  });
2359
2467
  }
2360
2468
  //#endregion
2361
- export { repairMatrixDirectRooms as C, promoteMatrixDirectRoomCandidate as S, MsgType as T, resolvePollReferenceEventId as _, sendSingleTextMessageMatrix as a, resolveMatrixRoomId as b, prepareMatrixSingleText as c, formatPollAsText as d, formatPollResultsAsText as f, parsePollStartContent as g, parsePollStart as h, sendPollMatrix as i, buildPollResponseContent as l, isPollStartType as m, reactMatrixMessage as n, sendTypingMatrix as o, isPollEventType as p, sendMessageMatrix as r, send_exports as s, editMessageMatrix as t, buildPollResultsSummary as u, cleanupMatrixDeliveryPlans as v, MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY as w, direct_management_exports as x, reconcileMatrixUnknownSend as y };
2469
+ export { promoteMatrixDirectRoomCandidate as A, parsePollStart as C, reconcileMatrixUnknownSend as D, cleanupMatrixDeliveryPlans as E, resolveMatrixRoomId as O, isPollStartType as S, resolvePollReferenceEventId as T, buildPollResponseContent as _, sendSingleTextMessageMatrix as a, formatPollResultsAsText as b, formatMatrixMediaTooLargeText as c, isLikelyBareFilename as d, resolveMatrixMessageAttachment as f, resolveMatrixThreadRootId as g, resolveMatrixReplyToEventId as h, sendPollMatrix as i, repairMatrixDirectRooms as j, direct_management_exports as k, formatMatrixMediaUnavailableText as l, prepareMatrixSingleText as m, reactMatrixMessage as n, sendTypingMatrix as o, resolveMatrixReplacementContent as p, sendMessageMatrix as r, send_exports as s, editMessageMatrix as t, formatMatrixMessageText as u, buildPollResultsSummary as v, parsePollStartContent as w, isPollEventType as x, formatPollAsText as y };
@@ -1,3 +1,3 @@
1
1
  import { r as setMatrixRuntime } from "./runtime-6S3DNFNv.js";
2
- import { t as createMatrixThreadBindingManager } from "./thread-bindings-BkBnn4te.js";
2
+ import { t as createMatrixThreadBindingManager } from "./thread-bindings-CRyf5on_.js";
3
3
  export { createMatrixThreadBindingManager, setMatrixRuntime };
@@ -1,6 +1,6 @@
1
1
  import { a as resolveMatrixAccountConfig, n as hasExplicitMatrixAccountConfig } from "./account-config-CRsKoMqJ.js";
2
- import "./accounts-DR1c4xF_.js";
3
- import { n as bootstrapMatrixVerification } from "./verification-XJtTc5DI.js";
2
+ import "./accounts-GwSAk9vY.js";
3
+ import { n as bootstrapMatrixVerification } from "./verification-B_aqtbx-.js";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
5
5
  //#region extensions/matrix/src/setup-bootstrap.ts
6
6
  async function maybeBootstrapNewEncryptedMatrixAccount(params) {
@@ -1,6 +1,6 @@
1
- import { s as resolveMatrixEnvAuthReadiness } from "./account-selection-DA-jfx22.js";
1
+ import { c as resolveMatrixEnvAuthReadiness } from "./account-selection-Bbtc483D.js";
2
2
  import { a as resolveMatrixAccountConfig } from "./account-config-CRsKoMqJ.js";
3
- import { r as resolveDefaultMatrixAccountId } from "./accounts-DR1c4xF_.js";
3
+ import { r as resolveDefaultMatrixAccountId } from "./accounts-GwSAk9vY.js";
4
4
  import { t as resolveMatrixConfigFieldPath } from "./config-paths-CnREYb1Y.js";
5
5
  import { r as updateMatrixAccountConfig } from "./config-update-BnX26jCO.js";
6
6
  import { t as isSupportedMatrixAvatarSource } from "./profile-vmjsmhh4.js";
@@ -311,7 +311,7 @@ const matrixSetupAdapter = {
311
311
  input
312
312
  }),
313
313
  afterAccountConfigWritten: async ({ previousCfg, cfg, accountId, runtime }) => {
314
- const { runMatrixSetupBootstrapAfterConfigWrite } = await import("./setup-bootstrap-S_loyUyM.js");
314
+ const { runMatrixSetupBootstrapAfterConfigWrite } = await import("./setup-bootstrap-CSI1L1lm.js");
315
315
  await runMatrixSetupBootstrapAfterConfigWrite({
316
316
  previousCfg,
317
317
  cfg,
@@ -1,2 +1,2 @@
1
- import { n as matrixSetupPlugin } from "./channel.setup-DhmDXwPp.js";
1
+ import { n as matrixSetupPlugin } from "./channel.setup-oxd8RsIr.js";
2
2
  export { matrixSetupPlugin };
@@ -1,10 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { n as requiresExplicitMatrixDefaultAccount, s as resolveMatrixEnvAuthReadiness } from "./account-selection-DA-jfx22.js";
2
+ import { c as resolveMatrixEnvAuthReadiness, r as requiresExplicitMatrixDefaultAccount } from "./account-selection-Bbtc483D.js";
3
3
  import { a as resolveMatrixAccountConfig } from "./account-config-CRsKoMqJ.js";
4
- import { i as resolveMatrixAccount, r as resolveDefaultMatrixAccountId, t as listMatrixAccountIds } from "./accounts-DR1c4xF_.js";
4
+ import { i as resolveMatrixAccount, r as resolveDefaultMatrixAccountId, t as listMatrixAccountIds } from "./accounts-GwSAk9vY.js";
5
5
  import { n as isMatrixRoomId } from "./target-ids-Nwx7cMVE.js";
6
6
  import { r as updateMatrixAccountConfig } from "./config-update-BnX26jCO.js";
7
- import { a as moveSingleMatrixAccountConfigToNamedAccount, i as createMatrixSetupDmPolicy } from "./setup-core-XkIfQ65J.js";
7
+ import { a as moveSingleMatrixAccountConfigToNamedAccount, i as createMatrixSetupDmPolicy } from "./setup-core-DuTlyqRz.js";
8
8
  import { n as validateMatrixHomeserverUrl, r as isPrivateOrLoopbackHost, t as resolveValidatedMatrixHomeserverUrl } from "./url-validation-GRHde6lq.js";
9
9
  import { n as ensureMatrixSdkInstalled, r as isMatrixSdkAvailable } from "./deps-mtxF2mHI.js";
10
10
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringifiedOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -91,7 +91,7 @@ async function promptMatrixAllowFrom(params) {
91
91
  pending.push(part);
92
92
  }
93
93
  if (pending.length > 0) {
94
- const { resolveMatrixTargets } = await import("./resolve-targets-B64O69Nd.js").then((n) => n.n);
94
+ const { resolveMatrixTargets } = await import("./resolve-targets-BpnALDzR.js").then((n) => n.n);
95
95
  const results = await resolveMatrixTargets({
96
96
  cfg,
97
97
  accountId,
@@ -211,7 +211,7 @@ async function configureMatrixAccessPrompts(params) {
211
211
  resolvedIds.push(cleaned);
212
212
  continue;
213
213
  }
214
- const { listMatrixDirectoryGroupsLive } = await import("./directory-live-DLUgWBhA.js").then((n) => n.t);
214
+ const { listMatrixDirectoryGroupsLive } = await import("./directory-live-DABCxf8j.js").then((n) => n.t);
215
215
  const matches = await listMatrixDirectoryGroupsLive({
216
216
  cfg: next,
217
217
  accountId: params.accountId,
@@ -464,7 +464,7 @@ const matrixOnboardingAdapter = {
464
464
  });
465
465
  },
466
466
  afterConfigWritten: async ({ previousCfg, cfg, accountId, runtime }) => {
467
- const { runMatrixSetupBootstrapAfterConfigWrite } = await import("./setup-bootstrap-S_loyUyM.js");
467
+ const { runMatrixSetupBootstrapAfterConfigWrite } = await import("./setup-bootstrap-CSI1L1lm.js");
468
468
  await runMatrixSetupBootstrapAfterConfigWrite({
469
469
  previousCfg,
470
470
  cfg,
@@ -1,5 +1,6 @@
1
1
  import { t as getMatrixRuntime } from "./runtime-6S3DNFNv.js";
2
- import { M as resolveMatrixSqliteStateEnv, l as resolveMatrixStoragePaths, o as recordCurrentStorageMetaDeviceId } from "./storage-BVf4uucD.js";
2
+ import { k as resolveMatrixSqliteStateEnv } from "./storage-metadata-DYArLcq1.js";
3
+ import { o as resolveMatrixStoragePaths, r as recordCurrentStorageMetaDeviceId } from "./storage-CV-pfV_2.js";
3
4
  import { createHash } from "node:crypto";
4
5
  import path from "node:path";
5
6
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";