@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,65 +1,19 @@
1
- import { l as resolveIMessageMessageId, n as createIMessageRpcClient, r as runIMessageCliJsonCommand, x as normalizeDirectChatIdentifier } from "./client-C3e7ZLqA.mjs";
2
- import { n as sanitizeIMessageFinalOutboundText } from "./sanitize-outbound-C02fJrn6.mjs";
3
- import { n as authorizeIMessageResourceReference, t as withIMessageRemoteFile } from "./remote-file-CCgMYZ-u.mjs";
4
- import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { i as runIMessageCliJsonCommand, n as createIMessageRpcClient } from "./client-D_BaG8sC.mjs";
2
+ import { s as resolveIMessageMessageId } from "./actions-qOuKy8To.mjs";
3
+ import { n as sanitizeIMessageFinalOutboundText } from "./sanitize-outbound-Dhjhz0a-.mjs";
4
+ import { resolveIMessageChat } from "./chat-lookup-xtPsOBkl.mjs";
5
+ import { n as authorizeIMessageResourceReference, t as withIMessageRemoteFile } from "./remote-file-DpK3GQFD.mjs";
5
6
  import { basename, parse, win32 } from "node:path";
6
- import { parseStrictInteger } from "openclaw/plugin-sdk/number-runtime";
7
7
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
8
8
  import { captureChannelReadAuthority, captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
9
9
  import { sanitizeUntrustedFileName } from "openclaw/plugin-sdk/security-runtime";
10
10
  import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
11
- // extensions/imessage/src/actions-chat-guid.ts
12
- const CHAT_LIST_CACHE_TTL_MS = 3e4;
13
- const chatListCache = /* @__PURE__ */ new Map();
14
- function numberFromUnknown(value) {
15
- return typeof value === "number" && Number.isFinite(value) ? value : parseStrictInteger(value);
16
- }
17
- function findChatGuid(chats, target) {
18
- if (target.kind === "chat_id") {
19
- for (const chat of chats) {
20
- const id = numberFromUnknown(chat.id);
21
- const guid = normalizeOptionalString(chat.guid);
22
- if (id === target.chatId && guid) return guid;
23
- }
24
- return null;
25
- }
26
- const wanted = normalizeDirectChatIdentifier(target.chatIdentifier);
27
- for (const chat of chats) {
28
- const identifier = normalizeOptionalString(chat.identifier);
29
- const guid = normalizeOptionalString(chat.guid);
30
- if (guid && (identifier === target.chatIdentifier || guid === target.chatIdentifier || identifier && normalizeDirectChatIdentifier(identifier) === wanted || normalizeDirectChatIdentifier(guid) === wanted)) return guid;
31
- }
32
- return null;
33
- }
34
- async function resolveIMessageActionChatGuid(params) {
35
- const { cliPath, dbPath, remoteHost } = params.options;
36
- const key = `${cliPath}\0${dbPath ?? ""}\0${remoteHost ?? ""}`;
37
- const cached = chatListCache.get(key);
38
- if (cached && cached.expiresAt > Date.now()) return findChatGuid(cached.list, params.target);
39
- chatListCache.delete(key);
40
- const client = await createIMessageRpcClient(params.options);
41
- try {
42
- const result = await client.request("chats.list", { limit: 1e3 }, { timeoutMs: params.options.timeoutMs });
43
- const list = isRecord(result) && Array.isArray(result.chats) ? result.chats.filter(isRecord) : [];
44
- chatListCache.set(key, {
45
- list,
46
- expiresAt: Date.now() + CHAT_LIST_CACHE_TTL_MS
47
- });
48
- return findChatGuid(list, params.target);
49
- } finally {
50
- await client.stop();
51
- }
52
- }
53
11
  // extensions/imessage/src/actions-transport.ts
54
- var IMessageRemoteUnsupportedError = class extends Error {
55
- constructor(message) {
56
- super(message);
57
- this.code = "IMESSAGE_REMOTE_UNSUPPORTED";
58
- this.name = "IMessageRemoteUnsupportedError";
59
- }
60
- };
61
12
  function throwIMessageRemoteUnsupported(message) {
62
- throw new IMessageRemoteUnsupportedError(`iMessage Remote Mac limitation: ${message}`);
13
+ throw Object.assign(/* @__PURE__ */ new Error(`iMessage Remote Mac limitation: ${message}`), {
14
+ code: "IMESSAGE_REMOTE_UNSUPPORTED",
15
+ name: "IMessageRemoteUnsupportedError"
16
+ });
63
17
  }
64
18
  async function runIMessageAction(options, method, params, args) {
65
19
  if (!options.remoteHost) {
@@ -165,7 +119,7 @@ function participantAction(method, command) {
165
119
  const imessageActionsRuntime = {
166
120
  resolveIMessageMessageId,
167
121
  authorizeMessageReference: authorizeIMessageResourceReference,
168
- resolveChatGuidForTarget: resolveIMessageActionChatGuid,
122
+ resolveChatGuidForTarget: async (params) => (await resolveIMessageChat(params))?.guid ?? null,
169
123
  async sendReaction(params) {
170
124
  await runMessageAction(params, "tapback", "tapback", {
171
125
  reaction: params.reaction,
@@ -1,10 +1,10 @@
1
- import "./targets-CIx4BKqL.mjs";
2
- import "./accounts-BH0coL46.mjs";
3
- import "./message-tool-api-CxSY_rh7.mjs";
4
- import "./actions-CW7XYYF4.mjs";
5
- import { s as imessageSetupContract } from "./setup-core-BWnW0czE.mjs";
6
- import { n as createIMessagePluginBase, r as imessageSetupWizard } from "./channel-6kcKpSRw.mjs";
7
- import "./conversation-bindings-vZFn6sN2.mjs";
1
+ import "./targets-C7CIWJ0k.mjs";
2
+ import "./accounts-C1Ypv3Wn.mjs";
3
+ import "./message-tool-api-DtZ1wKbT.mjs";
4
+ import "./actions-qOuKy8To.mjs";
5
+ import { s as imessageSetupContract } from "./setup-core-B1_P_t4T.mjs";
6
+ import { n as createIMessagePluginBase, r as imessageSetupWizard } from "./channel-CLaN4mQn.mjs";
7
+ import "./conversation-bindings-8DjxoIYU.mjs";
8
8
  import { createAllowedChatSenderMatcher as createAllowedChatSenderMatcher$1, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow as parseChatTargetPrefixesOrThrow$1, resolveServicePrefixedAllowTarget, resolveServicePrefixedChatTarget as resolveServicePrefixedChatTarget$1, resolveServicePrefixedOrChatAllowTarget as resolveServicePrefixedOrChatAllowTarget$1, resolveServicePrefixedTarget } from "openclaw/plugin-sdk/channel-targets";
9
9
  // extensions/imessage/src/channel.setup.ts
10
10
  const imessageSetupPlugin = createIMessagePluginBase({
@@ -1,10 +1,10 @@
1
- import { a as looksLikeIMessageExplicitTargetId, c as parseIMessageTarget, d as normalizeIMessageMessagingTarget, i as isAllowedIMessageSender, n as inferIMessageTargetChatType, o as normalizeIMessageHandle, s as parseIMessageAllowTarget, t as formatIMessageChatTarget, u as looksLikeIMessageTargetId } from "./targets-CIx4BKqL.mjs";
2
- import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./accounts-BH0coL46.mjs";
3
- import { o as IMESSAGE_ACTIONS, s as IMESSAGE_ACTION_NAMES } from "./message-tool-api-CxSY_rh7.mjs";
4
- import { _ as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./client-C3e7ZLqA.mjs";
5
- import { n as probeIMessage } from "./actions-CW7XYYF4.mjs";
6
- import { c as matchIMessageAcpConversation, i as resolveIMessageGroupRequireMention, l as normalizeIMessageAcpConversationId, o as resolveIMessageGroupToolPolicy, s as resolveIMessageInboundConversationId, t as imessagePlugin, u as resolveIMessageConversationIdFromTarget } from "./channel-6kcKpSRw.mjs";
7
- import { n as createIMessageConversationBindingManagerV2, t as createIMessageConversationBindingManager } from "./conversation-bindings-vZFn6sN2.mjs";
8
- import { a as resolveServicePrefixedChatTarget, c as imessageSetupPlugin, i as resolveServicePrefixedAllowTarget, n as parseChatAllowTargetPrefixes, o as resolveServicePrefixedOrChatAllowTarget, r as parseChatTargetPrefixesOrThrow, s as resolveServicePrefixedTarget, t as createAllowedChatSenderMatcher } from "./api-6xi-NBrt.mjs";
1
+ import { a as isAllowedIMessageSender, c as parseIMessageAllowTarget, d as looksLikeIMessageTargetId, f as normalizeIMessageMessagingTarget, l as parseIMessageTarget, o as looksLikeIMessageExplicitTargetId, r as inferIMessageTargetChatType, s as normalizeIMessageHandle, t as formatIMessageChatTarget } from "./targets-C7CIWJ0k.mjs";
2
+ import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./accounts-C1Ypv3Wn.mjs";
3
+ import { o as IMESSAGE_ACTIONS, s as IMESSAGE_ACTION_NAMES } from "./message-tool-api-DtZ1wKbT.mjs";
4
+ import { a as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./client-D_BaG8sC.mjs";
5
+ import { n as probeIMessage } from "./actions-qOuKy8To.mjs";
6
+ import { c as matchIMessageAcpConversation, i as resolveIMessageGroupRequireMention, l as normalizeIMessageAcpConversationId, o as resolveIMessageGroupToolPolicy, s as resolveIMessageInboundConversationId, t as imessagePlugin, u as resolveIMessageConversationIdFromTarget } from "./channel-CLaN4mQn.mjs";
7
+ import { n as createIMessageConversationBindingManagerV2, t as createIMessageConversationBindingManager } from "./conversation-bindings-8DjxoIYU.mjs";
8
+ import { a as resolveServicePrefixedChatTarget, c as imessageSetupPlugin, i as resolveServicePrefixedAllowTarget, n as parseChatAllowTargetPrefixes, o as resolveServicePrefixedOrChatAllowTarget, r as parseChatTargetPrefixesOrThrow, s as resolveServicePrefixedTarget, t as createAllowedChatSenderMatcher } from "./api-BXXuQQCS.mjs";
9
9
  import { t as IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps-_da8jqeo.mjs";
10
10
  export { DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS, IMESSAGE_ACTIONS, IMESSAGE_ACTION_NAMES, IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS, createAllowedChatSenderMatcher, createIMessageConversationBindingManager, createIMessageConversationBindingManagerV2, formatIMessageChatTarget, imessagePlugin, imessageSetupPlugin, inferIMessageTargetChatType, isAllowedIMessageSender, listEnabledIMessageAccounts, listIMessageAccountIds, looksLikeIMessageExplicitTargetId, looksLikeIMessageTargetId, matchIMessageAcpConversation, normalizeIMessageAcpConversationId, normalizeIMessageHandle, normalizeIMessageMessagingTarget, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow, parseIMessageAllowTarget, parseIMessageTarget, probeIMessage, resolveDefaultIMessageAccountId, resolveIMessageAccount, resolveIMessageConversationIdFromTarget, resolveIMessageGroupRequireMention, resolveIMessageGroupToolPolicy, resolveIMessageInboundConversationId, resolveServicePrefixedAllowTarget, resolveServicePrefixedChatTarget, resolveServicePrefixedOrChatAllowTarget, resolveServicePrefixedTarget };
@@ -1,11 +1,11 @@
1
- import { c as parseIMessageTarget, d as normalizeIMessageMessagingTarget } from "./targets-CIx4BKqL.mjs";
2
- import { o as resolveIMessageAccount } from "./accounts-BH0coL46.mjs";
3
- import { n as getCachedIMessagePrivateApiStatus } from "./message-tool-api-CxSY_rh7.mjs";
4
- import { a as normalizeIMessageMessageId } from "./actions-CW7XYYF4.mjs";
5
- import { d as getIMessageApprovalApprovers } from "./channel-6kcKpSRw.mjs";
6
- import { i as extractMarkdownFormatRuns } from "./sanitize-outbound-C02fJrn6.mjs";
7
- import { a as unregisterIMessageApprovalReactionTarget, c as buildIMessageApprovalConversationKeyForTarget, i as registerIMessageApprovalReactionTarget } from "./approval-reactions-B9CJS0NT.mjs";
8
- import { a as iMessageApprovalPollTargets, i as buildApprovalPollOptions, o as mapSentPollOptionsToDecisions, t as sendMessageIMessage } from "./send-D98hQFdv.mjs";
1
+ import { f as normalizeIMessageMessagingTarget, l as parseIMessageTarget } from "./targets-C7CIWJ0k.mjs";
2
+ import { o as resolveIMessageAccount } from "./accounts-C1Ypv3Wn.mjs";
3
+ import { n as getCachedIMessagePrivateApiStatus } from "./message-tool-api-DtZ1wKbT.mjs";
4
+ import { b as normalizeIMessageMessageId } from "./actions-qOuKy8To.mjs";
5
+ import { d as getIMessageApprovalApprovers } from "./channel-CLaN4mQn.mjs";
6
+ import { i as extractMarkdownFormatRuns } from "./sanitize-outbound-Dhjhz0a-.mjs";
7
+ import { c as buildIMessageApprovalConversationKeyForTarget, i as unregisterIMessageApprovalReactionTarget, r as registerIMessageApprovalReactionTarget } from "./approval-reactions-DBBsqbRC.mjs";
8
+ import { a as iMessageApprovalPollTargets, i as buildApprovalPollOptions, o as mapSentPollOptionsToDecisions, t as sendMessageIMessage } from "./send-DhEW0gfe.mjs";
9
9
  import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
10
10
  import { createActionGate } from "openclaw/plugin-sdk/channel-actions";
11
11
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
@@ -15,7 +15,7 @@ import { setTimeout } from "node:timers/promises";
15
15
  import { buildChannelApprovalExpiredText, buildChannelApprovalResolvedText, createChannelApprovalNativeRuntimeAdapterAsync, resolvePreparedApprovalAccountId } from "openclaw/plugin-sdk/approval-handler-runtime";
16
16
  // extensions/imessage/src/approval-handler.runtime.ts
17
17
  const log = createSubsystemLogger("imessage/approvals");
18
- const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-B2ZHQ3TJ.mjs"), "imessageActionsRuntime");
18
+ const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-Ccg9CARL.mjs"), "imessageActionsRuntime");
19
19
  const DEFAULT_PROBE_TIMEOUT_MS = 5e3;
20
20
  const APPROVAL_POLL_ORDERING_DELAY_MS = 1100;
21
21
  function classifyIMessageApprovalTargetTransport(params) {
@@ -33,113 +33,6 @@ function classifyIMessageApprovalTargetTransport(params) {
33
33
  if (/^SMS;/i.test(conversationId)) return "sms";
34
34
  return "unknown";
35
35
  }
36
- function canIMessageApprovalUsePoll(params) {
37
- if (params.plannedTarget.surface !== "origin" && params.plannedTarget.surface !== "approver-dm") return false;
38
- if (buildApprovalPollOptions({ allowedDecisions: params.allowedDecisions }).length < 2) return false;
39
- try {
40
- const account = resolveIMessageAccount({
41
- cfg: params.cfg,
42
- accountId: params.target.accountId
43
- });
44
- if (classifyIMessageApprovalTargetTransport({
45
- cfg: params.cfg,
46
- target: params.target
47
- }) === "sms") return false;
48
- if (!createActionGate(account.config.actions)("polls") || getIMessageApprovalApprovers({
49
- cfg: params.cfg,
50
- accountId: account.accountId
51
- }).length === 0) return false;
52
- const cliPath = account.config.cliPath?.trim() || "imsg";
53
- const status = getCachedIMessagePrivateApiStatus(cliPath);
54
- return status?.available === true && status?.selectors?.pollPayloadMessage === true && status.cliCapabilities?.pollSendSupportsNoComment === true;
55
- } catch {
56
- return false;
57
- }
58
- }
59
- async function deliverIMessageApprovalPoll(params) {
60
- const options = buildApprovalPollOptions({ allowedDecisions: params.allowedDecisions });
61
- try {
62
- const account = resolveIMessageAccount({
63
- cfg: params.cfg,
64
- accountId: params.target.accountId
65
- });
66
- const cliOptions = {
67
- cliPath: account.config.cliPath?.trim() || "imsg",
68
- dbPath: account.config.dbPath?.trim() || void 0,
69
- timeoutMs: account.config.probeTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS
70
- };
71
- const target = parseIMessageTarget(params.target.to);
72
- let chatGuid;
73
- if (target.kind === "chat_guid") chatGuid = target.chatGuid;
74
- else chatGuid = await (await loadIMessageActionsRuntime()).resolveChatGuidForTarget({
75
- target: target.kind === "handle" ? {
76
- kind: "chat_identifier",
77
- chatIdentifier: `${target.service === "sms" ? "SMS" : "iMessage"};-;${target.to}`
78
- } : target,
79
- options: cliOptions,
80
- conversationReadOrigin: "direct-operator"
81
- });
82
- if (!chatGuid || /^SMS;/i.test(chatGuid)) return null;
83
- await setTimeout(APPROVAL_POLL_ORDERING_DELAY_MS);
84
- const sent = await (await loadIMessageActionsRuntime()).sendPoll({
85
- chatGuid,
86
- question: extractMarkdownFormatRuns(params.question).text,
87
- choices: options.map((option) => option.text),
88
- suppressComment: true,
89
- options: cliOptions
90
- });
91
- const pollGuid = normalizeIMessageMessageId(sent.messageId);
92
- const optionDecisions = mapSentPollOptionsToDecisions({
93
- requested: options,
94
- sent: sent.pollOptions
95
- });
96
- if (optionDecisions.length !== options.length) {
97
- log.error("imessage approvals: imsg poll response did not return a complete option mapping");
98
- await iMessageApprovalPollTargets.registerTombstone({
99
- accountId: resolveIMessageAccount({
100
- cfg: params.cfg,
101
- accountId: params.target.accountId
102
- }).accountId,
103
- conversation: { chatGuid },
104
- ...pollGuid ? { pollGuid } : {},
105
- optionIds: sent.pollOptions.map((option) => option.id),
106
- approvalId: params.approvalId
107
- });
108
- return null;
109
- }
110
- const accountId = resolveIMessageAccount({
111
- cfg: params.cfg,
112
- accountId: params.target.accountId
113
- }).accountId;
114
- if (!await iMessageApprovalPollTargets.register({
115
- accountId,
116
- conversation: { chatGuid },
117
- ...pollGuid ? { pollGuid } : {},
118
- approvalId: params.approvalId,
119
- approvalKind: params.approvalKind,
120
- optionDecisions,
121
- expiresAtMs: params.expiresAtMs
122
- })) {
123
- await iMessageApprovalPollTargets.registerTombstone({
124
- accountId,
125
- conversation: { chatGuid },
126
- ...pollGuid ? { pollGuid } : {},
127
- optionIds: optionDecisions.map(([optionId]) => optionId),
128
- approvalId: params.approvalId
129
- });
130
- log.error("imessage approvals: poll target could not be registered");
131
- return null;
132
- }
133
- return {
134
- ...pollGuid ? { pollGuid } : {},
135
- chatGuid,
136
- optionDecisions
137
- };
138
- } catch (error) {
139
- log.warn(`imessage approvals: poll send failed, falling back to tapbacks: ${String(error)}`);
140
- return null;
141
- }
142
- }
143
36
  /** Clear both controls together; a stale binding would resolve a dead approval. */
144
37
  async function clearIMessageApprovalBindings(entry) {
145
38
  const accountId = entry.accountId?.trim();
@@ -259,12 +152,30 @@ const imessageApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapterA
259
152
  };
260
153
  },
261
154
  deliverPending: async ({ cfg, preparedTarget, plannedTarget, pendingPayload, view }) => {
262
- const expectPoll = canIMessageApprovalUsePoll({
263
- cfg,
264
- target: preparedTarget,
265
- plannedTarget,
266
- allowedDecisions: pendingPayload.allowedDecisions
267
- });
155
+ const canUsePoll = (surface) => {
156
+ if (surface !== "origin" && surface !== "approver-dm") return false;
157
+ if (buildApprovalPollOptions({ allowedDecisions: pendingPayload.allowedDecisions }).length < 2) return false;
158
+ try {
159
+ const account = resolveIMessageAccount({
160
+ cfg,
161
+ accountId: preparedTarget.accountId
162
+ });
163
+ if (classifyIMessageApprovalTargetTransport({
164
+ cfg,
165
+ target: preparedTarget
166
+ }) === "sms") return false;
167
+ if (!createActionGate(account.config.actions)("polls") || getIMessageApprovalApprovers({
168
+ cfg,
169
+ accountId: account.accountId
170
+ }).length === 0) return false;
171
+ const cliPath = account.config.cliPath?.trim() || "imsg";
172
+ const status = getCachedIMessagePrivateApiStatus(cliPath);
173
+ return status?.available === true && status?.selectors?.pollPayloadMessage === true && status.cliCapabilities?.pollSendSupportsNoComment === true;
174
+ } catch {
175
+ return false;
176
+ }
177
+ };
178
+ const expectPoll = canUsePoll(plannedTarget.surface);
268
179
  const conversation = buildIMessageApprovalConversationKeyForTarget(preparedTarget.to);
269
180
  if (!conversation) return null;
270
181
  const accountId = resolveIMessageAccount({
@@ -290,15 +201,85 @@ const imessageApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapterA
290
201
  });
291
202
  if (!result.guid) return null;
292
203
  const confirmedTransport = result.service ?? (result.chatGuid && /^iMessage;/i.test(result.chatGuid) ? "imessage" : result.chatGuid && /^SMS;/i.test(result.chatGuid) ? "sms" : targetTransport);
293
- const poll = expectPoll && confirmedTransport === "imessage" ? await deliverIMessageApprovalPoll({
294
- cfg,
295
- target: preparedTarget,
296
- approvalId: view.approvalId,
297
- approvalKind: view.approvalKind,
298
- expiresAtMs: view.expiresAtMs,
299
- question: pendingPayload.pollText,
300
- allowedDecisions: pendingPayload.allowedDecisions
301
- }) : null;
204
+ const poll = expectPoll && confirmedTransport === "imessage" ? await (async () => {
205
+ const { approvalId, approvalKind, expiresAtMs } = view;
206
+ const { pollText: question, allowedDecisions } = pendingPayload;
207
+ const options = buildApprovalPollOptions({ allowedDecisions });
208
+ try {
209
+ const account = resolveIMessageAccount({
210
+ cfg,
211
+ accountId: preparedTarget.accountId
212
+ });
213
+ const cliOptions = {
214
+ cliPath: account.config.cliPath?.trim() || "imsg",
215
+ dbPath: account.config.dbPath?.trim() || void 0,
216
+ timeoutMs: account.config.probeTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS
217
+ };
218
+ const target = parseIMessageTarget(preparedTarget.to);
219
+ let chatGuid;
220
+ if (target.kind === "chat_guid") chatGuid = target.chatGuid;
221
+ else chatGuid = await (await loadIMessageActionsRuntime()).resolveChatGuidForTarget({
222
+ target: target.kind === "handle" ? {
223
+ kind: "chat_identifier",
224
+ chatIdentifier: `${target.service === "sms" ? "SMS" : "iMessage"};-;${target.to}`
225
+ } : target,
226
+ options: cliOptions,
227
+ conversationReadOrigin: "direct-operator"
228
+ });
229
+ if (!chatGuid || /^SMS;/i.test(chatGuid)) return null;
230
+ await setTimeout(APPROVAL_POLL_ORDERING_DELAY_MS);
231
+ const sent = await (await loadIMessageActionsRuntime()).sendPoll({
232
+ chatGuid,
233
+ question: extractMarkdownFormatRuns(question).text,
234
+ choices: options.map((option) => option.text),
235
+ suppressComment: true,
236
+ options: cliOptions
237
+ });
238
+ const pollGuid = normalizeIMessageMessageId(sent.messageId);
239
+ const optionDecisions = mapSentPollOptionsToDecisions({
240
+ requested: options,
241
+ sent: sent.pollOptions
242
+ });
243
+ if (optionDecisions.length !== options.length) {
244
+ log.error("imessage approvals: imsg poll response did not return a complete option mapping");
245
+ await iMessageApprovalPollTargets.registerTombstone({
246
+ accountId: account.accountId,
247
+ conversation: { chatGuid },
248
+ ...pollGuid ? { pollGuid } : {},
249
+ optionIds: sent.pollOptions.map((option) => option.id),
250
+ approvalId
251
+ });
252
+ return null;
253
+ }
254
+ if (!await iMessageApprovalPollTargets.register({
255
+ accountId: account.accountId,
256
+ conversation: { chatGuid },
257
+ ...pollGuid ? { pollGuid } : {},
258
+ approvalId,
259
+ approvalKind,
260
+ optionDecisions,
261
+ expiresAtMs
262
+ })) {
263
+ await iMessageApprovalPollTargets.registerTombstone({
264
+ accountId: account.accountId,
265
+ conversation: { chatGuid },
266
+ ...pollGuid ? { pollGuid } : {},
267
+ optionIds: optionDecisions.map(([optionId]) => optionId),
268
+ approvalId
269
+ });
270
+ log.error("imessage approvals: poll target could not be registered");
271
+ return null;
272
+ }
273
+ return {
274
+ ...pollGuid ? { pollGuid } : {},
275
+ chatGuid,
276
+ optionDecisions
277
+ };
278
+ } catch (error) {
279
+ log.warn(`imessage approvals: poll send failed, falling back to tapbacks: ${String(error)}`);
280
+ return null;
281
+ }
282
+ })() : null;
302
283
  let hintMessageId;
303
284
  if (expectPoll && !poll && !reactionFallbackVisible) try {
304
285
  hintMessageId = (await sendMessageIMessage(preparedTarget.to, pendingPayload.text, {
@@ -1,13 +1,13 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-782esTHO.mjs";
2
- import { c as parseIMessageTarget, o as normalizeIMessageHandle } from "./targets-CIx4BKqL.mjs";
3
- import { i as normalizeIMessageGuid } from "./actions-CW7XYYF4.mjs";
4
- import { n as getOptionalIMessageRuntime } from "./runtime-BRQCPuAD.mjs";
5
- import { d as getIMessageApprovalApprovers, f as imessageApprovalAuth } from "./channel-6kcKpSRw.mjs";
6
- import { t as resolveIMessageReactionContext } from "./reaction-context-Bw00FkmU.mjs";
2
+ import { l as parseIMessageTarget, s as normalizeIMessageHandle } from "./targets-C7CIWJ0k.mjs";
3
+ import { t as chatContextFromIMessageTarget } from "./chat-context-fTfJVqAi.mjs";
4
+ import { g as getOptionalIMessageRuntime, y as normalizeIMessageGuid } from "./actions-qOuKy8To.mjs";
5
+ import { d as getIMessageApprovalApprovers, f as imessageApprovalAuth } from "./channel-CLaN4mQn.mjs";
7
6
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
8
7
  import { createLazyRuntimeSurface } from "openclaw/plugin-sdk/lazy-runtime";
9
- import { asDateTimestampMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
8
+ import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
10
9
  import { addApprovalReactionHintToText, approvalReactionDecisionSetsMatch, buildApprovalReactionDeliveredBindingMarker, buildApprovalReactionHint, createApprovalReactionTargetStore, listApprovalReactionBindings, normalizeApprovalReactionDecision, readApprovalReactionDecisionList, readApprovalReactionDeliveredBinding, readApprovalReactionPresentationBinding, readApprovalReactionTargetRecord, resolveTypedApprovalReactionTarget, settleApprovalReaction } from "openclaw/plugin-sdk/approval-reaction-runtime";
10
+ import { asDateTimestampMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
11
11
  import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
12
12
  // extensions/imessage/src/approval-target-keys.ts
13
13
  function chatIdToKeyValue(chatId) {
@@ -46,9 +46,7 @@ function enumerateApprovalTargetKeys(params) {
46
46
  function buildIMessageApprovalConversationKeyForTarget(to) {
47
47
  try {
48
48
  const target = parseIMessageTarget(to);
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 };
49
+ if (target.kind !== "handle") return chatContextFromIMessageTarget(target);
52
50
  const handle = normalizeIMessageHandle(target.to);
53
51
  return handle ? { handle } : null;
54
52
  } catch {
@@ -205,17 +203,113 @@ async function listPendingIMessageApprovalReactionPollTargets(params) {
205
203
  }
206
204
  return [...targetByApprovalAndMessage.values()];
207
205
  }
208
- function clearIMessageApprovalReactionPollTargetsForTest() {
209
- pendingReactionPollTargets.clear();
210
- pendingReactionPollTargetStore = void 0;
206
+ // extensions/imessage/src/monitor/reaction-context.ts
207
+ const TAPBACK_TEXT_PATTERNS = [
208
+ {
209
+ prefix: "loved",
210
+ action: "added",
211
+ emoji: "❤️"
212
+ },
213
+ {
214
+ prefix: "liked",
215
+ action: "added",
216
+ emoji: "👍"
217
+ },
218
+ {
219
+ prefix: "disliked",
220
+ action: "added",
221
+ emoji: "👎"
222
+ },
223
+ {
224
+ prefix: "laughed at",
225
+ action: "added",
226
+ emoji: "😂"
227
+ },
228
+ {
229
+ prefix: "emphasized",
230
+ action: "added",
231
+ emoji: "‼️"
232
+ },
233
+ {
234
+ prefix: "questioned",
235
+ action: "added",
236
+ emoji: "❓"
237
+ },
238
+ {
239
+ prefix: "removed a heart from",
240
+ action: "removed",
241
+ emoji: "❤️"
242
+ },
243
+ {
244
+ prefix: "removed a like from",
245
+ action: "removed",
246
+ emoji: "👍"
247
+ },
248
+ {
249
+ prefix: "removed a dislike from",
250
+ action: "removed",
251
+ emoji: "👎"
252
+ },
253
+ {
254
+ prefix: "removed a laugh from",
255
+ action: "removed",
256
+ emoji: "😂"
257
+ },
258
+ {
259
+ prefix: "removed an emphasis from",
260
+ action: "removed",
261
+ emoji: "‼️"
262
+ },
263
+ {
264
+ prefix: "removed a question from",
265
+ action: "removed",
266
+ emoji: "❓"
267
+ }
268
+ ];
269
+ function normalizeReactionValue(value) {
270
+ return value ? normalizeIMessageGuid(value) || void 0 : void 0;
271
+ }
272
+ function resolveReactionTargetGuidCandidates(...values) {
273
+ const candidates = [];
274
+ for (const value of values) {
275
+ const raw = value?.trim();
276
+ if (!raw) continue;
277
+ const normalized = normalizeIMessageGuid(raw);
278
+ for (const candidate of [normalized, raw]) if (candidate && !candidates.includes(candidate)) candidates.push(candidate);
279
+ }
280
+ return candidates;
281
+ }
282
+ function resolveTapbackTextContext(bodyText) {
283
+ const lower = bodyText.toLowerCase();
284
+ for (const pattern of TAPBACK_TEXT_PATTERNS) {
285
+ if (!lower.startsWith(pattern.prefix)) continue;
286
+ const afterPrefix = bodyText.slice(pattern.prefix.length).trim();
287
+ if (!/^(?:"[\s\S]*"|“[\s\S]*”)$/u.test(afterPrefix)) continue;
288
+ return {
289
+ action: pattern.action,
290
+ emoji: pattern.emoji,
291
+ targetText: afterPrefix.slice(1, -1).trim()
292
+ };
293
+ }
294
+ return null;
295
+ }
296
+ function resolveIMessageReactionContext(message, bodyText) {
297
+ if (message.is_reaction === true || message.is_tapback === true || message.associated_message_type != null && Number.isFinite(message.associated_message_type) && message.associated_message_type >= 2e3 && message.associated_message_type < 4e3) {
298
+ const targetGuids = resolveReactionTargetGuidCandidates(message.reacted_to_guid, message.associated_message_guid);
299
+ return {
300
+ action: message.is_reaction_add === false ? "removed" : "added",
301
+ emoji: normalizeReactionValue(message.reaction_emoji) ?? normalizeReactionValue(message.reaction_type) ?? "reaction",
302
+ targetGuid: targetGuids[0],
303
+ targetGuids
304
+ };
305
+ }
306
+ return resolveTapbackTextContext(bodyText);
211
307
  }
212
308
  // extensions/imessage/src/approval-reactions.ts
213
309
  var approval_reactions_exports = /* @__PURE__ */ __exportAll({
214
310
  addIMessageApprovalReactionHintToStructuredPayload: () => addIMessageApprovalReactionHintToStructuredPayload,
215
311
  buildIMessageApprovalConversationKeyForTarget: () => buildIMessageApprovalConversationKeyForTarget,
216
- clearIMessageApprovalReactionTargetsForTest: () => clearIMessageApprovalReactionTargetsForTest,
217
312
  handleIMessageApprovalReaction: () => handleIMessageApprovalReaction,
218
- maybeResolveIMessageApprovalReaction: () => maybeResolveIMessageApprovalReaction,
219
313
  registerIMessageApprovalReactionTarget: () => registerIMessageApprovalReactionTarget,
220
314
  registerIMessageApprovalReactionTargetForDeliveredPayload: () => registerIMessageApprovalReactionTargetForDeliveredPayload,
221
315
  resolveIMessageApprovalReactionTargetWithPersistence: () => resolveIMessageApprovalReactionTargetWithPersistence,
@@ -447,64 +541,50 @@ async function handleIMessageApprovalReaction(params) {
447
541
  handled: false,
448
542
  stopPolling: false
449
543
  };
450
- const settlement = await settleApprovalReaction({
451
- request: {
452
- cfg: params.cfg,
453
- approvalId: target.approvalId,
454
- approvalKind: target.approvalKind,
455
- decision: target.decision,
456
- channel: "imessage",
457
- accountId: params.accountId,
458
- senderId: event.actorHandle,
459
- gatewayUrl: params.gatewayUrl,
460
- ...params.gatewayRuntime ? { gatewayRuntime: params.gatewayRuntime } : {}
461
- },
462
- approvers: getIMessageApprovalApprovers({
463
- cfg: params.cfg,
464
- accountId: params.accountId
465
- }),
466
- authorizeActorAction: (input) => imessageApprovalAuth.authorizeActorAction(input),
467
- loadResolver: loadResolveApprovalOverGateway,
468
- clearTarget: async () => {
469
- await Promise.all(event.messageIdCandidates.map((candidate) => unregisterIMessageApprovalReactionTarget({
470
- accountId: params.accountId,
471
- conversation: event.conversation,
472
- messageId: candidate
473
- })));
474
- },
475
- onResolved: (result) => {
476
- const outcome = result.applied ? "resolved" : "already resolved";
477
- params.logVerboseMessage?.(`imessage: approval reaction ${outcome} id=${target.approvalId} sender=${event.actorHandle} ${formatCanonicalApprovalTerminalState(result.approval)} via messageId=${matchedMessageId ?? event.messageId}`);
478
- },
479
- onError: (error) => {
480
- try {
481
- getOptionalIMessageRuntime()?.logging.getChildLogger({
482
- plugin: "imessage",
483
- feature: "approval-reactions"
484
- }).warn("approval reaction failed", {
485
- approvalId: target.approvalId,
486
- senderId: event.actorHandle,
487
- error: String(error)
488
- });
489
- } catch {}
490
- },
491
- logVerboseMessage: params.logVerboseMessage
492
- });
493
- return settlement === "denied" ? {
494
- handled: true,
495
- stopPolling: false
496
- } : {
544
+ return {
497
545
  handled: true,
498
- stopPolling: true,
499
- stopPollingReason: settlement
546
+ stopPolling: await settleApprovalReaction({
547
+ request: {
548
+ cfg: params.cfg,
549
+ approvalId: target.approvalId,
550
+ approvalKind: target.approvalKind,
551
+ decision: target.decision,
552
+ channel: "imessage",
553
+ accountId: params.accountId,
554
+ senderId: event.actorHandle,
555
+ ...params.gatewayRuntime ? { gatewayRuntime: params.gatewayRuntime } : {}
556
+ },
557
+ approvers: getIMessageApprovalApprovers({
558
+ cfg: params.cfg,
559
+ accountId: params.accountId
560
+ }),
561
+ authorizeActorAction: (input) => imessageApprovalAuth.authorizeActorAction(input),
562
+ loadResolver: loadResolveApprovalOverGateway,
563
+ clearTarget: async () => {
564
+ await Promise.all(event.messageIdCandidates.map((candidate) => unregisterIMessageApprovalReactionTarget({
565
+ accountId: params.accountId,
566
+ conversation: event.conversation,
567
+ messageId: candidate
568
+ })));
569
+ },
570
+ onResolved: (result) => {
571
+ const outcome = result.applied ? "resolved" : "already resolved";
572
+ logVerbose(`imessage: approval reaction ${outcome} id=${target.approvalId} sender=${event.actorHandle} ${formatCanonicalApprovalTerminalState(result.approval)} via messageId=${matchedMessageId ?? event.messageId}`);
573
+ },
574
+ onError: (error) => {
575
+ try {
576
+ getOptionalIMessageRuntime()?.logging.getChildLogger({
577
+ plugin: "imessage",
578
+ feature: "approval-reactions"
579
+ }).warn("approval reaction failed", {
580
+ approvalId: target.approvalId,
581
+ senderId: event.actorHandle,
582
+ error: String(error)
583
+ });
584
+ } catch {}
585
+ },
586
+ logVerboseMessage: logVerbose
587
+ }) !== "denied"
500
588
  };
501
589
  }
502
- async function maybeResolveIMessageApprovalReaction(params) {
503
- return (await handleIMessageApprovalReaction(params)).handled;
504
- }
505
- function clearIMessageApprovalReactionTargetsForTest() {
506
- imessageApprovalReactionTargets.clearForTest();
507
- clearIMessageApprovalReactionPollTargetsForTest();
508
- loadResolveApprovalOverGateway.clear();
509
- }
510
- export { unregisterIMessageApprovalReactionTarget as a, buildIMessageApprovalConversationKeyForTarget as c, resolveIMessageApprovalControlActor as d, registerIMessageApprovalReactionTarget as i, enumerateApprovalTargetKeys as l, handleIMessageApprovalReaction as n, listPendingIMessageApprovalReactionPollTargets as o, maybeResolveIMessageApprovalReaction as r, buildIMessageApprovalConversationKeyForInbound as s, approval_reactions_exports as t, normalizeConversationKey as u };
590
+ export { resolveIMessageReactionContext as a, buildIMessageApprovalConversationKeyForTarget as c, resolveIMessageApprovalControlActor as d, unregisterIMessageApprovalReactionTarget as i, enumerateApprovalTargetKeys as l, handleIMessageApprovalReaction as n, listPendingIMessageApprovalReactionPollTargets as o, registerIMessageApprovalReactionTarget as r, buildIMessageApprovalConversationKeyForInbound as s, approval_reactions_exports as t, normalizeConversationKey as u };