@openclaw/imessage 2026.8.1-beta.2 → 2026.8.1

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 (157) hide show
  1. package/dist/{accounts-D00Njxg2.js → accounts-CCirBEIm.js} +4 -5
  2. package/dist/{actions.runtime-DTFKDN5p.js → actions.runtime-CAl3WcqD.js} +2 -3
  3. package/dist/api.js +6 -5
  4. package/dist/{approval-handler.runtime-BtLs4gho.js → approval-handler.runtime-UBd1j2Sg.js} +15 -9
  5. package/dist/approval-reactions-LL5yn1Rc.js +562 -0
  6. package/dist/{channel-lppmI51h.js → channel-DNI9DKGN.js} +26 -21
  7. package/dist/channel-config-api.js +1 -1
  8. package/dist/channel-plugin-api.js +1 -1
  9. package/dist/{channel.runtime-5wpCKQb7.js → channel.runtime-HSkrmWfW.js} +58 -11
  10. package/dist/{config-schema-DV0KP5nC.js → config-schema-DuGbA8Kp.js} +8 -7
  11. package/dist/contract-api.js +1 -1
  12. package/dist/doctor-contract-api.js +8 -281
  13. package/dist/{group-policy-DF9xSdik.js → group-policy-Dvc-BcWo.js} +19 -651
  14. package/dist/{media-contract-BEgdvYhW.js → media-contract-D-FhGE98.js} +1 -1
  15. package/dist/media-contract-api.js +1 -1
  16. package/dist/{message-tool-api-CPDfJJoE.js → message-tool-api-CvIgJpOo.js} +7 -4
  17. package/dist/message-tool-api.js +1 -1
  18. package/dist/{monitor-DnxJ8pW9.js → monitor-BywJn1QW.js} +343 -111
  19. package/dist/{question-reactions-DVe50UhB.js → question-reactions-viP7ZcyG.js} +2 -1
  20. package/dist/reaction-context-BAYI7pz0.js +105 -0
  21. package/dist/{remote-file-DLwO9ved.js → remote-file-6mCj2ZBy.js} +7 -3
  22. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  23. package/dist/runtime-Cza4CY5T.js +8 -0
  24. package/dist/runtime-api.js +10 -9
  25. package/dist/{sanitize-outbound-CoTZLXMw.js → sanitize-outbound-Du-r1lNQ.js} +345 -58
  26. package/dist/{send-BUXW76tw.js → send-mgWPKqSV.js} +147 -26
  27. package/dist/state-contract-4TK_cDDb.js +56 -0
  28. package/dist/state-migrations-SFdKp3GQ.js +277 -0
  29. package/node_modules/typebox/build/format/date.d.mts +1 -1
  30. package/node_modules/typebox/build/format/date.mjs +1 -1
  31. package/node_modules/typebox/build/format/date_time.d.mts +2 -2
  32. package/node_modules/typebox/build/format/date_time.mjs +3 -3
  33. package/node_modules/typebox/build/format/email.d.mts +1 -1
  34. package/node_modules/typebox/build/format/email.mjs +2 -2
  35. package/node_modules/typebox/build/format/hostname.mjs +2 -10
  36. package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
  37. package/node_modules/typebox/build/format/idn_email.mjs +3 -3
  38. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
  39. package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
  40. package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
  41. package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
  42. package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
  43. package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
  44. package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
  45. package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
  46. package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
  47. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
  48. package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
  49. package/node_modules/typebox/build/format/idna/index.mjs +2 -0
  50. package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
  51. package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
  52. package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
  53. package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
  54. package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
  55. package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
  56. package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
  57. package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
  58. package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
  59. package/node_modules/typebox/build/format/ipv4.mjs +2 -32
  60. package/node_modules/typebox/build/format/ipv6.mjs +2 -61
  61. package/node_modules/typebox/build/format/iri.d.mts +2 -2
  62. package/node_modules/typebox/build/format/iri.mjs +26 -8
  63. package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
  64. package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
  65. package/node_modules/typebox/build/format/regex.d.mts +1 -2
  66. package/node_modules/typebox/build/format/regex.mjs +2 -6
  67. package/node_modules/typebox/build/format/time.d.mts +2 -2
  68. package/node_modules/typebox/build/format/time.mjs +19 -14
  69. package/node_modules/typebox/build/format/uri.d.mts +1 -1
  70. package/node_modules/typebox/build/format/uri.mjs +3 -130
  71. package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
  72. package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
  73. package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
  74. package/node_modules/typebox/build/format/uri_template.mjs +4 -5
  75. package/node_modules/typebox/build/format/url.d.mts +3 -3
  76. package/node_modules/typebox/build/format/url.mjs +4 -5
  77. package/node_modules/typebox/build/guard/emit.d.mts +3 -1
  78. package/node_modules/typebox/build/guard/emit.mjs +12 -5
  79. package/node_modules/typebox/build/guard/guard.d.mts +8 -2
  80. package/node_modules/typebox/build/guard/guard.mjs +25 -4
  81. package/node_modules/typebox/build/guard/string.d.mts +2 -2
  82. package/node_modules/typebox/build/guard/string.mjs +7 -7
  83. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
  84. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
  85. package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
  86. package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
  87. package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
  88. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
  89. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
  90. package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
  91. package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
  92. package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
  93. package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
  94. package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
  95. package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
  96. package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
  97. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
  98. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
  99. package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
  100. package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
  101. package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
  102. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
  103. package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
  104. package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
  105. package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
  106. package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
  107. package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
  108. package/node_modules/typebox/build/schema/types/index.mjs +0 -2
  109. package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
  110. package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
  111. package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
  112. package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
  113. package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
  114. package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
  115. package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
  116. package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
  117. package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
  118. package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
  119. package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
  120. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
  121. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
  122. package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
  123. package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
  124. package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
  125. package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
  126. package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
  127. package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
  128. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
  129. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
  130. package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
  131. package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
  132. package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
  133. package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
  134. package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
  135. package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
  136. package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
  137. package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
  138. package/node_modules/typebox/build/type/script/parser.mjs +27 -23
  139. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
  140. package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
  141. package/node_modules/typebox/package.json +27 -27
  142. package/node_modules/typebox/readme.md +79 -82
  143. package/openclaw.plugin.json +0 -6
  144. package/package.json +5 -5
  145. package/dist/catchup-D32oYNxR.js +0 -294
  146. package/dist/monitor-reply-cache-DKlYGd5x.js +0 -348
  147. package/dist/persisted-echo-cache-BPWGUK-L.js +0 -143
  148. package/node_modules/typebox/build/format/_idna.d.mts +0 -2
  149. package/node_modules/typebox/build/format/_idna.mjs +0 -246
  150. package/node_modules/typebox/build/format/_puny.d.mts +0 -1
  151. package/node_modules/typebox/build/format/_puny.mjs +0 -77
  152. package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
  153. package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
  154. package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
  155. package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
  156. package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
  157. package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
