@openclaw/imessage 2026.9.1 → 2026.9.2

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 (30) hide show
  1. package/dist/{actions.runtime-DCjNT81u.js → actions.runtime-D5MAgeSs.js} +2 -2
  2. package/dist/api.js +3 -3
  3. package/dist/{approval-handler.runtime-BReeID1z.js → approval-handler.runtime-47rs6THN.js} +5 -5
  4. package/dist/{approval-reactions-DcLRPx7O.js → approval-reactions-sVpDno7d.js} +3 -7
  5. package/dist/{channel-zDmMTHWD.js → channel-BxraMrmK.js} +11 -8
  6. package/dist/channel-plugin-api.js +1 -1
  7. package/dist/{channel.runtime-qQBHCle8.js → channel.runtime-2jwkMPGR.js} +3 -3
  8. package/dist/{group-policy-BWqG2esy.js → group-policy-Cp8SDG4G.js} +2 -2
  9. package/dist/{monitor-AmSj6QIH.js → monitor-CESwxMQ4.js} +30 -25
  10. package/dist/{question-reactions-viP7ZcyG.js → question-reactions-9tBYB1_F.js} +4 -7
  11. package/dist/{reaction-context-BAYI7pz0.js → reaction-context-Br-vAJFp.js} +9 -3
  12. package/dist/{remote-file-COTN7196.js → remote-file-Biz5PjXi.js} +3 -52
  13. package/dist/runtime-api.js +3 -3
  14. package/dist/{sanitize-outbound-CN3Hxbjy.js → sanitize-outbound-Bvo4g1Mp.js} +78 -1
  15. package/dist/{send-v0blZfaI.js → send-DC981dqK.js} +5 -4
  16. package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
  17. package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
  18. package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
  19. package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
  20. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  21. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  22. package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
  23. package/node_modules/typebox/build/system/memory/create.mjs +3 -4
  24. package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
  25. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  26. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  27. package/node_modules/typebox/build/system/memory/update.mjs +3 -2
  28. package/node_modules/typebox/package.json +1 -1
  29. package/openclaw.plugin.json +2 -1
  30. package/package.json +5 -5
