@openclaw/imessage 2026.10.10 → 2026.11.5-beta.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 (137) hide show
  1. package/dist/.setup/{accounts-BH0coL46.mjs → accounts-C1Ypv3Wn.mjs} +6 -7
  2. package/dist/.setup/{actions-CW7XYYF4.mjs → actions-qOuKy8To.mjs} +360 -108
  3. package/dist/.setup/{actions.runtime-B2ZHQ3TJ.mjs → actions.runtime-Ccg9CARL.mjs} +10 -56
  4. package/dist/.setup/{api-6xi-NBrt.mjs → api-BXXuQQCS.mjs} +7 -7
  5. package/dist/.setup/{api-B0ih8Iof.mjs → api-DTbxSOPc.mjs} +8 -8
  6. package/dist/.setup/{approval-handler.runtime-BKmqba3L.mjs → approval-handler.runtime-B6vrFfZx.mjs} +112 -131
  7. package/dist/.setup/{approval-reactions-B9CJS0NT.mjs → approval-reactions-DBBsqbRC.mjs} +152 -72
  8. package/dist/.setup/{channel-6kcKpSRw.mjs → channel-CLaN4mQn.mjs} +142 -119
  9. package/dist/.setup/{channel.runtime-BW4A0m4h.mjs → channel.runtime-XJGx1MIH.mjs} +205 -363
  10. package/dist/.setup/chat-context-fTfJVqAi.mjs +77 -0
  11. package/dist/.setup/chat-lookup-xtPsOBkl.mjs +50 -0
  12. package/dist/.setup/client-D_BaG8sC.mjs +367 -0
  13. package/dist/.setup/{config-schema-DRkdRC21.mjs → config-schema-BjkQV5P5.mjs} +1 -2
  14. package/dist/.setup/{conversation-bindings-vZFn6sN2.mjs → conversation-bindings-8DjxoIYU.mjs} +9 -6
  15. package/dist/.setup/{media-contract-CoixpXRX.mjs → media-contract-BErFBKV9.mjs} +1 -1
  16. package/dist/.setup/{message-tool-api-CxSY_rh7.mjs → message-tool-api-DtZ1wKbT.mjs} +3 -6
  17. package/dist/.setup/{remote-file-CCgMYZ-u.mjs → remote-file-DpK3GQFD.mjs} +8 -22
  18. package/dist/.setup/{sanitize-outbound-C02fJrn6.mjs → sanitize-outbound-Dhjhz0a-.mjs} +23 -27
  19. package/dist/.setup/{send-D98hQFdv.mjs → send-DhEW0gfe.mjs} +150 -226
  20. package/dist/.setup/{setup-core-BWnW0czE.mjs → setup-core-B1_P_t4T.mjs} +2 -2
  21. package/dist/.setup/{setup-surface-aRZhAzzQ.mjs → setup-surface-CD28mXWK.mjs} +11 -25
  22. package/dist/.setup/{targets-CIx4BKqL.mjs → targets-C7CIWJ0k.mjs} +12 -3
  23. package/dist/.source-module-urls/929c518fa2986b0f85f66bceefead22868db0ab452dee914dc6a2bb86b2e60ad.json +1 -1
  24. package/dist/api.js +8 -8
  25. package/dist/channel-config-api.js +1 -1
  26. package/dist/channel-plugin-api.js +1 -1
  27. package/dist/contract-api.js +1 -1
  28. package/dist/media-contract-api.js +1 -1
  29. package/dist/message-tool-api.js +1 -1
  30. package/dist/runtime-api.js +1 -3
  31. package/dist/session-binding-contract-api.js +1 -1
  32. package/dist/setup-entry.js +1 -1
  33. package/dist/src/chat-db.worker.js +1 -1
  34. package/node_modules/typebox/build/format/duration.d.mts +2 -2
  35. package/node_modules/typebox/build/format/duration.mjs +2 -2
  36. package/node_modules/typebox/build/format/idn_email.d.mts +1 -0
  37. package/node_modules/typebox/build/format/idn_email.mjs +1 -0
  38. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -1
  39. package/node_modules/typebox/build/format/idn_hostname.mjs +1 -1
  40. package/node_modules/typebox/build/format/ipv4.d.mts +2 -2
  41. package/node_modules/typebox/build/format/ipv4.mjs +2 -2
  42. package/node_modules/typebox/build/format/ipv6.d.mts +1 -1
  43. package/node_modules/typebox/build/format/ipv6.mjs +1 -1
  44. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  45. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  46. package/node_modules/typebox/build/schema/build.mjs +1 -0
  47. package/node_modules/typebox/build/schema/engine/_unique.d.mts +4 -2
  48. package/node_modules/typebox/build/schema/engine/_unique.mjs +7 -3
  49. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +3 -3
  50. package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +0 -3
  51. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +15 -17
  52. package/node_modules/typebox/build/schema/engine/contains.mjs +3 -3
  53. package/node_modules/typebox/build/schema/engine/index.d.mts +1 -0
  54. package/node_modules/typebox/build/schema/engine/index.mjs +1 -0
  55. package/node_modules/typebox/build/schema/engine/items.mjs +7 -4
  56. package/node_modules/typebox/build/schema/engine/maxContains.mjs +2 -2
  57. package/node_modules/typebox/build/schema/engine/minContains.mjs +3 -3
  58. package/node_modules/typebox/build/schema/engine/oneOf.mjs +2 -2
  59. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +2 -2
  60. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -2
  61. package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +2 -2
  62. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +2 -2
  63. package/node_modules/typebox/build/system/hashing/hash.mjs +63 -34
  64. package/node_modules/typebox/build/system/locale/en_US.mjs +2 -1
  65. package/node_modules/typebox/build/system/memory/assign.d.mts +2 -8
  66. package/node_modules/typebox/build/system/memory/assign.mjs +13 -6
  67. package/node_modules/typebox/build/system/memory/clone.d.mts +4 -5
  68. package/node_modules/typebox/build/system/memory/clone.mjs +8 -96
  69. package/node_modules/typebox/build/system/memory/create.d.mts +1 -5
  70. package/node_modules/typebox/build/system/memory/create.mjs +18 -13
  71. package/node_modules/typebox/build/system/memory/deep.d.mts +2 -0
  72. package/node_modules/typebox/build/system/memory/deep.mjs +108 -0
  73. package/node_modules/typebox/build/system/memory/discard.d.mts +1 -1
  74. package/node_modules/typebox/build/system/memory/discard.mjs +9 -8
  75. package/node_modules/typebox/build/system/memory/finalize.d.mts +4 -0
  76. package/node_modules/typebox/build/system/memory/finalize.mjs +30 -0
  77. package/node_modules/typebox/build/system/memory/keys.d.mts +2 -0
  78. package/node_modules/typebox/build/system/memory/keys.mjs +8 -0
  79. package/node_modules/typebox/build/system/memory/update.d.mts +1 -4
  80. package/node_modules/typebox/build/system/memory/update.mjs +43 -16
  81. package/node_modules/typebox/build/type/engine/call/index.d.mts +1 -0
  82. package/node_modules/typebox/build/type/engine/call/index.mjs +1 -0
  83. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +2 -24
  84. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +2 -29
  85. package/node_modules/typebox/build/type/engine/evaluate/index.d.mts +1 -0
  86. package/node_modules/typebox/build/type/engine/evaluate/index.mjs +1 -0
  87. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +5 -1
  88. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +6 -1
  89. package/node_modules/typebox/build/type/engine/evaluate/property.d.mts +30 -0
  90. package/node_modules/typebox/build/type/engine/evaluate/property.mjs +29 -0
  91. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +1 -3
  92. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +1 -4
  93. package/node_modules/typebox/build/type/engine/object/from_intersect.d.mts +2 -2
  94. package/node_modules/typebox/build/type/engine/object/from_intersect.mjs +2 -2
  95. package/node_modules/typebox/build/type/engine/object/from_union.d.mts +2 -2
  96. package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
  97. package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +1 -3
  98. package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +1 -4
  99. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +1 -3
  100. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +1 -4
  101. package/node_modules/typebox/build/type/engine/this/index.d.mts +1 -0
  102. package/node_modules/typebox/build/type/engine/this/index.mjs +1 -0
  103. package/node_modules/typebox/build/value/clone/clone.d.mts +4 -3
  104. package/node_modules/typebox/build/value/clone/clone.mjs +5 -7
  105. package/node_modules/typebox/build/value/repair/from_cyclic.d.mts +2 -0
  106. package/node_modules/typebox/build/value/repair/from_cyclic.mjs +6 -0
  107. package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +25 -14
  108. package/node_modules/typebox/package.json +1 -1
  109. package/node_modules/typebox/readme.md +1 -1
  110. package/node_modules/zod/package.json +1 -1
  111. package/node_modules/zod/src/v4/classic/tests/array.test.ts +27 -0
  112. package/node_modules/zod/src/v4/classic/tests/map.test.ts +7 -0
  113. package/node_modules/zod/src/v4/classic/tests/set.test.ts +6 -0
  114. package/node_modules/zod/src/v4/core/compile.ts +9 -0
  115. package/node_modules/zod/src/v4/core/schemas.ts +35 -1
  116. package/node_modules/zod/src/v4/core/util.ts +13 -0
  117. package/node_modules/zod/src/v4/core/versions.ts +1 -1
  118. package/node_modules/zod/v4/core/compile.cjs +8 -0
  119. package/node_modules/zod/v4/core/compile.js +8 -0
  120. package/node_modules/zod/v4/core/schemas.cjs +30 -0
  121. package/node_modules/zod/v4/core/schemas.d.cts +3 -1
  122. package/node_modules/zod/v4/core/schemas.d.ts +3 -1
  123. package/node_modules/zod/v4/core/schemas.js +30 -0
  124. package/node_modules/zod/v4/core/util.cjs +15 -0
  125. package/node_modules/zod/v4/core/util.d.cts +2 -0
  126. package/node_modules/zod/v4/core/util.d.ts +2 -0
  127. package/node_modules/zod/v4/core/util.js +14 -0
  128. package/node_modules/zod/v4/core/versions.cjs +1 -1
  129. package/node_modules/zod/v4/core/versions.js +1 -1
  130. package/openclaw.plugin.json +0 -30
  131. package/package.json +6 -6
  132. package/dist/.setup/client-C3e7ZLqA.mjs +0 -739
  133. package/dist/.setup/question-reactions-DTj-VH3N.mjs +0 -67
  134. package/dist/.setup/reaction-context-Bw00FkmU.mjs +0 -105
  135. package/dist/.setup/runtime-BRQCPuAD.mjs +0 -7
  136. package/node_modules/typebox/build/system/memory/freeze.d.mts +0 -4
  137. package/node_modules/typebox/build/system/memory/freeze.mjs +0 -6