@@ -1,4 +1,5 @@
1
- import { E as resolveIMessageReactionContext, K as __exportAll } from "./group-policy-DF9xSdik.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
+ import { t as resolveIMessageReactionContext } from "./reaction-context-BAYI7pz0.js";
2
3
  import { createQuestionReactionTargetStore, questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
3
4
  //#region extensions/imessage/src/question-reactions.ts
4
5
  var question_reactions_exports = /* @__PURE__ */ __exportAll({
@@ -0,0 +1,105 @@
1
+ //#region extensions/imessage/src/monitor/reaction-context.ts
2
+ const TAPBACK_TEXT_PATTERNS = [
3
+ {
4
+ prefix: "loved",
5
+ action: "added",
6
+ emoji: "❤️"
7
+ },
8
+ {
9
+ prefix: "liked",
10
+ action: "added",
11
+ emoji: "👍"
12
+ },
13
+ {
14
+ prefix: "disliked",
15
+ action: "added",
16
+ emoji: "👎"
17
+ },
18
+ {
19
+ prefix: "laughed at",
20
+ action: "added",
21
+ emoji: "😂"
22
+ },
23
+ {
24
+ prefix: "emphasized",
25
+ action: "added",
26
+ emoji: "‼️"
27
+ },
28
+ {
29
+ prefix: "questioned",
30
+ action: "added",
31
+ emoji: "❓"
32
+ },
33
+ {
34
+ prefix: "removed a heart from",
35
+ action: "removed",
36
+ emoji: "❤️"
37
+ },
38
+ {
39
+ prefix: "removed a like from",
40
+ action: "removed",
41
+ emoji: "👍"
42
+ },
43
+ {
44
+ prefix: "removed a dislike from",
45
+ action: "removed",
46
+ emoji: "👎"
47
+ },
48
+ {
49
+ prefix: "removed a laugh from",
50
+ action: "removed",
51
+ emoji: "😂"
52
+ },
53
+ {
54
+ prefix: "removed an emphasis from",
55
+ action: "removed",
56
+ emoji: "‼️"
57
+ },
58
+ {
59
+ prefix: "removed a question from",
60
+ action: "removed",
61
+ emoji: "❓"
62
+ }
63
+ ];
64
+ function normalizeReactionValue(value) {
65
+ return typeof value === "string" ? value.trim().replace(/^p:\d+\//iu, "") || void 0 : void 0;
66
+ }
67
+ function resolveReactionTargetGuidCandidates(...values) {
68
+ const candidates = [];
69
+ for (const value of values) {
70
+ if (typeof value !== "string") continue;
71
+ const raw = value.trim();
72
+ if (!raw) continue;
73
+ const normalized = raw.replace(/^p:\d+\//iu, "");
74
+ for (const candidate of [normalized, raw]) if (candidate && !candidates.includes(candidate)) candidates.push(candidate);
75
+ }
76
+ return candidates;
77
+ }
78
+ function resolveTapbackTextContext(bodyText) {
79
+ const lower = bodyText.toLowerCase();
80
+ for (const pattern of TAPBACK_TEXT_PATTERNS) {
81
+ if (!lower.startsWith(pattern.prefix)) continue;
82
+ const afterPrefix = bodyText.slice(pattern.prefix.length).trim();
83
+ if (!/^(?:"[\s\S]*"|“[\s\S]*”)$/u.test(afterPrefix)) continue;
84
+ return {
85
+ action: pattern.action,
86
+ emoji: pattern.emoji,
87
+ targetText: afterPrefix.slice(1, -1).trim()
88
+ };
89
+ }
90
+ return null;
91
+ }
92
+ function resolveIMessageReactionContext(message, bodyText) {
93
+ if (message.is_reaction === true || message.is_tapback === true || typeof message.associated_message_type === "number" && Number.isFinite(message.associated_message_type) && message.associated_message_type >= 2e3 && message.associated_message_type < 4e3) {
94
+ const targetGuids = resolveReactionTargetGuidCandidates(message.reacted_to_guid, message.associated_message_guid);
95
+ return {
96
+ action: message.is_reaction_add === false ? "removed" : "added",
97
+ emoji: normalizeReactionValue(message.reaction_emoji) ?? normalizeReactionValue(message.reaction_type) ?? "reaction",
98
+ targetGuid: targetGuids[0],
99
+ targetGuids
100
+ };
101
+ }
102
+ return resolveTapbackTextContext(bodyText);
103
+ }
104
+ //#endregion
105
+ export { resolveIMessageReactionContext as t };
@@ -1,5 +1,5 @@
1
- import { p as resolveLocalIMessageChatDbPath, u as expandIMessageUserPath } from "./accounts-D00Njxg2.js";
2
- import { g as isIMessageEmailChatIdentifier, h as chatContextFromIMessageTarget, l as resolveIMessageCachedResourceBinding, u as resolveIMessageMessageId } from "./monitor-reply-cache-DKlYGd5x.js";
1
+ import { p as resolveLocalIMessageChatDbPath, u as expandIMessageUserPath } from "./accounts-CCirBEIm.js";
2
+ import { d as resolveIMessageCachedResourceBinding, f as resolveIMessageMessageId, g as isIMessageEmailChatIdentifier, h as chatContextFromIMessageTarget } from "./sanitize-outbound-Du-r1lNQ.js";
3
3
  import path from "node:path";
4
4
  import { normalizeScpRemoteHost } from "openclaw/plugin-sdk/host-runtime";
5
5
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
@@ -121,7 +121,11 @@ function checkIMessageResourceBinding(params) {
121
121
  FROM message m
122
122
  JOIN chat_message_join cmj ON cmj.message_id = m.ROWID
123
123
  JOIN chat c ON c.ROWID = cmj.chat_id
124
- WHERE m.guid = ?`).all(messageGuid).some((row) => (!hasChatId || row.chatId === chatId) && (expectedChatGuids.length === 0 || matchesAnyChatCandidate(row.chatGuid, expectedChatGuids)) && (expectedChatIdentifiers.length === 0 || matchesAnyChatCandidate(row.chatIdentifier, expectedChatIdentifiers)) && (identifierChatGuids.length === 0 || matchesAnyChatCandidate(row.chatGuid, identifierChatGuids))) ? "match" : "mismatch";
124
+ WHERE m.guid = ?`).all(messageGuid).map((row) => ({
125
+ chatId: row.chatId,
126
+ chatGuid: row.chatGuid,
127
+ chatIdentifier: row.chatIdentifier
128
+ })).some((row) => (!hasChatId || row.chatId === chatId) && (expectedChatGuids.length === 0 || matchesAnyChatCandidate(row.chatGuid, expectedChatGuids)) && (expectedChatIdentifiers.length === 0 || matchesAnyChatCandidate(row.chatIdentifier, expectedChatIdentifiers)) && (identifierChatGuids.length === 0 || matchesAnyChatCandidate(row.chatGuid, identifierChatGuids))) ? "match" : "mismatch";
125
129
  } catch {
126
130
  return "unavailable";
127
131
  } finally {
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll as t };
@@ -0,0 +1,8 @@
1
+ import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
2
+ //#region extensions/imessage/src/runtime.ts
3
+ const { getRuntime: getIMessageRuntime, setRuntime: setIMessageRuntime, tryGetRuntime: getOptionalIMessageRuntime } = createPluginRuntimeStore({
4
+ pluginId: "imessage",
5
+ errorMessage: "iMessage runtime not initialized"
6
+ });
7
+ //#endregion
8
+ export { getOptionalIMessageRuntime as n, setIMessageRuntime as r, getIMessageRuntime as t };
@@ -1,15 +1,16 @@
1
- import { F as imessageMessageActions, I as probeIMessage, h as normalizeIMessageMessagingTarget, l as chunkTextForOutbound, m as looksLikeIMessageTargetId, n as resolveIMessageGroupToolPolicy, t as resolveIMessageGroupRequireMention } from "./group-policy-DF9xSdik.js";
2
- import { o as resolveIMessageAccount } from "./accounts-D00Njxg2.js";
3
- import { m as setIMessageRuntime } from "./monitor-reply-cache-DKlYGd5x.js";
4
- import { n as IMessageConfigSchema } from "./config-schema-DV0KP5nC.js";
5
- import { t as sendMessageIMessage } from "./send-BUXW76tw.js";
6
- import { t as monitorIMessageProvider } from "./monitor-DnxJ8pW9.js";
7
- import { buildComputedAccountStatusSnapshot, collectStatusIssuesFromLastError } from "openclaw/plugin-sdk/status-helpers";
1
+ import { o as resolveIMessageAccount } from "./accounts-CCirBEIm.js";
2
+ import { c as normalizeIMessageMessagingTarget, d as imessageMessageActions, f as probeIMessage, n as resolveIMessageGroupToolPolicy, s as looksLikeIMessageTargetId, t as resolveIMessageGroupRequireMention } from "./group-policy-Dvc-BcWo.js";
3
+ import { r as setIMessageRuntime } from "./runtime-Cza4CY5T.js";
4
+ import { n as IMessageConfigSchema } from "./config-schema-DuGbA8Kp.js";
5
+ import { t as sendMessageIMessage } from "./send-mgWPKqSV.js";
6
+ import { t as monitorIMessageProvider } from "./monitor-BywJn1QW.js";
8
7
  import { formatTrimmedAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers";
9
- import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
8
+ import { buildComputedAccountStatusSnapshot, collectStatusIssuesFromLastError } from "openclaw/plugin-sdk/status-helpers";
9
+ import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
10
+ import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
10
11
  import { DEFAULT_ACCOUNT_ID, getChatChannelMeta } from "openclaw/plugin-sdk/core";
11
- import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
12
12
  import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
13
+ import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
13
14
  //#region extensions/imessage/src/config-accessors.ts
14
15
  function resolveIMessageConfigAllowFrom(params) {
15
16
  return (resolveIMessageAccount(params).config.allowFrom ?? []).map((entry) => String(entry));
@@ -1,15 +1,352 @@
1
- import { u as expandIMessageUserPath } from "./accounts-D00Njxg2.js";
2
- import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { u as expandIMessageUserPath } from "./accounts-CCirBEIm.js";
2
+ import { t as getIMessageRuntime } from "./runtime-Cza4CY5T.js";
3
+ import { a as IMESSAGE_REPLY_CACHE_NAMESPACE, f as resolveIMessageReplyCacheEntryKey, i as IMESSAGE_REPLY_CACHE_MAX_ENTRIES, n as IMESSAGE_REPLY_CACHE_COUNTER_KEY, o as IMESSAGE_REPLY_CACHE_TTL_MS, r as IMESSAGE_REPLY_CACHE_COUNTER_NAMESPACE } from "./state-contract-4TK_cDDb.js";
4
+ import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution";
5
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
3
7
  import { resolveUserPath } from "openclaw/plugin-sdk/text-utility-runtime";
4
8
  import { spawn } from "node:child_process";
5
9
  import { StringDecoder } from "node:string_decoder";
6
10
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
7
11
  import { FormatCapabilityProfile, findCodeRegions, isInsideCode, markdownToIR, renderMarkdownWithAttributedRanges, sanitizeAssistantVisibleText, stripMarkdown, tokenizeHtmlTags } from "openclaw/plugin-sdk/text-chunking";
12
+ //#region extensions/imessage/src/chat-context.ts
13
+ const EMAIL_HANDLE_PATTERN = /^[^\s@]+@[^\s@]+$/u;
14
+ function parseDirectChatIdentity(raw) {
15
+ const trimmed = raw.trim();
16
+ const parts = trimmed.split(";");
17
+ if (parts.length === 3 && parts[1] === "-" && parts[2]) {
18
+ const service = parts[0]?.toLowerCase();
19
+ if (service === "imessage" || service === "sms" || service === "any") {
20
+ const identifier = parts[2];
21
+ return {
22
+ service,
23
+ identifier: EMAIL_HANDLE_PATTERN.test(identifier) ? identifier.toLowerCase() : identifier
24
+ };
25
+ }
26
+ }
27
+ if (parts.length !== 1) return;
28
+ if (trimmed.startsWith("+") || EMAIL_HANDLE_PATTERN.test(trimmed)) return { identifier: trimmed.toLowerCase() };
29
+ }
30
+ function resolveIMessageDirectChatService(configuredService, chatGuid) {
31
+ if (configuredService === "imessage" || configuredService === "sms") return configuredService;
32
+ const observedService = chatGuid ? parseDirectChatIdentity(chatGuid)?.service : void 0;
33
+ return observedService === "imessage" || observedService === "sms" ? observedService : void 0;
34
+ }
35
+ function isIMessageEmailChatIdentifier(raw) {
36
+ const identity = parseDirectChatIdentity(raw);
37
+ return Boolean(identity && EMAIL_HANDLE_PATTERN.test(identity.identifier));
38
+ }
39
+ /**
40
+ * Strip the `iMessage;-;` / `SMS;-;` / `any;-;` service prefix that Messages
41
+ * uses for direct chats. Different layers report direct DMs in different
42
+ * forms, so raw comparison would falsely treat one DM as different chats.
43
+ */
44
+ function normalizeDirectChatIdentifier(raw) {
45
+ const trimmed = raw.trim();
46
+ return parseDirectChatIdentity(trimmed)?.identifier ?? trimmed;
47
+ }
48
+ function chatContextFromIMessageTarget(target, effectiveService) {
49
+ if (target.kind === "chat_id") return { chatId: target.chatId };
50
+ if (target.kind === "chat_guid") return { chatGuid: target.chatGuid };
51
+ if (target.kind === "chat_identifier") return { chatIdentifier: target.chatIdentifier };
52
+ const trimmedHandle = target.to.trim();
53
+ const canonicalHandle = trimmedHandle.startsWith("+") ? normalizeE164(trimmedHandle) : /^[^\s@]+@[^\s@]+$/u.test(trimmedHandle) ? trimmedHandle.toLowerCase() : void 0;
54
+ if (!canonicalHandle) return {};
55
+ const service = target.service === "auto" ? effectiveService : target.service;
56
+ if (service !== "imessage" && service !== "sms") return {};
57
+ return { chatIdentifier: `${service === "sms" ? "SMS" : "iMessage"};-;${canonicalHandle}` };
58
+ }
59
+ function compareOptional(left, right) {
60
+ return left === void 0 || right === void 0 ? void 0 : left === right;
61
+ }
62
+ function compareChatSelector(cachedRaw, currentRaw, crossKind = false) {
63
+ const cached = normalizeOptionalString(cachedRaw);
64
+ const current = normalizeOptionalString(currentRaw);
65
+ if (!cached || !current) return;
66
+ if (cached === current) return true;
67
+ const cachedDirect = parseDirectChatIdentity(cached);
68
+ const currentDirect = parseDirectChatIdentity(current);
69
+ if (!cachedDirect || !currentDirect) return crossKind ? void 0 : false;
70
+ if (cachedDirect.identifier !== currentDirect.identifier) return false;
71
+ if (cachedDirect.service === "any") return true;
72
+ if (!cachedDirect.service || !currentDirect.service) return;
73
+ return cachedDirect.service === currentDirect.service;
74
+ }
75
+ function resolveIMessageChatMatch(cached, current) {
76
+ const cachedChatGuid = normalizeOptionalString(cached.chatGuid);
77
+ const currentChatGuid = normalizeOptionalString(current.chatGuid);
78
+ const cachedChatIdentifier = normalizeOptionalString(cached.chatIdentifier);
79
+ const currentChatIdentifier = normalizeOptionalString(current.chatIdentifier);
80
+ const comparisons = [
81
+ compareChatSelector(cachedChatGuid, currentChatGuid),
82
+ compareChatSelector(cachedChatIdentifier, currentChatIdentifier),
83
+ compareOptional(cached.chatId, current.chatId),
84
+ compareChatSelector(cachedChatGuid, currentChatIdentifier, true),
85
+ compareChatSelector(cachedChatIdentifier, currentChatGuid, true)
86
+ ].filter((comparison) => comparison !== void 0);
87
+ if (comparisons.length === 0) return "unknown";
88
+ return comparisons.every(Boolean) ? "match" : "mismatch";
89
+ }
90
+ function isPositiveIMessageChatMatch(cached, current) {
91
+ return resolveIMessageChatMatch(cached, current) === "match";
92
+ }
93
+ //#endregion
8
94
  //#region extensions/imessage/src/constants.ts
9
95
  /** Default timeout for iMessage probe/RPC operations (10 seconds). */
10
96
  const DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS = 1e4;
11
97
  const DEFAULT_IMESSAGE_SEND_TIMEOUT_MS = 18e4;
12
98
  //#endregion
99
+ //#region extensions/imessage/src/monitor-reply-cache.ts
100
+ /** Recency window for the "react to the latest message" fallback. */
101
+ const LATEST_FALLBACK_MS = 600 * 1e3;
102
+ let persistenceFailureLogged = false;
103
+ function reportPersistenceFailure(scope, err) {
104
+ if (persistenceFailureLogged) return;
105
+ persistenceFailureLogged = true;
106
+ logVerbose(`imessage reply-cache: ${scope} disabled after first failure: ${String(err)}`);
107
+ }
108
+ const imessageReplyCacheByMessageId = /* @__PURE__ */ new Map();
109
+ const imessageShortIdToUuid = /* @__PURE__ */ new Map();
110
+ const imessageUuidToShortId = /* @__PURE__ */ new Map();
111
+ let imessageShortIdCounter = 0;
112
+ function openReplyCacheStore() {
113
+ return getIMessageRuntime().state.openSyncKeyedStore({
114
+ namespace: IMESSAGE_REPLY_CACHE_NAMESPACE,
115
+ maxEntries: IMESSAGE_REPLY_CACHE_MAX_ENTRIES
116
+ });
117
+ }
118
+ function openReplyCacheCounterStore() {
119
+ return getIMessageRuntime().state.openSyncKeyedStore({
120
+ namespace: IMESSAGE_REPLY_CACHE_COUNTER_NAMESPACE,
121
+ maxEntries: 1
122
+ });
123
+ }
124
+ function remainingTtlMs(timestamp) {
125
+ const remaining = IMESSAGE_REPLY_CACHE_TTL_MS - Math.max(0, Date.now() - timestamp);
126
+ return remaining > 0 ? remaining : void 0;
127
+ }
128
+ let hydrated = false;
129
+ function hydrateFromStoreOnce() {
130
+ if (hydrated) return;
131
+ hydrated = true;
132
+ const cutoff = Date.now() - IMESSAGE_REPLY_CACHE_TTL_MS;
133
+ let entries;
134
+ try {
135
+ const counter = openReplyCacheCounterStore().lookup(IMESSAGE_REPLY_CACHE_COUNTER_KEY);
136
+ if (counter && Number.isSafeInteger(counter.counter) && counter.counter > 0) imessageShortIdCounter = Math.max(imessageShortIdCounter, counter.counter);
137
+ entries = openReplyCacheStore().entries().map(({ value }) => value).filter((entry) => entry.timestamp >= cutoff).toSorted((a, b) => a.timestamp - b.timestamp).slice(-IMESSAGE_REPLY_CACHE_MAX_ENTRIES);
138
+ for (const entry of entries) {
139
+ const numeric = Number.parseInt(entry.shortId, 10);
140
+ if (Number.isFinite(numeric) && numeric > imessageShortIdCounter) imessageShortIdCounter = numeric;
141
+ }
142
+ } catch (err) {
143
+ reportPersistenceFailure("read", err);
144
+ return;
145
+ }
146
+ if (entries.length === 0) return;
147
+ for (const entry of entries) {
148
+ imessageReplyCacheByMessageId.set(entry.messageId, entry);
149
+ imessageShortIdToUuid.set(entry.shortId, entry.messageId);
150
+ imessageUuidToShortId.set(entry.messageId, entry.shortId);
151
+ }
152
+ }
153
+ function persistReplyCacheEntry(entry) {
154
+ const ttlMs = remainingTtlMs(entry.timestamp);
155
+ if (!ttlMs) return;
156
+ try {
157
+ openReplyCacheStore().register(resolveIMessageReplyCacheEntryKey(entry.messageId), entry, { ttlMs });
158
+ } catch (err) {
159
+ reportPersistenceFailure("write", err);
160
+ }
161
+ }
162
+ function deleteReplyCacheEntry(messageId) {
163
+ try {
164
+ openReplyCacheStore().delete(resolveIMessageReplyCacheEntryKey(messageId));
165
+ } catch (err) {
166
+ reportPersistenceFailure("delete", err);
167
+ }
168
+ }
169
+ function persistReplyCacheCounter() {
170
+ try {
171
+ openReplyCacheCounterStore().register(IMESSAGE_REPLY_CACHE_COUNTER_KEY, { counter: imessageShortIdCounter });
172
+ } catch (err) {
173
+ reportPersistenceFailure("counter", err);
174
+ }
175
+ }
176
+ function buildReplyCacheEntry(entry, messageId, shortId) {
177
+ return {
178
+ accountId: entry.accountId,
179
+ messageId,
180
+ shortId,
181
+ timestamp: entry.timestamp,
182
+ ...typeof entry.chatGuid === "string" ? { chatGuid: entry.chatGuid } : {},
183
+ ...typeof entry.chatIdentifier === "string" ? { chatIdentifier: entry.chatIdentifier } : {},
184
+ ...typeof entry.chatId === "number" ? { chatId: entry.chatId } : {},
185
+ ...typeof entry.isFromMe === "boolean" ? { isFromMe: entry.isFromMe } : {}
186
+ };
187
+ }
188
+ function generateShortId() {
189
+ imessageShortIdCounter += 1;
190
+ persistReplyCacheCounter();
191
+ return String(imessageShortIdCounter);
192
+ }
193
+ function rememberIMessageReplyCache(entry) {
194
+ hydrateFromStoreOnce();
195
+ const messageId = entry.messageId.trim();
196
+ if (!messageId) return {
197
+ ...entry,
198
+ shortId: ""
199
+ };
200
+ let shortId = imessageUuidToShortId.get(messageId);
201
+ if (!shortId) {
202
+ shortId = generateShortId();
203
+ imessageShortIdToUuid.set(shortId, messageId);
204
+ imessageUuidToShortId.set(messageId, shortId);
205
+ }
206
+ const fullEntry = buildReplyCacheEntry(entry, messageId, shortId);
207
+ imessageReplyCacheByMessageId.delete(messageId);
208
+ imessageReplyCacheByMessageId.set(messageId, fullEntry);
209
+ const cutoff = Date.now() - IMESSAGE_REPLY_CACHE_TTL_MS;
210
+ let evicted = false;
211
+ const deletedMessageIds = [];
212
+ for (const [key, value] of imessageReplyCacheByMessageId) {
213
+ if (value.timestamp >= cutoff) break;
214
+ imessageReplyCacheByMessageId.delete(key);
215
+ deletedMessageIds.push(key);
216
+ if (value.shortId) {
217
+ imessageShortIdToUuid.delete(value.shortId);
218
+ imessageUuidToShortId.delete(key);
219
+ }
220
+ evicted = true;
221
+ }
222
+ while (imessageReplyCacheByMessageId.size > IMESSAGE_REPLY_CACHE_MAX_ENTRIES) {
223
+ const oldest = imessageReplyCacheByMessageId.keys().next().value;
224
+ if (!oldest) break;
225
+ const oldEntry = imessageReplyCacheByMessageId.get(oldest);
226
+ imessageReplyCacheByMessageId.delete(oldest);
227
+ deletedMessageIds.push(oldest);
228
+ if (oldEntry?.shortId) {
229
+ imessageShortIdToUuid.delete(oldEntry.shortId);
230
+ imessageUuidToShortId.delete(oldest);
231
+ }
232
+ evicted = true;
233
+ }
234
+ if (evicted) for (const messageIdToDelete of deletedMessageIds) deleteReplyCacheEntry(messageIdToDelete);
235
+ persistReplyCacheEntry(fullEntry);
236
+ return fullEntry;
237
+ }
238
+ function hasChatScope(ctx) {
239
+ if (!ctx) return false;
240
+ return Boolean(normalizeOptionalString(ctx.chatGuid) || normalizeOptionalString(ctx.chatIdentifier) || typeof ctx.chatId === "number");
241
+ }
242
+ function isCrossChatMismatch(cached, ctx) {
243
+ return resolveIMessageChatMatch(cached, ctx) === "mismatch";
244
+ }
245
+ function describeChatForError(values) {
246
+ const parts = [];
247
+ if (normalizeOptionalString(values.chatGuid)) parts.push("chatGuid=<redacted>");
248
+ if (normalizeOptionalString(values.chatIdentifier)) parts.push("chatIdentifier=<redacted>");
249
+ if (typeof values.chatId === "number") parts.push("chatId=<redacted>");
250
+ return parts.length === 0 ? "<unknown chat>" : parts.join(", ");
251
+ }
252
+ function describeMessageIdForError(inputId, inputKind) {
253
+ if (inputKind === "short") return `<short:${inputId.length}-digit>`;
254
+ return `<uuid:${inputId.slice(0, 8)}...>`;
255
+ }
256
+ function buildCrossChatError(inputId, inputKind, cached, ctx) {
257
+ const remediation = inputKind === "short" ? "Use a message ID from the current chat target; MessageSidFull from another chat is rejected." : "Retry with the correct chat target.";
258
+ return /* @__PURE__ */ new Error(`iMessage message id ${describeMessageIdForError(inputId, inputKind)} belongs to a different chat (${describeChatForError(cached)}) than the current call target (${describeChatForError(ctx)}). ${remediation}`);
259
+ }
260
+ function resolveIMessageMessageId(shortOrUuid, opts) {
261
+ const trimmed = shortOrUuid.trim();
262
+ if (!trimmed) return trimmed;
263
+ hydrateFromStoreOnce();
264
+ if (/^\d+$/.test(trimmed)) {
265
+ const uuid = imessageShortIdToUuid.get(trimmed);
266
+ if (uuid) {
267
+ const cached = imessageReplyCacheByMessageId.get(uuid);
268
+ if (opts?.chatContext && hasChatScope(opts.chatContext)) {
269
+ if (cached && isCrossChatMismatch(cached, opts.chatContext)) throw buildCrossChatError(trimmed, "short", cached, opts.chatContext);
270
+ }
271
+ if (opts?.requireFromMe && cached?.isFromMe !== true) throw buildFromMeError(trimmed, "short");
272
+ return uuid;
273
+ }
274
+ if (opts?.requireKnownShortId && !hasChatScope(opts.chatContext)) throw new Error(`iMessage short message id ${describeMessageIdForError(trimmed, "short")} requires a chat scope (chatGuid / chatIdentifier / chatId or a target).`);
275
+ if (opts?.requireKnownShortId) throw new Error(`iMessage short message id ${describeMessageIdForError(trimmed, "short")} is no longer available. Use MessageSidFull.`);
276
+ return trimmed;
277
+ }
278
+ const cached = imessageReplyCacheByMessageId.get(trimmed);
279
+ if (opts?.chatContext) {
280
+ if (cached && isCrossChatMismatch(cached, opts.chatContext)) throw buildCrossChatError(trimmed, "uuid", cached, opts.chatContext);
281
+ }
282
+ if (opts?.requireFromMe && cached?.isFromMe !== true) throw buildFromMeError(trimmed, "uuid");
283
+ return trimmed;
284
+ }
285
+ function isKnownFromMeIMessageMessageId(messageId, ctx) {
286
+ const trimmed = normalizeOptionalString(messageId);
287
+ if (!trimmed || !ctx.accountId || !hasChatScope(ctx)) return false;
288
+ hydrateFromStoreOnce();
289
+ const cached = imessageReplyCacheByMessageId.get(trimmed);
290
+ if (!cached || cached.isFromMe !== true || cached.accountId !== ctx.accountId) return false;
291
+ return isPositiveIMessageChatMatch(cached, ctx);
292
+ }
293
+ function buildFromMeError(inputId, inputKind) {
294
+ return /* @__PURE__ */ new Error(`iMessage message id ${describeMessageIdForError(inputId, inputKind)} is not one this agent sent. edit and unsend can only target messages the gateway delivered itself; messages received from other participants cannot be modified.`);
295
+ }
296
+ /**
297
+ * Return the most recent cached entry whose chat scope matches the supplied
298
+ * context. Used as a fallback when an agent calls a per-message action (e.g.
299
+ * `react`) without specifying a `messageId` — the natural intent is "react
300
+ * to the message I just received in this chat."
301
+ *
302
+ * Strict semantics for safety:
303
+ * - Caller must supply a chat scope. We refuse to "guess" the active chat.
304
+ * - Cached entry must positively match on at least one identifier kind
305
+ * (chatGuid, chatIdentifier, chatId, or normalized direct-DM fingerprint).
306
+ * We do NOT fall through on "no overlapping identifier" — that's how a
307
+ * cached entry from a foreign chat could be returned when the caller's
308
+ * context didn't share any identifier kind with the cache.
309
+ * - Caller must supply an accountId; we never cross account boundaries.
310
+ * - We only consider entries newer than `LATEST_FALLBACK_MS`. The intent
311
+ * of "react to the latest" is "the message I just received," not
312
+ * "anything in this chat from any time."
313
+ */
314
+ function findLatestIMessageEntryForChat(ctx) {
315
+ if (!hasChatScope(ctx)) return;
316
+ if (!ctx.accountId) return;
317
+ const cutoff = Date.now() - LATEST_FALLBACK_MS;
318
+ let best;
319
+ for (const entry of imessageReplyCacheByMessageId.values()) {
320
+ if (entry.accountId !== ctx.accountId) continue;
321
+ if (entry.timestamp < cutoff) continue;
322
+ if (!isPositiveIMessageChatMatch(entry, ctx)) continue;
323
+ if (!best || entry.timestamp > best.timestamp) best = entry;
324
+ }
325
+ return best;
326
+ }
327
+ function resolveIMessageCachedResourceBinding(messageId, ctx) {
328
+ hydrateFromStoreOnce();
329
+ const entry = imessageReplyCacheByMessageId.get(messageId.trim());
330
+ if (!entry) return "unknown";
331
+ if (Date.now() - entry.timestamp > 216e5) return "unknown";
332
+ if (entry.accountId !== ctx.accountId) return "mismatch";
333
+ const chatMatch = resolveIMessageChatMatch(entry, ctx);
334
+ if (chatMatch !== "match") return chatMatch;
335
+ return "match";
336
+ }
337
+ function isIMessageCurrentMessageInChat(params) {
338
+ if (!params.accountId || !hasChatScope(params.chatContext)) return false;
339
+ const currentMessageId = normalizeOptionalString(String(params.currentMessageId));
340
+ if (!currentMessageId) return false;
341
+ hydrateFromStoreOnce();
342
+ const fullMessageId = /^\d+$/.test(currentMessageId) ? imessageShortIdToUuid.get(currentMessageId) : currentMessageId;
343
+ if (!fullMessageId) return false;
344
+ return resolveIMessageCachedResourceBinding(fullMessageId, {
345
+ ...params.chatContext,
346
+ accountId: params.accountId
347
+ }) === "match";
348
+ }
349
+ //#endregion
13
350
  //#region extensions/imessage/src/client.ts
14
351
  var IMessageRpcRequestError = class extends Error {
15
352
  constructor(message, code, data) {
@@ -329,35 +666,6 @@ function codeDelimiter(content) {
329
666
  const longestRun = Math.max(0, ...[...content.matchAll(/`+/gu)].map((match) => match[0].length));
330
667
  return "`".repeat(longestRun + 1);
331
668
  }
332
- function protectDunderIdentifiers(input) {
333
- const protections = [];
334
- let markdown = "";
335
- let cursor = 0;
336
- for (const match of input.matchAll(/__[\p{L}_][\p{L}\p{N}_]*__/gu)) {
337
- const identifier = match[0];
338
- const start = match.index ?? 0;
339
- const end = start + identifier.length;
340
- const before = input[start - 1];
341
- const beforeBefore = input[start - 2];
342
- const after = input[end];
343
- const member = before === ".";
344
- const call = after === "(";
345
- const functionArgument = before === "(" && /[\p{L}\p{N}_]/u.test(beforeBefore ?? "");
346
- if (!member && !call && !functionArgument && !(after === "[")) continue;
347
- let token = `OCdunder${protections.length}token`;
348
- while (input.includes(token)) token += "x";
349
- markdown += input.slice(cursor, start) + token;
350
- protections.push({
351
- token,
352
- identifier
353
- });
354
- cursor = end;
355
- }
356
- return {
357
- markdown: markdown + input.slice(cursor),
358
- protections
359
- };
360
- }
361
669
  function applyTextEdits(text, edits) {
362
670
  const ordered = edits.toSorted((left, right) => left.start - right.start);
363
671
  let rendered = "";
@@ -372,26 +680,6 @@ function applyTextEdits(text, edits) {
372
680
  mapOffset: (offset) => offset + ordered.reduce((delta, edit) => delta + (edit.end <= offset ? edit.text.length - edit.end + edit.start : 0), 0)
373
681
  };
374
682
  }
375
- function restoreDunderIdentifiers(text, ranges, codeRanges, protections) {
376
- const edited = applyTextEdits(text, protections.flatMap((protection) => {
377
- const start = text.indexOf(protection.token);
378
- return start === -1 ? [] : [{
379
- start,
380
- end: start + protection.token.length,
381
- text: protection.identifier
382
- }];
383
- }));
384
- const mapRange = (range) => ({
385
- ...range,
386
- start: edited.mapOffset(range.start),
387
- length: edited.mapOffset(range.start + range.length) - edited.mapOffset(range.start)
388
- });
389
- return {
390
- text: edited.text,
391
- ranges: ranges.map(mapRange),
392
- codeRanges: codeRanges.map(mapRange)
393
- };
394
- }
395
683
  function restoreCodeMarkers(text, ranges, codeRanges) {
396
684
  const edited = applyTextEdits(text, codeRanges.map((range) => {
397
685
  const end = range.start + range.length;
@@ -414,22 +702,21 @@ function restoreCodeMarkers(text, ranges, codeRanges) {
414
702
  };
415
703
  }
416
704
  function extractMarkdownFormatRuns(input) {
417
- const protectedDunders = protectDunderIdentifiers(input);
418
- const ir = markdownToIR(protectedDunders.markdown, {
705
+ const ir = markdownToIR(input, {
419
706
  autolink: false,
420
707
  enableHtmlUnderline: true,
421
708
  headingStyle: "rich",
422
709
  linkify: false,
710
+ preserveDunderIdentifiers: true,
423
711
  preserveSourceBlockSpacing: true
424
712
  });
425
713
  const rendered = renderMarkdownWithAttributedRanges(ir, { styleMap: IMESSAGE_STYLE_MAP }, IMESSAGE_FORMAT_PROFILE);
426
714
  const code = renderMarkdownWithAttributedRanges(ir, { styleMap: { code: "code" } }, IMESSAGE_CODE_PROFILE);
427
- const dunders = restoreDunderIdentifiers(rendered.text, rendered.ranges.map(({ start, length, style }) => ({
715
+ return restoreCodeMarkers(rendered.text, rendered.ranges.map(({ start, length, style }) => ({
428
716
  start,
429
717
  length,
430
718
  styles: [style]
431
- })), code.ranges, protectedDunders.protections);
432
- return restoreCodeMarkers(dunders.text, dunders.ranges, dunders.codeRanges);
719
+ })), code.ranges);
433
720
  }
434
721
  //#endregion
435
722
  //#region extensions/imessage/src/monitor/sanitize-outbound.ts
@@ -445,7 +732,7 @@ const FINAL_PRIVATE_MARKER_RE = /(?:#\+){2,}#?|\bassistant\s+to\s*=\s*\w+|^[ \t]
445
732
  const PRIVATE_USE_START = 57344;
446
733
  const PRIVATE_USE_END = 63743;
447
734
  const MAX_PRIVATE_MARKDOWN_UNWRAP_PASSES = 32;
448
- const PLAIN_TEXT_HTML_TAG_RE = /<\/?[a-z][a-z0-9_-]*\b[^>]*>/gi;
735
+ const PLAIN_TEXT_HTML_TAG_RE = /<\/?[a-z][a-z0-9_.:-]*(?=[\s/>])[^>]*>/gi;
449
736
  const PRIVATE_PROVIDER_TAG_NAMES = [
450
737
  "think",
451
738
  "thinking",
@@ -893,4 +1180,4 @@ function sanitizeOutboundText(text) {
893
1180
  return cleaned;
894
1181
  }
895
1182
  //#endregion
896
- export { IMessageRpcRequestError as a, DEFAULT_IMESSAGE_SEND_TIMEOUT_MS as c, extractMarkdownFormatRuns as i, sanitizeIMessageFinalOutboundText as n, createIMessageRpcClient as o, sanitizeOutboundText as r, DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS as s, protectIMessageFencedRoleMarkers as t };
1183
+ export { normalizeDirectChatIdentifier as _, IMessageRpcRequestError as a, isIMessageCurrentMessageInChat as c, resolveIMessageCachedResourceBinding as d, resolveIMessageMessageId as f, isIMessageEmailChatIdentifier as g, chatContextFromIMessageTarget as h, extractMarkdownFormatRuns as i, isKnownFromMeIMessageMessageId as l, DEFAULT_IMESSAGE_SEND_TIMEOUT_MS as m, sanitizeIMessageFinalOutboundText as n, createIMessageRpcClient as o, DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS as p, sanitizeOutboundText as r, findLatestIMessageEntryForChat as s, protectIMessageFencedRoleMarkers as t, rememberIMessageReplyCache as u, resolveIMessageDirectChatService as v };