@@ -1,5 +1,5 @@
1
- import { _ as normalizeDirectChatIdentifier, f as resolveIMessageMessageId, n as sanitizeIMessageFinalOutboundText, o as createIMessageRpcClient } from "./sanitize-outbound-CN3Hxbjy.js";
2
- import { i as runIMessageCliJsonCommand, n as authorizeIMessageResourceReference, t as withIMessageRemoteFile } from "./remote-file-COTN7196.js";
1
+ import { n as sanitizeIMessageFinalOutboundText, o as createIMessageRpcClient, p as resolveIMessageMessageId, s as runIMessageCliJsonCommand, v as normalizeDirectChatIdentifier } from "./sanitize-outbound-Bvo4g1Mp.js";
2
+ import { n as authorizeIMessageResourceReference, t as withIMessageRemoteFile } from "./remote-file-Biz5PjXi.js";
3
3
  import { basename, parse, win32 } from "node:path";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { asDateTimestampMs, parseStrictInteger, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
package/dist/api.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./accounts-CCirBEIm.js";
2
2
  import { _ as IMESSAGE_ACTION_NAMES, a as isAllowedIMessageSender, c as parseIMessageAllowTarget, g as IMESSAGE_ACTIONS, l as parseIMessageTarget, n as formatIMessageChatTarget, o as looksLikeIMessageExplicitTargetId, r as inferIMessageTargetChatType, s as normalizeIMessageHandle } from "./message-tool-api-CUoFESHj.js";
3
- import { p as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./sanitize-outbound-CN3Hxbjy.js";
4
- import { a as normalizeIMessageAcpConversationId, c as normalizeIMessageMessagingTarget, f as probeIMessage, i as matchIMessageAcpConversation, n as resolveIMessageGroupToolPolicy, o as resolveIMessageConversationIdFromTarget, r as resolveIMessageInboundConversationId, s as looksLikeIMessageTargetId, t as resolveIMessageGroupRequireMention, v as imessageSetupContract } from "./group-policy-BWqG2esy.js";
5
- import { n as createIMessagePluginBase, r as imessageSetupWizard, t as imessagePlugin } from "./channel-zDmMTHWD.js";
3
+ import { m as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./sanitize-outbound-Bvo4g1Mp.js";
4
+ import { a as normalizeIMessageAcpConversationId, c as normalizeIMessageMessagingTarget, f as probeIMessage, i as matchIMessageAcpConversation, n as resolveIMessageGroupToolPolicy, o as resolveIMessageConversationIdFromTarget, r as resolveIMessageInboundConversationId, s as looksLikeIMessageTargetId, t as resolveIMessageGroupRequireMention, v as imessageSetupContract } from "./group-policy-Cp8SDG4G.js";
5
+ import { n as createIMessagePluginBase, r as imessageSetupWizard, t as imessagePlugin } from "./channel-BxraMrmK.js";
6
6
  import { t as createIMessageConversationBindingManager } from "./conversation-bindings-GDQ_Laxj.js";
7
7
  import { t as IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps-B-QEsLSM.js";
8
8
  import { createAllowedChatSenderMatcher, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow, resolveServicePrefixedAllowTarget, resolveServicePrefixedChatTarget, resolveServicePrefixedOrChatAllowTarget, resolveServicePrefixedTarget } from "openclaw/plugin-sdk/channel-targets";
@@ -1,9 +1,9 @@
1
1
  import { o as resolveIMessageAccount } from "./accounts-CCirBEIm.js";
2
2
  import { f as getCachedIMessagePrivateApiStatus, l as parseIMessageTarget } from "./message-tool-api-CUoFESHj.js";
3
- import { i as extractMarkdownFormatRuns } from "./sanitize-outbound-CN3Hxbjy.js";
4
- import { c as normalizeIMessageMessagingTarget, l as getIMessageApprovalApprovers } from "./group-policy-BWqG2esy.js";
5
- import { a as unregisterIMessageApprovalReactionTarget, c as buildIMessageApprovalConversationKeyForTarget, i as registerIMessageApprovalReactionTarget } from "./approval-reactions-DcLRPx7O.js";
6
- import { a as iMessageApprovalPollTargets, c as iMessageApprovalControlBindings, i as buildApprovalPollOptions, o as mapSentPollOptionsToDecisions, t as sendMessageIMessage } from "./send-v0blZfaI.js";
3
+ import { i as extractMarkdownFormatRuns } from "./sanitize-outbound-Bvo4g1Mp.js";
4
+ import { c as normalizeIMessageMessagingTarget, l as getIMessageApprovalApprovers } from "./group-policy-Cp8SDG4G.js";
5
+ import { a as unregisterIMessageApprovalReactionTarget, c as buildIMessageApprovalConversationKeyForTarget, i as registerIMessageApprovalReactionTarget } from "./approval-reactions-sVpDno7d.js";
6
+ import { a as iMessageApprovalPollTargets, c as iMessageApprovalControlBindings, i as buildApprovalPollOptions, o as mapSentPollOptionsToDecisions, t as sendMessageIMessage } from "./send-DC981dqK.js";
7
7
  import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
8
8
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
9
9
  import { createActionGate } from "openclaw/plugin-sdk/channel-actions";
@@ -13,7 +13,7 @@ import { buildChannelApprovalExpiredText, buildChannelApprovalResolvedText, crea
13
13
  import { setTimeout } from "node:timers/promises";
14
14
  //#region extensions/imessage/src/approval-handler.runtime.ts
15
15
  const log = createSubsystemLogger("imessage/approvals");
16
- const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-DCjNT81u.js"), "imessageActionsRuntime");
16
+ const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-D5MAgeSs.js"), "imessageActionsRuntime");
17
17
  const DEFAULT_PROBE_TIMEOUT_MS = 5e3;
18
18
  const APPROVAL_POLL_ORDERING_DELAY_MS = 1100;
19
19
  function buildPendingPayload(params) {
@@ -1,8 +1,8 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { l as parseIMessageTarget, s as normalizeIMessageHandle } from "./message-tool-api-CUoFESHj.js";
3
- import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-BWqG2esy.js";
3
+ import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-Cp8SDG4G.js";
4
4
  import { n as getOptionalIMessageRuntime } from "./runtime-Cza4CY5T.js";
5
- import { t as resolveIMessageReactionContext } from "./reaction-context-BAYI7pz0.js";
5
+ import { n as normalizeIMessageGuid, t as resolveIMessageReactionContext } from "./reaction-context-Br-vAJFp.js";
6
6
  import { createLazyRuntimeSurface } from "openclaw/plugin-sdk/lazy-runtime";
7
7
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { asDateTimestampMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
@@ -10,10 +10,6 @@ import { isApprovalNotFoundError } from "openclaw/plugin-sdk/error-runtime";
10
10
  import { addApprovalReactionHintToText, approvalReactionDecisionSetsMatch, buildApprovalReactionDeliveredBindingMarker, buildApprovalReactionHint, createApprovalReactionTargetStore, listApprovalReactionBindings, normalizeApprovalReactionDecision, readApprovalReactionDecisionList, readApprovalReactionDeliveredBinding, readApprovalReactionPresentationBinding, resolveTypedApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
11
11
  import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
12
12
  //#region extensions/imessage/src/approval-target-keys.ts
13
- /** Strip the `p:<n>/` part prefix Messages puts on some GUIDs so keys match. */
14
- function normalizeIMessageGuid(value) {
15
- return value.trim().replace(/^p:\d+\//iu, "");
16
- }
17
13
  function chatIdToKeyValue(chatId) {
18
14
  if (chatId == null || chatId === "") return null;
19
15
  if (typeof chatId === "number") return Number.isFinite(chatId) && chatId > 0 ? String(chatId) : null;
@@ -559,4 +555,4 @@ function clearIMessageApprovalReactionTargetsForTest() {
559
555
  loadResolveApprovalOverGateway.clear();
560
556
  }
561
557
  //#endregion
562
- export { unregisterIMessageApprovalReactionTarget as a, buildIMessageApprovalConversationKeyForTarget as c, normalizeConversationKey as d, normalizeIMessageGuid as f, registerIMessageApprovalReactionTarget as i, enumerateApprovalTargetKeys as l, handleIMessageApprovalReaction as n, listPendingIMessageApprovalReactionPollTargets as o, maybeResolveIMessageApprovalReaction as r, buildIMessageApprovalConversationKeyForInbound as s, approval_reactions_exports as t, enumerateConversationKeyForms as u };
558
+ export { unregisterIMessageApprovalReactionTarget as a, buildIMessageApprovalConversationKeyForTarget as c, normalizeConversationKey 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, enumerateConversationKeyForms as u };
@@ -1,7 +1,7 @@
1
1
  import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, t as collectIMessageDuplicateAccountSourceWarnings } from "./accounts-CCirBEIm.js";
2
2
  import { l as parseIMessageTarget, o as looksLikeIMessageExplicitTargetId, r as inferIMessageTargetChatType, s as normalizeIMessageHandle, u as isIMessagePhoneLikeHandle } from "./message-tool-api-CUoFESHj.js";
3
- import { n as sanitizeIMessageFinalOutboundText, r as sanitizeOutboundText, v as resolveIMessageDirectChatService } from "./sanitize-outbound-CN3Hxbjy.js";
4
- import { a as normalizeIMessageAcpConversationId, c as normalizeIMessageMessagingTarget, d as imessageMessageActions, h as createIMessageSetupWizardProxy, i as matchIMessageAcpConversation, l as getIMessageApprovalApprovers, n as resolveIMessageGroupToolPolicy, o as resolveIMessageConversationIdFromTarget, t as resolveIMessageGroupRequireMention, u as imessageApprovalAuth, v as imessageSetupContract } from "./group-policy-BWqG2esy.js";
3
+ import { n as sanitizeIMessageFinalOutboundText, r as sanitizeOutboundText, y as resolveIMessageDirectChatService } from "./sanitize-outbound-Bvo4g1Mp.js";
4
+ import { a as normalizeIMessageAcpConversationId, c as normalizeIMessageMessagingTarget, d as imessageMessageActions, h as createIMessageSetupWizardProxy, i as matchIMessageAcpConversation, l as getIMessageApprovalApprovers, n as resolveIMessageGroupToolPolicy, o as resolveIMessageConversationIdFromTarget, t as resolveIMessageGroupRequireMention, u as imessageApprovalAuth, v as imessageSetupContract } from "./group-policy-Cp8SDG4G.js";
5
5
  import { t as createIMessageConversationBindingManager } from "./conversation-bindings-GDQ_Laxj.js";
6
6
  import { t as IMessageChannelConfigSchema } from "./config-schema-DuGbA8Kp.js";
7
7
  import { n as resolveIMessageAttachmentRoots, r as resolveIMessageRemoteAttachmentRoots } from "./media-contract-pns3TSS5.js";
@@ -90,7 +90,7 @@ const imessageApproval = createApproverRestrictedNativeApprovalCapabilityFromFor
90
90
  approvalKind,
91
91
  request
92
92
  }),
93
- load: async () => (await import("./approval-handler.runtime-BReeID1z.js")).imessageApprovalNativeRuntime
93
+ load: async () => (await import("./approval-handler.runtime-47rs6THN.js")).imessageApprovalNativeRuntime
94
94
  })
95
95
  });
96
96
  const imessageApprovalRouting = imessageApproval.routing;
@@ -205,7 +205,7 @@ const imessageDoctor = {
205
205
  //#region extensions/imessage/src/shared.ts
206
206
  const IMESSAGE_CHANNEL = "imessage";
207
207
  async function loadIMessageChannelRuntime$1() {
208
- return await import("./channel.runtime-qQBHCle8.js");
208
+ return await import("./channel.runtime-2jwkMPGR.js");
209
209
  }
210
210
  const imessageSetupWizard = createIMessageSetupWizardProxy(async () => (await loadIMessageChannelRuntime$1()).imessageSetupWizard);
211
211
  const imessageConfigAdapter = createScopedChannelConfigAdapter({
@@ -267,7 +267,10 @@ function createIMessagePluginBase(params) {
267
267
  effects: true,
268
268
  groupManagement: true
269
269
  },
270
- reload: { configPrefixes: ["channels.imessage"] },
270
+ reload: {
271
+ configPrefixes: ["channels.imessage"],
272
+ noopPrefixes: ["messages.inbound"]
273
+ },
271
274
  configSchema: IMessageChannelConfigSchema,
272
275
  config: {
273
276
  ...imessageConfigAdapter,
@@ -304,7 +307,7 @@ async function probeIMessageStatusAccount(params) {
304
307
  }
305
308
  //#endregion
306
309
  //#region extensions/imessage/src/channel.ts
307
- const loadIMessageChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-qQBHCle8.js"));
310
+ const loadIMessageChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-2jwkMPGR.js"));
308
311
  function toIMessageMessageSendResult(result, kind, replyToId) {
309
312
  const receipt = result.receipt ?? createMessageReceiptFromOutboundResults({
310
313
  results: result.messageId ? [{
@@ -320,8 +323,8 @@ function toIMessageMessageSendResult(result, kind, replyToId) {
320
323
  ...result.meta && Object.keys(result.meta).length > 0 ? { meta: result.meta } : {}
321
324
  };
322
325
  }
323
- const loadIMessageApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-DcLRPx7O.js").then((n) => n.t));
324
- const loadIMessageQuestionReactionsModule = createLazyRuntimeModule(() => import("./question-reactions-viP7ZcyG.js").then((n) => n.r));
326
+ const loadIMessageApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-sVpDno7d.js").then((n) => n.t));
327
+ const loadIMessageQuestionReactionsModule = createLazyRuntimeModule(() => import("./question-reactions-9tBYB1_F.js").then((n) => n.r));
325
328
  async function prepareForwardedIMessageApprovalPayload(params) {
326
329
  const prepared = (await loadIMessageApprovalReactionsModule()).addIMessageApprovalReactionHintToStructuredPayload(params);
327
330
  if (prepared) Object.assign(params.payload, prepared);
@@ -1,2 +1,2 @@
1
- import { t as imessagePlugin } from "./channel-zDmMTHWD.js";
1
+ import { t as imessagePlugin } from "./channel-BxraMrmK.js";
2
2
  export { imessagePlugin };
@@ -1,8 +1,8 @@
1
1
  import { l as resolveIMessageRemoteHost, o as resolveIMessageAccount, r as listEnabledIMessageAccounts, s as resolveIMessageDuplicateSourceOwner } from "./accounts-CCirBEIm.js";
2
- import { _ as imessageDmPolicy, b as isAutoManagedIMessageCliPath, f as probeIMessage, g as imessageCompletionNote, m as createIMessageCliPathTextInput, p as IMESSAGE_INSTALL_COMMAND, x as normalizeIMessageCliPathForSetup, y as imessageSetupStatusBase } from "./group-policy-BWqG2esy.js";
2
+ import { _ as imessageDmPolicy, b as isAutoManagedIMessageCliPath, f as probeIMessage, g as imessageCompletionNote, m as createIMessageCliPathTextInput, p as IMESSAGE_INSTALL_COMMAND, x as normalizeIMessageCliPathForSetup, y as imessageSetupStatusBase } from "./group-policy-Cp8SDG4G.js";
3
3
  import { t as IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps-B-QEsLSM.js";
4
- import { t as sendMessageIMessage } from "./send-v0blZfaI.js";
5
- import { t as monitorIMessageProvider } from "./monitor-AmSj6QIH.js";
4
+ import { t as sendMessageIMessage } from "./send-DC981dqK.js";
5
+ import { t as monitorIMessageProvider } from "./monitor-CESwxMQ4.js";
6
6
  import { createAccountStatusSink, resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
7
7
  import path from "node:path";
8
8
  import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
@@ -1,6 +1,6 @@
1
1
  import { a as resolveDefaultIMessageAccountId, l as resolveIMessageRemoteHost, n as hasExclusiveIMessageLocalDatabase, o as resolveIMessageAccount, u as expandIMessageUserPath } from "./accounts-CCirBEIm.js";
2
2
  import { _ as IMESSAGE_ACTION_NAMES, d as normalizeBareIMessageChatIdentifier, f as getCachedIMessagePrivateApiStatus, g as IMESSAGE_ACTIONS, h as setCachedIMessagePrivateApiStatus, l as parseIMessageTarget, p as imessageRpcSupportsMethod, s as normalizeIMessageHandle$1, t as describeIMessageMessageTool, u as isIMessagePhoneLikeHandle } from "./message-tool-api-CUoFESHj.js";
3
- import { c as isIMessageCurrentMessageInChat, h as chatContextFromIMessageTarget, o as createIMessageRpcClient, s as findLatestIMessageEntryForChat, u as rememberIMessageReplyCache } from "./sanitize-outbound-CN3Hxbjy.js";
3
+ import { c as findLatestIMessageEntryForChat, d as rememberIMessageReplyCache, g as chatContextFromIMessageTarget, l as isIMessageCurrentMessageInChat, o as createIMessageRpcClient } from "./sanitize-outbound-Bvo4g1Mp.js";
4
4
  import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
5
5
  import path from "node:path";
6
6
  import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution";
@@ -519,7 +519,7 @@ async function probeIMessage(timeoutMs, opts = {}) {
519
519
  }
520
520
  //#endregion
521
521
  //#region extensions/imessage/src/actions.ts
522
- const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-DCjNT81u.js"), "imessageActionsRuntime");
522
+ const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-D5MAgeSs.js"), "imessageActionsRuntime");
523
523
  const log = createSubsystemLogger("channels/imessage");
524
524
  const providerId = "imessage";
525
525
  const SUPPORTED_ACTIONS = /* @__PURE__ */ new Set([...IMESSAGE_ACTION_NAMES, "upload-file"]);
@@ -1,14 +1,14 @@
1
1
  import { d as resolveIMessageChatDbLookupPath, f as resolveIMessageHomeDir, l as resolveIMessageRemoteHost, o as resolveIMessageAccount } from "./accounts-CCirBEIm.js";
2
2
  import { c as parseIMessageAllowTarget, f as getCachedIMessagePrivateApiStatus, i as isAllowedIMessageReplyContextSender, l as parseIMessageTarget, n as formatIMessageChatTarget, p as imessageRpcSupportsMethod, s as normalizeIMessageHandle } from "./message-tool-api-CUoFESHj.js";
3
- import { l as isKnownFromMeIMessageMessageId, o as createIMessageRpcClient, r as sanitizeOutboundText, u as rememberIMessageReplyCache, v as resolveIMessageDirectChatService } from "./sanitize-outbound-CN3Hxbjy.js";
4
- import { f as probeIMessage, r as resolveIMessageInboundConversationId } from "./group-policy-BWqG2esy.js";
3
+ import { d as rememberIMessageReplyCache, o as createIMessageRpcClient, r as sanitizeOutboundText, u as isKnownFromMeIMessageMessageId, y as resolveIMessageDirectChatService } from "./sanitize-outbound-Bvo4g1Mp.js";
4
+ import { f as probeIMessage, r as resolveIMessageInboundConversationId } from "./group-policy-Cp8SDG4G.js";
5
5
  import { t as getIMessageRuntime } from "./runtime-Cza4CY5T.js";
6
6
  import { d as resolveIMessageEchoMediaKey, l as capFailureRetriesMap, t as IMESSAGE_CATCHUP_CURSOR_NAMESPACE, u as resolveIMessageCatchupCursorKey } from "./state-contract-DvahEY4X.js";
7
7
  import { n as resolveIMessageAttachmentRoots, r as resolveIMessageRemoteAttachmentRoots } from "./media-contract-pns3TSS5.js";
8
- import { i as registerIMessageApprovalReactionTarget, n as handleIMessageApprovalReaction, o as listPendingIMessageApprovalReactionPollTargets, r as maybeResolveIMessageApprovalReaction, s as buildIMessageApprovalConversationKeyForInbound } from "./approval-reactions-DcLRPx7O.js";
9
- import { c as iMessageApprovalControlBindings, n as hasPersistedIMessageEcho, r as stripLeadingEchoTextCorruptionMarkers, s as maybeResolveIMessageApprovalPollVote, t as sendMessageIMessage } from "./send-v0blZfaI.js";
10
- import { t as resolveIMessageReactionContext } from "./reaction-context-BAYI7pz0.js";
11
- import { n as maybeResolveIMessageQuestionReaction, t as hasIMessageQuestionReactionTarget } from "./question-reactions-viP7ZcyG.js";
8
+ import { i as registerIMessageApprovalReactionTarget, n as handleIMessageApprovalReaction, o as listPendingIMessageApprovalReactionPollTargets, r as maybeResolveIMessageApprovalReaction, s as buildIMessageApprovalConversationKeyForInbound } from "./approval-reactions-sVpDno7d.js";
9
+ import { c as iMessageApprovalControlBindings, n as hasPersistedIMessageEcho, r as stripLeadingEchoTextCorruptionMarkers, s as maybeResolveIMessageApprovalPollVote, t as sendMessageIMessage } from "./send-DC981dqK.js";
10
+ import { n as normalizeIMessageGuid, t as resolveIMessageReactionContext } from "./reaction-context-Br-vAJFp.js";
11
+ import { n as maybeResolveIMessageQuestionReaction, t as hasIMessageQuestionReactionTarget } from "./question-reactions-9tBYB1_F.js";
12
12
  import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
13
13
  import { chunkMarkdownTextWithMode as chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
14
14
  import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
@@ -20,12 +20,12 @@ import { createNonExitingRuntime, danger, logVerbose, shouldLogVerbose, warn } f
20
20
  import { isInboundPathAllowed, kindFromMime } from "openclaw/plugin-sdk/media-runtime";
21
21
  import { asDateTimestampMs, asPositiveFiniteNumber, parseDateStringTimestampMs, resolveIntegerOption, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
22
22
  import { createHash } from "node:crypto";
23
- import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
23
+ import { createRuntimeConfigReader, getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
24
24
  import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
25
25
  import { collectErrorGraphCandidates, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
26
- import { buildChannelGroupsScopeTree, resolveChannelGroupPolicy, resolveScopeRequireMention } from "openclaw/plugin-sdk/channel-policy";
26
+ import { buildChannelGroupsScopeTree, resolveChannelGroupPolicy, resolveChannelGroups, resolveChannelGroupsConfigPath, resolveScopeRequireMention } from "openclaw/plugin-sdk/channel-policy";
27
27
  import { convertMarkdownTables as convertMarkdownTables$1, findCodeRegions, isInsideCode, sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
28
- import { buildChannelInboundEventContext, buildMentionRegexes, createChannelInboundDebouncer, createChannelPartialDeliveryError, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundFromLabel, formatInboundMediaUnavailableText, formatMediaPlaceholderText, isChannelPartialDeliveryError, logInboundDrop, matchesMentionPatterns, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, shouldDebounceTextInbound, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
28
+ import { buildChannelInboundEventContext, buildMentionRegexes, createChannelInboundDebouncer, createChannelPartialDeliveryError, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundFromLabel, formatInboundMediaUnavailableText, formatMediaPlaceholderText, isChannelPartialDeliveryError, logInboundDrop, matchesMentionPatterns, resolveEnvelopeFormatOptions, resolveInboundDebounceMs, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, shouldDebounceTextInbound, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
29
29
  import { resolveAgentConfig, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
30
30
  import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
31
31
  import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
@@ -73,13 +73,10 @@ function hasUnscopedTarget(targets) {
73
73
  function uniqueChatIds(chatIds) {
74
74
  return [...new Set(chatIds)];
75
75
  }
76
- function normalizeMessageGuid(value) {
77
- return value.trim().replace(/^p:\d+\//iu, "");
78
- }
79
76
  function enumerateMessageGuidCandidates(value) {
80
77
  const trimmed = value.trim();
81
78
  if (!trimmed) return [];
82
- return [trimmed, normalizeMessageGuid(trimmed)].filter((candidate, index, candidates) => candidate.length > 0 && candidates.indexOf(candidate) === index);
79
+ return [trimmed, normalizeIMessageGuid(trimmed)].filter((candidate, index, candidates) => candidate.length > 0 && candidates.indexOf(candidate) === index);
83
80
  }
84
81
  function buildPendingTargetsByMessageId(targets) {
85
82
  const pendingByMessageId = /* @__PURE__ */ new Map();
@@ -170,7 +167,7 @@ async function pollPendingIMessageApprovalReactions(params) {
170
167
  for (const message of messages) {
171
168
  const targetGuid = message.guid?.trim();
172
169
  if (!targetGuid) continue;
173
- const target = pendingByMessageId.get(targetGuid) ?? pendingByMessageId.get(normalizeMessageGuid(targetGuid));
170
+ const target = pendingByMessageId.get(targetGuid) ?? pendingByMessageId.get(normalizeIMessageGuid(targetGuid));
174
171
  if (!target) continue;
175
172
  bindObservedConversation({
176
173
  target,
@@ -2799,17 +2796,16 @@ const IMESSAGE_DIAGNOSTIC_DROP_REASONS = /* @__PURE__ */ new Set([
2799
2796
  "agent echo in self-chat",
2800
2797
  "echo",
2801
2798
  "from me",
2799
+ "no mention",
2802
2800
  "reflected assistant content",
2803
2801
  "self-chat echo"
2804
2802
  ]);
2805
- const IMESSAGE_THROTTLED_DIAGNOSTIC_DROP_REASONS = /* @__PURE__ */ new Set(["from me"]);
2806
- function shouldThrottleIMessageInboundDropDiagnostic(reason) {
2807
- return IMESSAGE_THROTTLED_DIAGNOSTIC_DROP_REASONS.has(reason);
2808
- }
2803
+ const IMESSAGE_THROTTLED_DIAGNOSTIC_DROP_REASONS = /* @__PURE__ */ new Set(["from me", "no mention"]);
2809
2804
  function describeIMessageInboundDropDiagnostic(params) {
2810
2805
  if (!IMESSAGE_DIAGNOSTIC_DROP_REASONS.has(params.reason)) return null;
2811
2806
  const messageId = typeof params.message.id === "number" || typeof params.message.id === "string" ? String(params.message.id) : "unknown";
2812
- return `imessage: dropped inbound message account=${params.accountId} reason=${JSON.stringify(params.reason)} chat_id=${params.message.chat_id ?? "unknown"} group=${params.message.is_group === true} message_id=${messageId} guid=${params.message.guid ? "present" : "missing"} created_at=${params.message.created_at ?? "unknown"}`;
2807
+ const mentionHint = params.reason === "no mention" ? ` Mention the agent (default patterns come from its identity name/emoji), or set ${params.groupsConfigPath}["${params.message.chat_id}"].requireMention=false. Preserve existing groups entries; when adding the first groups map, include "*": {} to keep other chats admitted.` : "";
2808
+ return `imessage: dropped inbound message account=${params.accountId} reason=${JSON.stringify(params.reason)} chat_id=${params.message.chat_id ?? "unknown"} group=${params.message.is_group === true} message_id=${messageId} guid=${params.message.guid ? "present" : "missing"} created_at=${params.message.created_at ?? "unknown"}${mentionHint}`;
2813
2809
  }
2814
2810
  function describeIMessageWatchSubscribeStartupFailure(params) {
2815
2811
  const retry = params.retryDelayMs !== void 0 ? ` retry_in_ms=${params.retryDelayMs}` : "";
@@ -2833,10 +2829,17 @@ async function waitForWatchSubscribeRetryDelay(params) {
2833
2829
  async function monitorIMessageProvider(opts = {}) {
2834
2830
  const runtime = resolveRuntime(opts);
2835
2831
  const cfg = opts.config ?? getRuntimeConfig();
2832
+ const readConfig = createRuntimeConfigReader(cfg);
2836
2833
  const accountInfo = resolveIMessageAccount({
2837
2834
  cfg,
2838
2835
  accountId: opts.accountId
2839
2836
  });
2837
+ const groupsConfigPath = resolveChannelGroupsConfigPath({
2838
+ cfg,
2839
+ channel: "imessage",
2840
+ accountId: accountInfo.accountId,
2841
+ groups: resolveChannelGroups(cfg, "imessage", accountInfo.accountId)
2842
+ });
2840
2843
  const approvalGatewayRuntime = opts.channelRuntime?.runtimeContexts.get({
2841
2844
  channelId: "imessage",
2842
2845
  accountId: accountInfo.accountId,
@@ -2941,6 +2944,10 @@ async function monitorIMessageProvider(opts = {}) {
2941
2944
  const { debouncer: inboundDebouncer } = createChannelInboundDebouncer({
2942
2945
  cfg,
2943
2946
  channel: "imessage",
2947
+ resolveDebounceMs: () => resolveInboundDebounceMs({
2948
+ cfg: readConfig(),
2949
+ channel: "imessage"
2950
+ }),
2944
2951
  buildKey: (entry) => {
2945
2952
  const msg = entry.message;
2946
2953
  const sender = msg.sender?.trim();
@@ -3041,9 +3048,6 @@ async function monitorIMessageProvider(opts = {}) {
3041
3048
  runtime.error?.(`imessage catchup: failed to advance pending live cursor: ${String(err)}`);
3042
3049
  }
3043
3050
  }
3044
- async function handleMessageNow(message, ingressLifecycle) {
3045
- await handleMessageNowInner(message, ingressLifecycle);
3046
- }
3047
3051
  const pollCommentFolder = createPollCommentFolder();
3048
3052
  function resolveIMessageInboundBodyText(message) {
3049
3053
  const messageText = ((message.poll ? renderIMessagePollBody(message.poll, message.sender, { preferOptionId: Boolean(remoteHost) }) : null) ?? message.text ?? "").trim();
@@ -3060,7 +3064,7 @@ async function monitorIMessageProvider(opts = {}) {
3060
3064
  effectiveAttachmentRoots
3061
3065
  };
3062
3066
  }
3063
- async function handleMessageNowInner(rawMessage, ingressLifecycle) {
3067
+ async function handleMessageNow(rawMessage, ingressLifecycle) {
3064
3068
  const message = await repairMessageConversationAnchor(rawMessage);
3065
3069
  if (!message) return;
3066
3070
  const pollFoldAtMs = message.created_at ? Date.parse(message.created_at) : NaN;
@@ -3105,12 +3109,13 @@ async function monitorIMessageProvider(opts = {}) {
3105
3109
  if (decision.reason === "echo" || decision.reason === "reflected assistant content") loopRateLimiter.record(rateLimitKey);
3106
3110
  const diagnostic = describeIMessageInboundDropDiagnostic({
3107
3111
  accountId: accountInfo.accountId,
3112
+ groupsConfigPath,
3108
3113
  reason: decision.reason,
3109
3114
  message
3110
3115
  });
3111
3116
  if (diagnostic) {
3112
3117
  const throttleKey = `${rateLimitKey}:${decision.reason}`;
3113
- if (!shouldThrottleIMessageInboundDropDiagnostic(decision.reason) || !loggedThrottledDropDiagnostics.check(throttleKey)) runtime.log?.(warn(diagnostic));
3118
+ if (!IMESSAGE_THROTTLED_DIAGNOSTIC_DROP_REASONS.has(decision.reason) || !loggedThrottledDropDiagnostics.check(throttleKey)) runtime.log?.(warn(diagnostic));
3114
3119
  }
3115
3120
  if (decision.reason === "group id not in allowlist") warnGroupAllowlistDropPerChatOnce({
3116
3121
  accountId: accountInfo.accountId,
@@ -3539,7 +3544,7 @@ async function monitorIMessageProvider(opts = {}) {
3539
3544
  const repairedMessage = await repairMessageConversationAnchor(message);
3540
3545
  if (!repairedMessage) return { kind: "completed" };
3541
3546
  if (isApprovalCommand) {
3542
- await handleMessageNowInner(repairedMessage);
3547
+ await handleMessageNow(repairedMessage);
3543
3548
  return { kind: "completed" };
3544
3549
  }
3545
3550
  const conversation = resolveApprovalControlConversation(repairedMessage);
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { t as resolveIMessageReactionContext } from "./reaction-context-BAYI7pz0.js";
2
+ import { n as normalizeIMessageGuid, t as resolveIMessageReactionContext } from "./reaction-context-Br-vAJFp.js";
3
3
  import { createQuestionReactionTargetStore, questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
4
4
  //#region extensions/imessage/src/question-reactions.ts
5
5
  var question_reactions_exports = /* @__PURE__ */ __exportAll({
@@ -7,12 +7,9 @@ var question_reactions_exports = /* @__PURE__ */ __exportAll({
7
7
  maybeResolveIMessageQuestionReaction: () => maybeResolveIMessageQuestionReaction,
8
8
  registerIMessageQuestionReactionTargetForDeliveredPayload: () => registerIMessageQuestionReactionTargetForDeliveredPayload
9
9
  });
10
- function normalizeGuid(value) {
11
- return value.trim().replace(/^p:\d+\//iu, "");
12
- }
13
10
  function buildKey(identity) {
14
11
  const account = identity.accountId.trim();
15
- const guid = normalizeGuid(identity.messageGuid);
12
+ const guid = normalizeIMessageGuid(identity.messageGuid);
16
13
  return account && guid ? `${account}:${guid}` : null;
17
14
  }
18
15
  const questionReactionTargets = createQuestionReactionTargetStore({
@@ -25,7 +22,7 @@ const questionReactionTargets = createQuestionReactionTargetStore({
25
22
  function reactionCandidates(message, bodyText) {
26
23
  const reaction = resolveIMessageReactionContext(message, bodyText);
27
24
  if (!reaction) return null;
28
- const guids = Array.from(new Set([...reaction.targetGuids ?? [], reaction.targetGuid ?? ""].map(normalizeGuid).filter(Boolean)));
25
+ const guids = Array.from(new Set([...reaction.targetGuids ?? [], reaction.targetGuid ?? ""].map(normalizeIMessageGuid).filter(Boolean)));
29
26
  return guids.length > 0 ? {
30
27
  action: reaction.action,
31
28
  emoji: reaction.emoji,
@@ -39,7 +36,7 @@ function registerIMessageQuestionReactionTargetForDeliveredPayload(params) {
39
36
  for (const result of params.results) {
40
37
  if (result.channel !== "imessage") continue;
41
38
  const guid = typeof result.meta?.imessageMessageGuid === "string" ? result.meta.imessageMessageGuid : result.messageId;
42
- if (/^\d+$/u.test(normalizeGuid(guid))) continue;
39
+ if (/^\d+$/u.test(normalizeIMessageGuid(guid))) continue;
43
40
  registered = questionReactionTargets.register(binding, {
44
41
  accountId: params.accountId,
45
42
  messageGuid: guid
@@ -1,3 +1,9 @@
1
+ //#region extensions/imessage/src/message-guid.ts
2
+ /** Strip the `p:<n>/` part prefix Messages puts on some GUIDs so keys match. */
3
+ function normalizeIMessageGuid(value) {
4
+ return value.trim().replace(/^p:\d+\//iu, "");
5
+ }
6
+ //#endregion
1
7
  //#region extensions/imessage/src/monitor/reaction-context.ts
2
8
  const TAPBACK_TEXT_PATTERNS = [
3
9
  {
@@ -62,7 +68,7 @@ const TAPBACK_TEXT_PATTERNS = [
62
68
  }
63
69
  ];
64
70
  function normalizeReactionValue(value) {
65
- return typeof value === "string" ? value.trim().replace(/^p:\d+\//iu, "") || void 0 : void 0;
71
+ return typeof value === "string" ? normalizeIMessageGuid(value) || void 0 : void 0;
66
72
  }
67
73
  function resolveReactionTargetGuidCandidates(...values) {
68
74
  const candidates = [];
@@ -70,7 +76,7 @@ function resolveReactionTargetGuidCandidates(...values) {
70
76
  if (typeof value !== "string") continue;
71
77
  const raw = value.trim();
72
78
  if (!raw) continue;
73
- const normalized = raw.replace(/^p:\d+\//iu, "");
79
+ const normalized = normalizeIMessageGuid(raw);
74
80
  for (const candidate of [normalized, raw]) if (candidate && !candidates.includes(candidate)) candidates.push(candidate);
75
81
  }
76
82
  return candidates;
@@ -102,4 +108,4 @@ function resolveIMessageReactionContext(message, bodyText) {
102
108
  return resolveTapbackTextContext(bodyText);
103
109
  }
104
110
  //#endregion
105
- export { resolveIMessageReactionContext as t };
111
+ export { normalizeIMessageGuid as n, resolveIMessageReactionContext as t };
@@ -1,5 +1,5 @@
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-CN3Hxbjy.js";
1
+ import { p as resolveLocalIMessageChatDbPath } from "./accounts-CCirBEIm.js";
2
+ import { _ as isIMessageEmailChatIdentifier, f as resolveIMessageCachedResourceBinding, g as chatContextFromIMessageTarget, p as resolveIMessageMessageId } from "./sanitize-outbound-Bvo4g1Mp.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";
@@ -8,55 +8,6 @@ import { randomUUID } from "node:crypto";
8
8
  import { runCommandWithTimeout } from "openclaw/plugin-sdk/process-runtime";
9
9
  import { openNodeSqliteDatabase } from "openclaw/plugin-sdk/sqlite-runtime";
10
10
  import { sanitizeTempFileName } from "openclaw/plugin-sdk/temp-path";
11
- //#region extensions/imessage/src/cli-output.ts
12
- const IMESSAGE_CLI_STDOUT_MAX_BYTES = 8388608;
13
- const IMESSAGE_CLI_STDERR_TAIL_BYTES = 65536;
14
- function parseLastJsonObject(stdout) {
15
- const last = stdout.split(/\r?\n/u).findLast((line) => line.trim().length > 0)?.trim();
16
- if (!last) return null;
17
- try {
18
- const value = JSON.parse(last);
19
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
20
- } catch {
21
- return null;
22
- }
23
- }
24
- async function runIMessageCliJsonCommand(params) {
25
- const dbPath = params.dbPath?.trim();
26
- const argv = [
27
- expandIMessageUserPath(params.cliPath),
28
- ...params.args,
29
- ...dbPath ? ["--db", dbPath] : [],
30
- "--json"
31
- ];
32
- const result = await runCommandWithTimeout(argv, {
33
- killProcessTree: true,
34
- maxOutputBytes: {
35
- stdout: IMESSAGE_CLI_STDOUT_MAX_BYTES,
36
- stderr: IMESSAGE_CLI_STDERR_TAIL_BYTES
37
- },
38
- outputCapture: {
39
- stdout: "head",
40
- stderr: "tail"
41
- },
42
- terminateOnOutputLimit: { stdout: true },
43
- timeoutMs: params.timeoutMs
44
- });
45
- if (result.termination === "timeout") throw new Error(`iMessage action timed out after ${params.timeoutMs}ms`);
46
- if (result.outputLimitExceeded || result.stdoutTruncatedBytes) throw new Error(`imsg stdout exceeded ${IMESSAGE_CLI_STDOUT_MAX_BYTES} bytes`);
47
- const parsed = parseLastJsonObject(result.stdout);
48
- if (result.code !== 0) {
49
- const detail = typeof parsed?.error === "string" && parsed.error.trim() || result.stderr.trim() || result.stdout.trim() || `imsg exited with code ${result.code}`;
50
- throw new Error(detail);
51
- }
52
- if (!parsed) throw new Error(`imsg returned non-JSON output: ${result.stdout.trim() || result.stderr.trim()}`);
53
- if (parsed.success === false) {
54
- const detail = typeof parsed.error === "string" && parsed.error.trim() ? parsed.error.trim() : "iMessage action failed";
55
- throw new Error(detail);
56
- }
57
- return parsed;
58
- }
59
- //#endregion
60
11
  //#region extensions/imessage/src/message-resource-db.ts
61
12
  function normalizeIMessageMessageGuidForLookup(messageId) {
62
13
  const trimmed = messageId.trim();
@@ -291,4 +242,4 @@ rm -rf -- ${remoteDir}
291
242
  }
292
243
  }
293
244
  //#endregion
294
- export { runIMessageCliJsonCommand as i, authorizeIMessageResourceReference as n, resolveAuthorizedIMessageReplyReference as r, withIMessageRemoteFile as t };
245
+ export { authorizeIMessageResourceReference as n, resolveAuthorizedIMessageReplyReference as r, withIMessageRemoteFile as t };
@@ -1,9 +1,9 @@
1
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-BWqG2esy.js";
2
+ import { c as normalizeIMessageMessagingTarget, d as imessageMessageActions, f as probeIMessage, n as resolveIMessageGroupToolPolicy, s as looksLikeIMessageTargetId, t as resolveIMessageGroupRequireMention } from "./group-policy-Cp8SDG4G.js";
3
3
  import { r as setIMessageRuntime } from "./runtime-Cza4CY5T.js";
4
4
  import { n as IMessageConfigSchema } from "./config-schema-DuGbA8Kp.js";
5
- import { t as sendMessageIMessage } from "./send-v0blZfaI.js";
6
- import { t as monitorIMessageProvider } from "./monitor-AmSj6QIH.js";
5
+ import { t as sendMessageIMessage } from "./send-DC981dqK.js";
6
+ import { t as monitorIMessageProvider } from "./monitor-CESwxMQ4.js";
7
7
  import { formatTrimmedAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers";
8
8
  import { buildComputedAccountStatusSnapshot, collectStatusIssuesFromLastError } from "openclaw/plugin-sdk/status-helpers";
9
9
  import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
@@ -5,6 +5,7 @@ import { a as IMESSAGE_REPLY_CACHE_NAMESPACE, f as resolveIMessageReplyCacheEntr
5
5
  import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution";
6
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
8
+ import { runCommandWithTimeout } from "openclaw/plugin-sdk/process-runtime";
8
9
  import { resolveUserPath } from "openclaw/plugin-sdk/text-utility-runtime";
9
10
  import { spawn } from "node:child_process";
10
11
  import { StringDecoder } from "node:string_decoder";
@@ -348,6 +349,77 @@ function isIMessageCurrentMessageInChat(params) {
348
349
  }) === "match";
349
350
  }
350
351
  //#endregion
352
+ //#region extensions/imessage/src/cli-output.ts
353
+ const IMESSAGE_CLI_STDOUT_MAX_BYTES = 8388608;
354
+ const IMESSAGE_CLI_STDERR_TAIL_BYTES = 65536;
355
+ function parseLastJsonObject(stdout) {
356
+ const last = stdout.split(/\r?\n/u).findLast((line) => line.trim().length > 0)?.trim();
357
+ if (!last) return null;
358
+ try {
359
+ const value = JSON.parse(last);
360
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
361
+ } catch {
362
+ return null;
363
+ }
364
+ }
365
+ async function runIMessageCliJsonCommand(params) {
366
+ const dbPath = params.dbPath?.trim();
367
+ const argv = [
368
+ expandIMessageUserPath(params.cliPath),
369
+ ...params.args,
370
+ ...dbPath ? ["--db", dbPath] : [],
371
+ "--json"
372
+ ];
373
+ const result = await runCommandWithTimeout(argv, {
374
+ killProcessTree: true,
375
+ maxOutputBytes: {
376
+ stdout: IMESSAGE_CLI_STDOUT_MAX_BYTES,
377
+ stderr: IMESSAGE_CLI_STDERR_TAIL_BYTES
378
+ },
379
+ outputCapture: {
380
+ stdout: "head",
381
+ stderr: "tail"
382
+ },
383
+ terminateOnOutputLimit: { stdout: true },
384
+ timeoutMs: params.timeoutMs
385
+ });
386
+ if (result.termination === "timeout") throw new Error(`iMessage action timed out after ${params.timeoutMs}ms`);
387
+ if (result.outputLimitExceeded || result.stdoutTruncatedBytes) throw new Error(`imsg stdout exceeded ${IMESSAGE_CLI_STDOUT_MAX_BYTES} bytes`);
388
+ const parsed = parseLastJsonObject(result.stdout);
389
+ if (result.code !== 0) {
390
+ const detail = typeof parsed?.error === "string" && parsed.error.trim() || result.stderr.trim() || result.stdout.trim() || `imsg exited with code ${result.code}`;
391
+ throw new Error(detail);
392
+ }
393
+ if (!parsed) throw new Error(`imsg returned non-JSON output: ${result.stdout.trim() || result.stderr.trim()}`);
394
+ if (parsed.success === false) {
395
+ const detail = typeof parsed.error === "string" && parsed.error.trim() ? parsed.error.trim() : "iMessage action failed";
396
+ throw new Error(detail);
397
+ }
398
+ return parsed;
399
+ }
400
+ //#endregion
401
+ //#region extensions/imessage/src/bridge-recovery.ts
402
+ const BRIDGE_RECOVERY_TIMEOUT_MS = 3e4;
403
+ const recoveries = /* @__PURE__ */ new Map();
404
+ /**
405
+ * Re-inject the private bridge after imsg has positively identified it as
406
+ * unresponsive. This deliberately does not retry the failed mutation: imsg may
407
+ * still reconcile a published send, so replaying it could duplicate a message.
408
+ */
409
+ function recoverIMessageBridge(cliPath) {
410
+ const existing = recoveries.get(cliPath);
411
+ if (existing) return existing;
412
+ const recovery = runIMessageCliJsonCommand({
413
+ cliPath,
414
+ args: ["launch"],
415
+ timeoutMs: BRIDGE_RECOVERY_TIMEOUT_MS
416
+ }).then(() => void 0).finally(() => {
417
+ recoveries.delete(cliPath);
418
+ });
419
+ recoveries.set(cliPath, recovery);
420
+ return recovery;
421
+ }
422
+ //#endregion
351
423
  //#region extensions/imessage/src/client.ts
352
424
  var IMessageRpcRequestError = class extends Error {
353
425
  constructor(message, code, data) {
@@ -483,6 +555,11 @@ var IMessageRpcClient = class {
483
555
  } catch (err) {
484
556
  if (isIMessageBridgeStall(err)) {
485
557
  invalidateCachedIMessagePrivateApiStatus(this.configuredCliPath);
558
+ try {
559
+ await recoverIMessageBridge(this.configuredCliPath);
560
+ } catch (recoveryError) {
561
+ this.runtime?.error?.(`imessage: automatic bridge recovery failed: ${formatErrorMessage(recoveryError)}`);
562
+ }
486
563
  throw describeIMessageBridgeStall(err);
487
564
  }
488
565
  throw err;
@@ -1204,4 +1281,4 @@ function sanitizeOutboundText(text) {
1204
1281
  return cleaned;
1205
1282
  }
1206
1283
  //#endregion
1207
- 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 };
1284
+ export { isIMessageEmailChatIdentifier as _, IMessageRpcRequestError as a, findLatestIMessageEntryForChat as c, rememberIMessageReplyCache as d, resolveIMessageCachedResourceBinding as f, chatContextFromIMessageTarget as g, DEFAULT_IMESSAGE_SEND_TIMEOUT_MS as h, extractMarkdownFormatRuns as i, isIMessageCurrentMessageInChat as l, DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS as m, sanitizeIMessageFinalOutboundText as n, createIMessageRpcClient as o, resolveIMessageMessageId as p, sanitizeOutboundText as r, runIMessageCliJsonCommand as s, protectIMessageFencedRoleMarkers as t, isKnownFromMeIMessageMessageId as u, normalizeDirectChatIdentifier as v, resolveIMessageDirectChatService as y };
@@ -1,11 +1,12 @@
1
1
  import { d as resolveIMessageChatDbLookupPath, l as resolveIMessageRemoteHost, n as hasExclusiveIMessageLocalDatabase, o as resolveIMessageAccount } from "./accounts-CCirBEIm.js";
2
2
  import { l as parseIMessageTarget, n as formatIMessageChatTarget, s as normalizeIMessageHandle } from "./message-tool-api-CUoFESHj.js";
3
- import { a as IMessageRpcRequestError, h as chatContextFromIMessageTarget, n as sanitizeIMessageFinalOutboundText, o as createIMessageRpcClient, t as protectIMessageFencedRoleMarkers, u as rememberIMessageReplyCache, v as resolveIMessageDirectChatService } from "./sanitize-outbound-CN3Hxbjy.js";
4
- import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-BWqG2esy.js";
3
+ import { a as IMessageRpcRequestError, d as rememberIMessageReplyCache, g as chatContextFromIMessageTarget, n as sanitizeIMessageFinalOutboundText, o as createIMessageRpcClient, s as runIMessageCliJsonCommand, t as protectIMessageFencedRoleMarkers, y as resolveIMessageDirectChatService } from "./sanitize-outbound-Bvo4g1Mp.js";
4
+ import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-Cp8SDG4G.js";
5
5
  import { n as getOptionalIMessageRuntime, t as getIMessageRuntime } from "./runtime-Cza4CY5T.js";
6
6
  import { c as IMESSAGE_SENT_ECHOES_TTL_MS, d as resolveIMessageEchoMediaKey, p as resolveIMessageSentEchoEntryKey, s as IMESSAGE_SENT_ECHOES_NAMESPACE } from "./state-contract-DvahEY4X.js";
7
- import { d as normalizeConversationKey, f as normalizeIMessageGuid, i as registerIMessageApprovalReactionTarget, l as enumerateApprovalTargetKeys, s as buildIMessageApprovalConversationKeyForInbound, u as enumerateConversationKeyForms } from "./approval-reactions-DcLRPx7O.js";
8
- import { i as runIMessageCliJsonCommand, r as resolveAuthorizedIMessageReplyReference, t as withIMessageRemoteFile } from "./remote-file-COTN7196.js";
7
+ import { d as normalizeConversationKey, i as registerIMessageApprovalReactionTarget, l as enumerateApprovalTargetKeys, s as buildIMessageApprovalConversationKeyForInbound, u as enumerateConversationKeyForms } from "./approval-reactions-sVpDno7d.js";
8
+ import { n as normalizeIMessageGuid } from "./reaction-context-Br-vAJFp.js";
9
+ import { r as resolveAuthorizedIMessageReplyReference, t as withIMessageRemoteFile } from "./remote-file-Biz5PjXi.js";
9
10
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
10
11
  import { createLazyRuntimeSurface } from "openclaw/plugin-sdk/lazy-runtime";
11
12
  import { accessSync, constants } from "node:fs";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a json pointer
3
- * @specification
4
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
+ * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsJsonPointer(value: string): boolean;
@@ -1,8 +1,8 @@
1
1
  const JsonPointer = /^(?:\/(?:[^~/]|~0|~1)*)*$/;
2
2
  /**
3
3
  * Returns true if the value is a json pointer
4
- * @specification
5
- * @source ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
+ * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsJsonPointer(value) {
8
8
  return JsonPointer.test(value);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a json pointer uri fragment
3
- * @specification
4
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
+ * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsJsonPointerUriFragment(value: string): boolean;
@@ -1,8 +1,8 @@
1
1
  const JsonPointerUriFragment = /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i;
2
2
  /**
3
3
  * Returns true if the value is a json pointer uri fragment
4
- * @specification
5
- * @source ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
+ * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsJsonPointerUriFragment(value) {
8
8
  return JsonPointerUriFragment.test(value);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a relative json pointer
3
- * @specification
4
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
+ * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsRelativeJsonPointer(value: string): boolean;
@@ -1,8 +1,8 @@
1
1
  const RelativeJsonPointer = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;
2
2
  /**
3
3
  * Returns true if the value is a relative json pointer
4
- * @specification
5
- * @source ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
+ * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsRelativeJsonPointer(value) {
8
8
  return RelativeJsonPointer.test(value);
@@ -1,11 +1,12 @@
1
1
  // deno-lint-ignore-file ban-types no-explicit-any
2
2
  // deno-fmt-ignore-file
3
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
4
5
  /**
5
6
  * Performs an Object assign using the Left and Right object types. We track this operation as it
6
7
  * creates a new GC handle per assignment.
7
8
  */
8
9
  export function Assign(left, right) {
9
10
  Metrics.assign += 1;
10
- return { ...left, ...right };
11
+ return Freeze({ ...left, ...right });
11
12
  }
@@ -1,7 +1,7 @@
1
1
  // deno-lint-ignore-file no-explicit-any
2
- // deno-fmt-ignore-file
3
2
  import { Settings } from '../settings/index.mjs';
4
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
5
5
  function MergeHidden(left, right) {
6
6
  for (const key of Object.keys(right)) {
7
7
  Object.defineProperty(left, key, {
@@ -23,8 +23,7 @@ function Merge(left, right) {
23
23
  */
24
24
  export function Create(hidden, enumerable, options = {}) {
25
25
  Metrics.create += 1;
26
- const settings = Settings.Get();
27
26
  const withOptions = Merge(enumerable, options);
28
- const withHidden = settings.enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
29
- return settings.immutableTypes ? Object.freeze(withHidden) : withHidden;
27
+ const withHidden = Settings.Get().enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
28
+ return Freeze(withHidden);
30
29
  }
@@ -1,7 +1,7 @@
1
1
  // deno-lint-ignore-file no-explicit-any
2
- // deno-fmt-ignore-file
3
2
  import { Guard } from '../../guard/index.mjs';
4
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
5
5
  import { Clone } from './clone.mjs';
6
6
  /** Discards multiple property keys from the given object value */
7
7
  export function Discard(value, propertyKeys) {
@@ -14,5 +14,5 @@ export function Discard(value, propertyKeys) {
14
14
  descriptor.value = Clone(descriptor.value);
15
15
  Object.defineProperty(result, key, descriptor);
16
16
  }
17
- return result;
17
+ return Freeze(result);
18
18
  }
@@ -0,0 +1,4 @@
1
+ type ObjectLike = Record<PropertyKey, any>;
2
+ /** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
3
+ export declare function Freeze(value: ObjectLike): ObjectLike;
4
+ export {};
@@ -0,0 +1,6 @@
1
+ // deno-lint-ignore-file no-explicit-any
2
+ import { Settings } from '../settings/index.mjs';
3
+ /** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
4
+ export function Freeze(value) {
5
+ return Settings.Get().immutableTypes ? Object.freeze(value) : value;
6
+ }
@@ -1,6 +1,7 @@
1
- // deno-fmt-ignore-file
1
+ // deno-lint-ignore-file no-explicit-any
2
2
  import { Settings } from '../settings/index.mjs';
3
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
4
5
  import { Clone } from './clone.mjs';
5
6
  /**
6
7
  * Updates a value with new properties while preserving property enumerability. Use this function to modify
@@ -28,5 +29,5 @@ export function Update(current, hidden, enumerable) {
28
29
  value: enumerable[key]
29
30
  });
30
31
  }
31
- return result;
32
+ return Freeze(result);
32
33
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.3.17",
4
+ "version": "1.3.18",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "id": "imessage",
3
+ "name": "iMessage",
4
+ "description": "OpenClaw iMessage channel plugin using imsg on a signed-in Mac.",
3
5
  "doctorContract": {
4
6
  "configRepair": true,
5
7
  "stateMigrations": true
6
8
  },
7
- "icon": "https://cdn.simpleicons.org/imessage",
8
9
  "activation": {
9
10
  "onStartup": false
10
11
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/imessage",
3
- "version": "2026.9.1",
3
+ "version": "2026.9.2",
4
4
  "description": "OpenClaw iMessage channel plugin using imsg on a signed-in Mac",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,11 +8,11 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "typebox": "1.3.17",
11
+ "typebox": "1.3.18",
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.9.1"
15
+ "openclaw": ">=2026.9.2"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
@@ -92,10 +92,10 @@
92
92
  "allowInvalidConfigRecovery": true
93
93
  },
94
94
  "compat": {
95
- "pluginApi": ">=2026.9.1"
95
+ "pluginApi": ">=2026.9.2"
96
96
  },
97
97
  "build": {
98
- "openclawVersion": "2026.9.1",
98
+ "openclawVersion": "2026.9.2",
99
99
  "bundledDist": false
100
100
  },
101
101
  "release": {