@@ -1,739 +0,0 @@
1
- import { u as expandIMessageUserPath } from "./accounts-BH0coL46.mjs";
2
- import { i as invalidateCachedIMessagePrivateApiStatus } from "./message-tool-api-CxSY_rh7.mjs";
3
- import { t as getIMessageRuntime } from "./runtime-BRQCPuAD.mjs";
4
- import { asNullableRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
- import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution";
6
- import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
7
- import { createHash } from "node:crypto";
8
- import { runCommandWithTimeout } from "openclaw/plugin-sdk/process-runtime";
9
- import { resolveUserPath } from "openclaw/plugin-sdk/text-utility-runtime";
10
- import { spawn } from "node:child_process";
11
- import { StringDecoder } from "node:string_decoder";
12
- import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
13
- import { captureChannelReadAuthority, captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
14
- import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
15
- // extensions/imessage/src/chat-context.ts
16
- const EMAIL_HANDLE_PATTERN = /^[^\s@]+@[^\s@]+$/u;
17
- function parseDirectChatIdentity(raw) {
18
- const trimmed = raw.trim();
19
- const parts = trimmed.split(";");
20
- if (parts.length === 3 && parts[1] === "-" && parts[2]) {
21
- const service = parts[0]?.toLowerCase();
22
- if (service === "imessage" || service === "sms" || service === "any") {
23
- const identifier = parts[2];
24
- return {
25
- service,
26
- identifier: EMAIL_HANDLE_PATTERN.test(identifier) ? identifier.toLowerCase() : identifier
27
- };
28
- }
29
- }
30
- if (parts.length !== 1) return;
31
- if (trimmed.startsWith("+") || EMAIL_HANDLE_PATTERN.test(trimmed)) return { identifier: trimmed.toLowerCase() };
32
- }
33
- function resolveIMessageDirectChatService(configuredService, chatGuid) {
34
- if (configuredService === "imessage" || configuredService === "sms") return configuredService;
35
- const observedService = chatGuid ? parseDirectChatIdentity(chatGuid)?.service : void 0;
36
- return observedService === "imessage" || observedService === "sms" ? observedService : void 0;
37
- }
38
- function isIMessageEmailChatIdentifier(raw) {
39
- const identity = parseDirectChatIdentity(raw);
40
- return Boolean(identity && EMAIL_HANDLE_PATTERN.test(identity.identifier));
41
- }
42
- /**
43
- * Strip the `iMessage;-;` / `SMS;-;` / `any;-;` service prefix that Messages
44
- * uses for direct chats. Different layers report direct DMs in different
45
- * forms, so raw comparison would falsely treat one DM as different chats.
46
- */
47
- function normalizeDirectChatIdentifier(raw) {
48
- const trimmed = raw.trim();
49
- return parseDirectChatIdentity(trimmed)?.identifier ?? trimmed;
50
- }
51
- function chatContextFromIMessageTarget(target, effectiveService) {
52
- if (target.kind === "chat_id") return { chatId: target.chatId };
53
- if (target.kind === "chat_guid") return { chatGuid: target.chatGuid };
54
- if (target.kind === "chat_identifier") return { chatIdentifier: target.chatIdentifier };
55
- const trimmedHandle = target.to.trim();
56
- const canonicalHandle = trimmedHandle.startsWith("+") ? normalizeE164(trimmedHandle) : EMAIL_HANDLE_PATTERN.test(trimmedHandle) ? trimmedHandle.toLowerCase() : void 0;
57
- if (!canonicalHandle) return {};
58
- const service = target.service === "auto" ? effectiveService : target.service;
59
- if (service !== "imessage" && service !== "sms") return {};
60
- return { chatIdentifier: `${service === "sms" ? "SMS" : "iMessage"};-;${canonicalHandle}` };
61
- }
62
- function compareOptional(left, right) {
63
- return left === void 0 || right === void 0 ? void 0 : left === right;
64
- }
65
- function compareChatSelector(cachedRaw, currentRaw, crossKind = false) {
66
- const cached = normalizeOptionalString(cachedRaw);
67
- const current = normalizeOptionalString(currentRaw);
68
- if (!cached || !current) return;
69
- if (cached === current) return true;
70
- const cachedDirect = parseDirectChatIdentity(cached);
71
- const currentDirect = parseDirectChatIdentity(current);
72
- if (!cachedDirect || !currentDirect) return crossKind ? void 0 : false;
73
- if (cachedDirect.identifier !== currentDirect.identifier) return false;
74
- if (cachedDirect.service === "any") return true;
75
- if (!cachedDirect.service || !currentDirect.service) return;
76
- return cachedDirect.service === currentDirect.service;
77
- }
78
- function resolveIMessageChatMatch(cached, current) {
79
- const comparisons = [
80
- compareChatSelector(cached.chatGuid, current.chatGuid),
81
- compareChatSelector(cached.chatIdentifier, current.chatIdentifier),
82
- compareOptional(cached.chatId, current.chatId),
83
- compareChatSelector(cached.chatGuid, current.chatIdentifier, true),
84
- compareChatSelector(cached.chatIdentifier, current.chatGuid, true)
85
- ].filter((comparison) => comparison !== void 0);
86
- if (comparisons.length === 0) return "unknown";
87
- return comparisons.every(Boolean) ? "match" : "mismatch";
88
- }
89
- // extensions/imessage/src/constants.ts
90
- const DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS = 1e4;
91
- const DEFAULT_IMESSAGE_SEND_TIMEOUT_MS = 18e4;
92
- // extensions/imessage/src/state-contract.ts
93
- const IMESSAGE_REPLY_CACHE_NAMESPACE = "imessage.reply-cache";
94
- const IMESSAGE_REPLY_CACHE_MAX_ENTRIES = 2e3;
95
- const IMESSAGE_REPLY_CACHE_COUNTER_NAMESPACE = "imessage.reply-cache-counter";
96
- const IMESSAGE_REPLY_CACHE_COUNTER_KEY = "short-id-counter";
97
- const IMESSAGE_REPLY_CACHE_TTL_MS = 216e5;
98
- function resolveIMessageReplyCacheEntryKey(messageId) {
99
- return createHash("sha256").update(messageId, "utf8").digest("hex").slice(0, 32);
100
- }
101
- const MAX_FAILURE_RETRY_MAP_SIZE = 512;
102
- const MAX_FAILURE_RETRY_MAP_JSON_BYTES = 48e3;
103
- const textEncoder = new TextEncoder();
104
- const IMESSAGE_CATCHUP_CURSOR_NAMESPACE = "imessage.catchup-cursors";
105
- function resolveIMessageCatchupCursorKey(accountId) {
106
- return createHash("sha256").update(accountId, "utf8").digest("hex").slice(0, 32);
107
- }
108
- /**
109
- * Bound the retry map so a pathological storm of unique failing GUIDs
110
- * cannot grow the cursor value without limit. Keeps the `maxSize` entries
111
- * with the highest counts (closest to give-up) when over the bound.
112
- */
113
- function capFailureRetriesMap(map, maxSize = MAX_FAILURE_RETRY_MAP_SIZE, maxBytes = MAX_FAILURE_RETRY_MAP_JSON_BYTES) {
114
- const entries = Object.entries(map);
115
- if (entries.length <= maxSize && textEncoder.encode(JSON.stringify(map)).byteLength <= maxBytes) return map;
116
- entries.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
117
- const capped = {};
118
- for (const [guid, count] of entries.slice(0, maxSize)) {
119
- capped[guid] = count;
120
- if (textEncoder.encode(JSON.stringify(capped)).byteLength > maxBytes) {
121
- delete capped[guid];
122
- break;
123
- }
124
- }
125
- return capped;
126
- }
127
- const IMESSAGE_SENT_ECHOES_TTL_MS = 432e5;
128
- const IMESSAGE_SENT_ECHOES_NAMESPACE = "imessage.sent-echoes";
129
- function resolveIMessageSentEchoEntryKey(entry) {
130
- return createHash("sha256").update(JSON.stringify([
131
- entry.scope,
132
- entry.text ?? "",
133
- resolveIMessageEchoMediaKey(entry.media) ?? "",
134
- entry.messageId ?? "",
135
- entry.timestamp
136
- ])).digest("hex").slice(0, 32);
137
- }
138
- function resolveIMessageEchoMediaKey(media) {
139
- const contentType = media?.contentType?.trim().toLowerCase() || void 0;
140
- const kind = media?.kind && media.kind !== "unknown" ? media.kind : void 0;
141
- if (kind) return `kind:${kind}`;
142
- const normalizedContentType = contentType?.split(";", 1)[0]?.trim();
143
- return normalizedContentType ? `mime:${normalizedContentType}` : void 0;
144
- }
145
- // extensions/imessage/src/monitor-reply-cache.ts
146
- /** Recency window for the "react to the latest message" fallback. */
147
- const LATEST_FALLBACK_MS = 6e5;
148
- let persistenceFailureLogged = false;
149
- function reportPersistenceFailure(scope, err) {
150
- if (persistenceFailureLogged) return;
151
- persistenceFailureLogged = true;
152
- logVerbose(`imessage reply-cache: ${scope} disabled after first failure: ${String(err)}`);
153
- }
154
- const imessageReplyCacheByMessageId = /* @__PURE__ */ new Map();
155
- const imessageShortIdToUuid = /* @__PURE__ */ new Map();
156
- let imessageShortIdCounter = 0;
157
- function openReplyCacheStore() {
158
- return getIMessageRuntime().state.openKeyedStoreV2({
159
- namespace: IMESSAGE_REPLY_CACHE_NAMESPACE,
160
- maxEntries: IMESSAGE_REPLY_CACHE_MAX_ENTRIES
161
- });
162
- }
163
- function openReplyCacheCounterStore() {
164
- return getIMessageRuntime().state.openKeyedStoreV2({
165
- namespace: IMESSAGE_REPLY_CACHE_COUNTER_NAMESPACE,
166
- maxEntries: 1
167
- });
168
- }
169
- function remainingTtlMs(timestamp) {
170
- const remaining = IMESSAGE_REPLY_CACHE_TTL_MS - Math.max(0, Date.now() - timestamp);
171
- return remaining > 0 ? remaining : void 0;
172
- }
173
- let hydrated = false;
174
- let hydration;
175
- let persistence = Promise.resolve();
176
- function hydrateCounter(counter) {
177
- if (counter && Number.isSafeInteger(counter.counter) && counter.counter > 0) imessageShortIdCounter = Math.max(imessageShortIdCounter, counter.counter);
178
- }
179
- function hydrateRows(entries) {
180
- const cutoff = Date.now() - IMESSAGE_REPLY_CACHE_TTL_MS;
181
- for (const entry of entries.filter((cached) => cached.timestamp >= cutoff).toSorted((a, b) => a.timestamp - b.timestamp).slice(-2e3)) {
182
- const numeric = Number.parseInt(entry.shortId, 10);
183
- if (Number.isFinite(numeric) && numeric > imessageShortIdCounter) imessageShortIdCounter = numeric;
184
- imessageReplyCacheByMessageId.set(entry.messageId, entry);
185
- imessageShortIdToUuid.set(entry.shortId, entry.messageId);
186
- }
187
- }
188
- async function hydrateFromStoreOnce() {
189
- if (hydrated) return;
190
- hydration ??= (async () => {
191
- try {
192
- hydrateCounter(await openReplyCacheCounterStore().lookup(IMESSAGE_REPLY_CACHE_COUNTER_KEY));
193
- hydrateRows((await openReplyCacheStore().entries()).map(({ value }) => value));
194
- } catch (err) {
195
- reportPersistenceFailure("read", err);
196
- } finally {
197
- hydrated = true;
198
- }
199
- })();
200
- await hydration;
201
- }
202
- async function persistReplyCacheEntry(entry) {
203
- const ttlMs = remainingTtlMs(entry.timestamp);
204
- if (!ttlMs) return;
205
- try {
206
- await openReplyCacheStore().register(resolveIMessageReplyCacheEntryKey(entry.messageId), entry, { ttlMs });
207
- } catch (err) {
208
- reportPersistenceFailure("write", err);
209
- }
210
- }
211
- async function deleteReplyCacheEntry(messageId) {
212
- try {
213
- await openReplyCacheStore().delete(resolveIMessageReplyCacheEntryKey(messageId));
214
- } catch (err) {
215
- reportPersistenceFailure("delete", err);
216
- }
217
- }
218
- async function persistReplyCacheCounter(counter) {
219
- try {
220
- await openReplyCacheCounterStore().register(IMESSAGE_REPLY_CACHE_COUNTER_KEY, { counter });
221
- } catch (err) {
222
- reportPersistenceFailure("counter", err);
223
- }
224
- }
225
- function buildReplyCacheEntry(entry, messageId, shortId) {
226
- return {
227
- accountId: entry.accountId,
228
- messageId,
229
- shortId,
230
- timestamp: entry.timestamp,
231
- ...typeof entry.chatGuid === "string" ? { chatGuid: entry.chatGuid } : {},
232
- ...typeof entry.chatIdentifier === "string" ? { chatIdentifier: entry.chatIdentifier } : {},
233
- ...typeof entry.chatId === "number" ? { chatId: entry.chatId } : {},
234
- ...typeof entry.isFromMe === "boolean" ? { isFromMe: entry.isFromMe } : {}
235
- };
236
- }
237
- async function rememberIMessageReplyCache(entry) {
238
- await hydrateFromStoreOnce();
239
- const messageId = entry.messageId.trim();
240
- if (!messageId) return {
241
- ...entry,
242
- shortId: ""
243
- };
244
- let shortId = imessageReplyCacheByMessageId.get(messageId)?.shortId;
245
- const isNewMessage = !shortId;
246
- if (!shortId) {
247
- shortId = String(++imessageShortIdCounter);
248
- imessageShortIdToUuid.set(shortId, messageId);
249
- }
250
- const fullEntry = buildReplyCacheEntry(entry, messageId, shortId);
251
- imessageReplyCacheByMessageId.delete(messageId);
252
- imessageReplyCacheByMessageId.set(messageId, fullEntry);
253
- const cutoff = Date.now() - IMESSAGE_REPLY_CACHE_TTL_MS;
254
- const deletedMessageIds = [];
255
- const pruneUntil = (retain) => {
256
- for (const [key, cached] of imessageReplyCacheByMessageId) {
257
- if (retain(key, cached)) break;
258
- imessageReplyCacheByMessageId.delete(key);
259
- deletedMessageIds.push(key);
260
- if (cached.shortId) imessageShortIdToUuid.delete(cached.shortId);
261
- }
262
- };
263
- pruneUntil((_key, cached) => cached.timestamp >= cutoff);
264
- pruneUntil((key) => !key || imessageReplyCacheByMessageId.size <= 2e3);
265
- const counter = imessageShortIdCounter;
266
- persistence = persistence.then(async () => {
267
- if (isNewMessage) await persistReplyCacheCounter(counter);
268
- for (const messageIdToDelete of deletedMessageIds) await deleteReplyCacheEntry(messageIdToDelete);
269
- await persistReplyCacheEntry(fullEntry);
270
- });
271
- await persistence;
272
- return fullEntry;
273
- }
274
- function hasChatScope(ctx) {
275
- if (!ctx) return false;
276
- return Boolean(normalizeOptionalString(ctx.chatGuid) || normalizeOptionalString(ctx.chatIdentifier) || typeof ctx.chatId === "number");
277
- }
278
- function describeChatForError(values) {
279
- const parts = [];
280
- if (normalizeOptionalString(values.chatGuid)) parts.push("chatGuid=<redacted>");
281
- if (normalizeOptionalString(values.chatIdentifier)) parts.push("chatIdentifier=<redacted>");
282
- if (typeof values.chatId === "number") parts.push("chatId=<redacted>");
283
- return parts.length === 0 ? "<unknown chat>" : parts.join(", ");
284
- }
285
- function describeMessageIdForError(inputId, inputKind) {
286
- if (inputKind === "short") return `<short:${inputId.length}-digit>`;
287
- return `<uuid:${inputId.slice(0, 8)}...>`;
288
- }
289
- function buildCrossChatError(inputId, inputKind, cached, ctx) {
290
- 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.";
291
- 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}`);
292
- }
293
- async function resolveIMessageMessageId(shortOrUuid, opts) {
294
- const trimmed = shortOrUuid.trim();
295
- if (!trimmed) return trimmed;
296
- await hydrateFromStoreOnce();
297
- const inputKind = /^\d+$/.test(trimmed) ? "short" : "uuid";
298
- const messageId = inputKind === "short" ? imessageShortIdToUuid.get(trimmed) : trimmed;
299
- if (!messageId) {
300
- if (opts?.requireKnownShortId) {
301
- if (!hasChatScope(opts.chatContext)) throw new Error(`iMessage short message id ${describeMessageIdForError(trimmed, "short")} requires a chat scope (chatGuid / chatIdentifier / chatId or a target).`);
302
- throw new Error(`iMessage short message id ${describeMessageIdForError(trimmed, "short")} is no longer available. Use MessageSidFull.`);
303
- }
304
- return trimmed;
305
- }
306
- const cached = imessageReplyCacheByMessageId.get(messageId);
307
- if (cached && opts?.chatContext && (inputKind === "uuid" || hasChatScope(opts.chatContext)) && resolveIMessageChatMatch(cached, opts.chatContext) === "mismatch") throw buildCrossChatError(trimmed, inputKind, cached, opts.chatContext);
308
- if (opts?.requireFromMe && cached?.isFromMe !== true) throw buildFromMeError(trimmed, inputKind);
309
- return messageId;
310
- }
311
- async function isKnownFromMeIMessageMessageId(messageId, ctx) {
312
- const trimmed = normalizeOptionalString(messageId);
313
- if (!trimmed || !ctx.accountId || !hasChatScope(ctx)) return false;
314
- await hydrateFromStoreOnce();
315
- const cached = imessageReplyCacheByMessageId.get(trimmed);
316
- if (!cached || cached.isFromMe !== true) return false;
317
- return resolveCachedResourceBinding(trimmed, {
318
- ...ctx,
319
- accountId: ctx.accountId
320
- }) === "match";
321
- }
322
- async function isKnownFromMeIMessageTarget(params) {
323
- const { accountId, chatId, chatGuid, chatIdentifier } = params;
324
- const ctx = {
325
- accountId,
326
- chatId,
327
- chatGuid,
328
- chatIdentifier
329
- };
330
- const isKnownFromMe = params.isKnownFromMeMessageId ?? isKnownFromMeIMessageMessageId;
331
- for (const messageId of params.messageIds) if (await isKnownFromMe(messageId, ctx)) return true;
332
- return false;
333
- }
334
- function buildFromMeError(inputId, inputKind) {
335
- 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.`);
336
- }
337
- /** Latest recent entry with a positive same-account conversation match; never guess a chat. */
338
- function findLatestIMessageEntryForChat(ctx) {
339
- if (!hasChatScope(ctx) || !ctx.accountId) return;
340
- const cutoff = Date.now() - LATEST_FALLBACK_MS;
341
- let best;
342
- for (const entry of imessageReplyCacheByMessageId.values()) {
343
- if (entry.accountId !== ctx.accountId) continue;
344
- if (entry.timestamp < cutoff) continue;
345
- if (resolveIMessageChatMatch(entry, ctx) !== "match") continue;
346
- if (!best || entry.timestamp > best.timestamp) best = entry;
347
- }
348
- return best;
349
- }
350
- async function resolveIMessageCachedResourceBinding(messageId, ctx) {
351
- await hydrateFromStoreOnce();
352
- return resolveCachedResourceBinding(messageId, ctx);
353
- }
354
- function resolveCachedResourceBinding(messageId, ctx) {
355
- const entry = imessageReplyCacheByMessageId.get(messageId.trim());
356
- if (!entry) return "unknown";
357
- if (Date.now() - entry.timestamp > 216e5) return "unknown";
358
- if (entry.accountId !== ctx.accountId) return "mismatch";
359
- return resolveIMessageChatMatch(entry, ctx);
360
- }
361
- async function isIMessageCurrentMessageInChatAsync(params) {
362
- await hydrateFromStoreOnce();
363
- return isCurrentMessageInChat(params);
364
- }
365
- function isCurrentMessageInChat(params) {
366
- if (!params.accountId || !hasChatScope(params.chatContext)) return false;
367
- const currentMessageId = normalizeOptionalString(String(params.currentMessageId));
368
- if (!currentMessageId) return false;
369
- const fullMessageId = /^\d+$/.test(currentMessageId) ? imessageShortIdToUuid.get(currentMessageId) : currentMessageId;
370
- if (!fullMessageId) return false;
371
- return resolveCachedResourceBinding(fullMessageId, {
372
- ...params.chatContext,
373
- accountId: params.accountId
374
- }) === "match";
375
- }
376
- // extensions/imessage/src/cli-output.ts
377
- const IMESSAGE_CLI_STDOUT_MAX_BYTES = 8388608;
378
- const IMESSAGE_CLI_STDERR_TAIL_BYTES = 65536;
379
- function parseLastJsonObject(stdout) {
380
- const last = stdout.split(/\r?\n/u).findLast((line) => line.trim().length > 0)?.trim();
381
- if (!last) return null;
382
- try {
383
- return asNullableRecord(JSON.parse(last));
384
- } catch {
385
- return null;
386
- }
387
- }
388
- async function runIMessageCliJsonCommand(params) {
389
- const dbPath = params.dbPath?.trim();
390
- const argv = [
391
- expandIMessageUserPath(params.cliPath),
392
- ...params.args,
393
- ...dbPath ? ["--db", dbPath] : [],
394
- "--json"
395
- ];
396
- const result = await runCommandWithTimeout(argv, {
397
- killProcessTree: true,
398
- maxOutputBytes: {
399
- stdout: IMESSAGE_CLI_STDOUT_MAX_BYTES,
400
- stderr: IMESSAGE_CLI_STDERR_TAIL_BYTES
401
- },
402
- outputCapture: {
403
- stdout: "head",
404
- stderr: "tail"
405
- },
406
- terminateOnOutputLimit: { stdout: true },
407
- timeoutMs: params.timeoutMs
408
- });
409
- if (result.termination === "timeout") throw new Error(`iMessage action timed out after ${params.timeoutMs}ms`);
410
- if (result.outputLimitExceeded || result.stdoutTruncatedBytes) throw new Error(`imsg stdout exceeded ${IMESSAGE_CLI_STDOUT_MAX_BYTES} bytes`);
411
- const parsed = parseLastJsonObject(result.stdout);
412
- if (result.code !== 0) {
413
- const detail = typeof parsed?.error === "string" && parsed.error.trim() || result.stderr.trim() || result.stdout.trim() || `imsg exited with code ${result.code}`;
414
- throw new Error(detail);
415
- }
416
- if (!parsed) throw new Error(`imsg returned non-JSON output: ${result.stdout.trim() || result.stderr.trim()}`);
417
- if (parsed.success === false) {
418
- const detail = typeof parsed.error === "string" && parsed.error.trim() ? parsed.error.trim() : "iMessage action failed";
419
- throw new Error(detail);
420
- }
421
- return parsed;
422
- }
423
- // extensions/imessage/src/bridge-recovery.ts
424
- const BRIDGE_RECOVERY_TIMEOUT_MS = 3e4;
425
- const recoveries = /* @__PURE__ */ new Map();
426
- /**
427
- * Re-inject the private bridge after imsg has positively identified it as
428
- * unresponsive. This deliberately does not retry the failed mutation: imsg may
429
- * still reconcile a published send, so replaying it could duplicate a message.
430
- */
431
- function recoverIMessageBridge(cliPath) {
432
- const existing = recoveries.get(cliPath);
433
- if (existing) return existing;
434
- const recovery = runIMessageCliJsonCommand({
435
- cliPath,
436
- args: ["launch"],
437
- timeoutMs: BRIDGE_RECOVERY_TIMEOUT_MS
438
- }).then(() => void 0).finally(() => {
439
- recoveries.delete(cliPath);
440
- });
441
- recoveries.set(cliPath, recovery);
442
- return recovery;
443
- }
444
- // extensions/imessage/src/client.ts
445
- const IMSG_APPLE_FRAMEWORK_STDERR_PATTERN = /^(?:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+ imsg\[\d+:\d+\] )?Could not fetch group for change type \d+ with identifier [^:]+:ABGroup, making it a delete change type\.$/u;
446
- var IMessageRpcRequestError = class extends Error {
447
- constructor(message, code, data) {
448
- super(message);
449
- this.code = code;
450
- this.data = data;
451
- this.name = "IMessageRpcRequestError";
452
- }
453
- };
454
- function isIMessageBridgeStall(error) {
455
- if (error instanceof IMessageRpcRequestError && isRecord(error.data)) {
456
- const { transport, detail } = error.data;
457
- if (transport === "bridge_v2" && typeof detail === "string" && detail.startsWith("The bridge response deadline expired.")) return true;
458
- }
459
- return error instanceof Error && error.message.includes("Timed out waiting for response");
460
- }
461
- const BRIDGE_STALL_GUIDANCE = "The imsg private API bridge stopped responding. Run `imsg launch` to re-inject the dylib, then `openclaw channels status --probe` to refresh capability detection.";
462
- function describeIMessageBridgeStall(error) {
463
- if (error instanceof IMessageRpcRequestError) return new IMessageRpcRequestError(`${error.message} ${BRIDGE_STALL_GUIDANCE}`, error.code, error.data);
464
- if (error instanceof Error) return new Error(`${error.message} ${BRIDGE_STALL_GUIDANCE}`, { cause: error });
465
- return error;
466
- }
467
- const PUBLIC_IMESSAGE_FULL_DISK_ACCESS_ERROR = "imsg cannot access ~/Library/Messages/chat.db. Grant Full Disk Access to the Gateway/launcher process and restart Gateway.";
468
- const IMESSAGE_RPC_CLOSE_GRACE_MS = 500;
469
- function isTestEnv() {
470
- const vitest = normalizeLowercaseStringOrEmpty(process.env.VITEST);
471
- return Boolean(vitest);
472
- }
473
- function normalizeIMessageFullDiskAccessError(message) {
474
- const normalized = normalizeLowercaseStringOrEmpty(message);
475
- if (!normalized.includes("full disk access") || !normalized.includes("chat.db")) return;
476
- return PUBLIC_IMESSAGE_FULL_DISK_ACCESS_ERROR;
477
- }
478
- function createLfLineFramer(onLine) {
479
- const decoder = new StringDecoder("utf8");
480
- let buffer = "";
481
- return {
482
- write(chunk) {
483
- buffer += typeof chunk === "string" ? chunk : decoder.write(chunk);
484
- let newlineIndex = buffer.indexOf("\n");
485
- while (newlineIndex !== -1) {
486
- const line = buffer.slice(0, newlineIndex);
487
- buffer = buffer.slice(newlineIndex + 1);
488
- onLine(line);
489
- newlineIndex = buffer.indexOf("\n");
490
- }
491
- },
492
- flush() {
493
- buffer += decoder.end();
494
- if (!buffer) return;
495
- const line = buffer;
496
- buffer = "";
497
- onLine(line);
498
- }
499
- };
500
- }
501
- var IMessageRpcClient = class {
502
- constructor(opts = {}) {
503
- this.pending = /* @__PURE__ */ new Map();
504
- this.terminalResolve = null;
505
- this.reapedResolve = null;
506
- this.child = null;
507
- this.stopPromise = null;
508
- this.stdoutFramer = createLfLineFramer((line) => this.handleStdoutLine(line));
509
- this.stderrFramer = createLfLineFramer((line) => this.handleStderrLine(line));
510
- this.nextId = 1;
511
- this.publicProcessError = null;
512
- this.configuredCliPath = opts.cliPath?.trim() || "imsg";
513
- this.cliPath = expandIMessageUserPath(this.configuredCliPath);
514
- const dbPath = opts.dbPath?.trim();
515
- this.dbPath = dbPath ? opts.remoteHost?.trim() ? dbPath : resolveUserPath(dbPath) : void 0;
516
- this.runtime = opts.runtime;
517
- this.onNotification = opts.onNotification;
518
- this.terminal = new Promise((resolve) => {
519
- this.terminalResolve = resolve;
520
- });
521
- this.reaped = new Promise((resolve) => {
522
- this.reapedResolve = resolve;
523
- });
524
- }
525
- async start() {
526
- if (this.child) return;
527
- if (isTestEnv()) throw new Error("Refusing to start imsg rpc in test environment; mock iMessage RPC client");
528
- const args = ["rpc", "--json"];
529
- if (this.dbPath) args.push("--db", this.dbPath);
530
- const child = spawn(this.cliPath, args, { stdio: [
531
- "pipe",
532
- "pipe",
533
- "pipe"
534
- ] });
535
- this.child = child;
536
- for (const [stream, framer] of [[child.stdout, this.stdoutFramer], [child.stderr, this.stderrFramer]]) stream.on("data", (chunk) => {
537
- if (this.child === child) framer.write(chunk);
538
- });
539
- const failFromProcessError = (err) => this.failTransport(err, child);
540
- child.on("error", failFromProcessError);
541
- for (const stream of [
542
- child.stdin,
543
- child.stdout,
544
- child.stderr
545
- ]) {
546
- stream.on("error", failFromProcessError);
547
- stream.once("close", () => {
548
- const error = stream.errored;
549
- if (error) failFromProcessError(error);
550
- });
551
- }
552
- child.on("close", (code, signal) => {
553
- if (this.child === child) {
554
- this.stdoutFramer.flush();
555
- this.stderrFramer.flush();
556
- this.child = null;
557
- }
558
- this.finish(this.buildCloseError(code, signal));
559
- this.markReaped();
560
- });
561
- }
562
- async stop() {
563
- if (this.stopPromise) return await this.stopPromise;
564
- const child = this.child;
565
- if (!child) return;
566
- this.stopPromise = this.stopChild(child);
567
- return await this.stopPromise;
568
- }
569
- async waitForClose() {
570
- throw await this.terminal;
571
- }
572
- async request(method, params, opts) {
573
- const child = this.child;
574
- const stdin = child?.stdin;
575
- const assertReadAuthority = captureChannelReadAuthority();
576
- return captureEffectAuthority().initiate(() => {
577
- if (child !== this.child || stdin !== this.child?.stdin) throw new Error("imsg rpc process changed before request initiation");
578
- assertReadAuthority?.();
579
- opts?.assertCurrent?.();
580
- return this.initiateRequest(method, params, opts);
581
- });
582
- }
583
- async initiateRequest(method, params, opts) {
584
- if (!this.child || !this.child.stdin) throw new Error("imsg rpc not running");
585
- const id = this.nextId++;
586
- const line = `${JSON.stringify({
587
- jsonrpc: "2.0",
588
- id,
589
- method,
590
- params: params ?? {}
591
- })}\n`;
592
- const timeoutMs = opts?.timeoutMs ?? 1e4;
593
- const key = String(id);
594
- const pendingResponse = new Promise((resolve, reject) => {
595
- this.pending.set(key, {
596
- resolve: (value) => resolve(value),
597
- reject
598
- });
599
- });
600
- const response = timeoutMs > 0 ? raceWithTimeout(pendingResponse, timeoutMs, () => {
601
- this.pending.delete(key);
602
- throw new Error(`imsg rpc timeout (${method})`);
603
- }) : pendingResponse;
604
- try {
605
- this.child.stdin.write(line, (err) => {
606
- if (err) this.failTransport(err, this.child);
607
- });
608
- } catch (err) {
609
- this.failTransport(err, this.child);
610
- }
611
- try {
612
- return await response;
613
- } catch (err) {
614
- if (isIMessageBridgeStall(err)) {
615
- invalidateCachedIMessagePrivateApiStatus(this.configuredCliPath);
616
- try {
617
- await recoverIMessageBridge(this.configuredCliPath);
618
- } catch (recoveryError) {
619
- this.runtime?.error?.(`imessage: automatic bridge recovery failed: ${formatErrorMessage(recoveryError)}`);
620
- }
621
- throw describeIMessageBridgeStall(err);
622
- }
623
- throw err;
624
- }
625
- }
626
- async stopChild(child) {
627
- try {
628
- child.stdin.end();
629
- } catch (err) {
630
- this.failTransport(err, child);
631
- }
632
- if (await this.waitForReap(IMESSAGE_RPC_CLOSE_GRACE_MS)) return;
633
- this.signalChild(child, "SIGTERM");
634
- if (await this.waitForReap(IMESSAGE_RPC_CLOSE_GRACE_MS)) return;
635
- this.signalChild(child, "SIGKILL");
636
- if (!await this.waitForReap(IMESSAGE_RPC_CLOSE_GRACE_MS)) throw new Error("imsg rpc did not exit after SIGKILL");
637
- }
638
- async waitForReap(timeoutMs) {
639
- if (!this.reapedResolve) return true;
640
- return await raceWithTimeout(this.reaped.then(() => true), timeoutMs, () => false);
641
- }
642
- signalChild(child, signal) {
643
- try {
644
- child.kill(signal);
645
- } catch {}
646
- }
647
- failTransport(err, child) {
648
- if (!this.finish(err instanceof Error ? err : new Error(String(err)))) return;
649
- if (child) this.signalChild(child, "SIGTERM");
650
- }
651
- handleStdoutLine(line) {
652
- const trimmed = line.trim();
653
- if (!trimmed) return;
654
- this.handleLine(trimmed);
655
- }
656
- handleStderrLine(line) {
657
- const trimmed = line.trim();
658
- if (!trimmed) return;
659
- this.recordProcessDiagnostic(trimmed);
660
- if (IMSG_APPLE_FRAMEWORK_STDERR_PATTERN.test(trimmed)) {
661
- logVerbose(`imsg rpc: ${trimmed}`);
662
- return;
663
- }
664
- this.runtime?.error?.(`imsg rpc: ${trimmed}`);
665
- }
666
- handleLine(line) {
667
- let parsed;
668
- try {
669
- parsed = JSON.parse(line);
670
- } catch (err) {
671
- this.recordProcessDiagnostic(line);
672
- const detail = formatErrorMessage(err);
673
- this.runtime?.error?.(`imsg rpc: failed to parse ${line}: ${detail}`);
674
- return;
675
- }
676
- if (parsed.id !== void 0 && parsed.id !== null) {
677
- const key = String(parsed.id);
678
- const pending = this.pending.get(key);
679
- if (!pending) return;
680
- this.pending.delete(key);
681
- if (parsed.error) {
682
- const baseMessage = parsed.error.message ?? "imsg rpc error";
683
- const details = parsed.error.data;
684
- const code = parsed.error.code;
685
- const suffixes = [];
686
- if (typeof code === "number") suffixes.push(`code=${code}`);
687
- if (details !== void 0) {
688
- const detailText = typeof details === "string" ? details : JSON.stringify(details, null, 2);
689
- if (detailText) suffixes.push(detailText);
690
- }
691
- const msg = suffixes.length > 0 ? `${baseMessage}: ${suffixes.join(" ")}` : baseMessage;
692
- pending.reject(new IMessageRpcRequestError(msg, typeof code === "number" ? code : void 0, details));
693
- return;
694
- }
695
- pending.resolve(parsed.result);
696
- return;
697
- }
698
- if (parsed.method) this.onNotification?.({
699
- method: parsed.method,
700
- params: parsed.params
701
- });
702
- }
703
- recordProcessDiagnostic(line) {
704
- this.publicProcessError ??= normalizeIMessageFullDiskAccessError(line) ?? null;
705
- }
706
- buildCloseError(code, signal) {
707
- if (this.publicProcessError) return new Error(this.publicProcessError);
708
- if (code !== 0 && code !== null) {
709
- const reason = signal ? `signal ${signal}` : `code ${code}`;
710
- return /* @__PURE__ */ new Error(`imsg rpc exited (${reason})`);
711
- }
712
- return /* @__PURE__ */ new Error("imsg rpc closed");
713
- }
714
- failAll(err) {
715
- for (const [key, pending] of this.pending.entries()) {
716
- pending.reject(err);
717
- this.pending.delete(key);
718
- }
719
- }
720
- finish(err) {
721
- const resolve = this.terminalResolve;
722
- if (!resolve) return false;
723
- this.terminalResolve = null;
724
- this.failAll(err);
725
- resolve(err);
726
- return true;
727
- }
728
- markReaped() {
729
- const resolve = this.reapedResolve;
730
- this.reapedResolve = null;
731
- resolve?.();
732
- }
733
- };
734
- async function createIMessageRpcClient(opts = {}) {
735
- const client = new IMessageRpcClient(opts);
736
- await client.start();
737
- return client;
738
- }
739
- export { resolveIMessageDirectChatService as S, DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS as _, isIMessageCurrentMessageInChatAsync as a, isIMessageEmailChatIdentifier as b, resolveIMessageCachedResourceBinding as c, IMESSAGE_SENT_ECHOES_NAMESPACE as d, IMESSAGE_SENT_ECHOES_TTL_MS as f, resolveIMessageSentEchoEntryKey as g, resolveIMessageEchoMediaKey as h, findLatestIMessageEntryForChat as i, resolveIMessageMessageId as l, resolveIMessageCatchupCursorKey as m, createIMessageRpcClient as n, isKnownFromMeIMessageTarget as o, capFailureRetriesMap as p, runIMessageCliJsonCommand as r, rememberIMessageReplyCache as s, IMessageRpcRequestError as t, IMESSAGE_CATCHUP_CURSOR_NAMESPACE as u, DEFAULT_IMESSAGE_SEND_TIMEOUT_MS as v, normalizeDirectChatIdentifier as x, chatContextFromIMessageTarget as y };