@openclaw/imessage 2026.9.1 → 2026.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{actions.runtime-DCjNT81u.js → actions.runtime-CzvR20qT.js} +2 -2
- package/dist/api.js +3 -3
- package/dist/{approval-handler.runtime-BReeID1z.js → approval-handler.runtime-B6JGnxQf.js} +5 -5
- package/dist/{approval-reactions-DcLRPx7O.js → approval-reactions-BM_AwHPq.js} +46 -85
- package/dist/{channel-zDmMTHWD.js → channel-B6qtBfCj.js} +21 -14
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-qQBHCle8.js → channel.runtime-C2lcFXWn.js} +4 -8
- package/dist/{config-schema-DuGbA8Kp.js → config-schema-CCbTcJEV.js} +10 -37
- package/dist/{group-policy-BWqG2esy.js → group-policy-Duro87b4.js} +2 -2
- package/dist/{monitor-AmSj6QIH.js → monitor-Dj3TAimI.js} +41 -43
- package/dist/{question-reactions-viP7ZcyG.js → question-reactions-9tBYB1_F.js} +4 -7
- package/dist/{reaction-context-BAYI7pz0.js → reaction-context-Br-vAJFp.js} +9 -3
- package/dist/{remote-file-COTN7196.js → remote-file-5n5LznCa.js} +3 -52
- package/dist/runtime-api.js +5 -5
- package/dist/{sanitize-outbound-CN3Hxbjy.js → sanitize-outbound-C6UF2cvr.js} +124 -51
- package/dist/{send-v0blZfaI.js → send-CIHiLtcY.js} +5 -4
- package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
- package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
- package/node_modules/typebox/build/system/memory/create.mjs +3 -4
- package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
- package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
- package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
- package/node_modules/typebox/build/system/memory/update.mjs +3 -2
- package/node_modules/typebox/package.json +1 -1
- package/openclaw.plugin.json +7 -2
- package/package.json +5 -5
|
@@ -1,15 +1,15 @@
|
|
|
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 {
|
|
4
|
-
import { f as probeIMessage, r as resolveIMessageInboundConversationId } from "./group-policy-
|
|
3
|
+
import { d as rememberIMessageReplyCache, o as createIMessageRpcClient, r as sanitizeOutboundText, u as isKnownFromMeIMessageMessageId, y as resolveIMessageDirectChatService } from "./sanitize-outbound-C6UF2cvr.js";
|
|
4
|
+
import { f as probeIMessage, r as resolveIMessageInboundConversationId } from "./group-policy-Duro87b4.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-
|
|
9
|
-
import { c as iMessageApprovalControlBindings, n as hasPersistedIMessageEcho, r as stripLeadingEchoTextCorruptionMarkers, s as maybeResolveIMessageApprovalPollVote, t as sendMessageIMessage } from "./send-
|
|
10
|
-
import { t as resolveIMessageReactionContext } from "./reaction-context-
|
|
11
|
-
import { n as maybeResolveIMessageQuestionReaction, t as hasIMessageQuestionReactionTarget } from "./question-reactions-
|
|
12
|
-
import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline,
|
|
8
|
+
import { i as registerIMessageApprovalReactionTarget, n as handleIMessageApprovalReaction, o as listPendingIMessageApprovalReactionPollTargets, r as maybeResolveIMessageApprovalReaction, s as buildIMessageApprovalConversationKeyForInbound } from "./approval-reactions-BM_AwHPq.js";
|
|
9
|
+
import { c as iMessageApprovalControlBindings, n as hasPersistedIMessageEcho, r as stripLeadingEchoTextCorruptionMarkers, s as maybeResolveIMessageApprovalPollVote, t as sendMessageIMessage } from "./send-CIHiLtcY.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
|
+
import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, 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";
|
|
15
15
|
import path from "node:path";
|
|
@@ -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, createAcceptedChannelDeliveryResult, 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,
|
|
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(
|
|
170
|
+
const target = pendingByMessageId.get(targetGuid) ?? pendingByMessageId.get(normalizeIMessageGuid(targetGuid));
|
|
174
171
|
if (!target) continue;
|
|
175
172
|
bindObservedConversation({
|
|
176
173
|
target,
|
|
@@ -994,32 +991,24 @@ async function deliverIMessageReply(params) {
|
|
|
994
991
|
} catch (error) {
|
|
995
992
|
const partial = isChannelPartialDeliveryError(error) ? error.deliveryResult : void 0;
|
|
996
993
|
if (accepted.length === 0 && partial?.visibleReplySent !== true) throw error;
|
|
997
|
-
|
|
998
|
-
results:
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
throw createChannelPartialDeliveryError(error, {
|
|
1002
|
-
messageIds: listMessageReceiptPlatformIds(receipt),
|
|
1003
|
-
receipt,
|
|
1004
|
-
visibleReplySent: true,
|
|
994
|
+
throw createChannelPartialDeliveryError(error, createAcceptedChannelDeliveryResult({
|
|
995
|
+
results: accepted.map((result) => ({ receipt: result.receipt })),
|
|
996
|
+
deliveryResults: partial ? [partial] : [],
|
|
997
|
+
kind: reply.mediaUrls.length > 0 ? "media" : "text",
|
|
1005
998
|
content: [...accepted.map((result) => result.sentText), partial?.content].filter(Boolean).join("\n")
|
|
1006
|
-
});
|
|
999
|
+
}));
|
|
1007
1000
|
}
|
|
1008
1001
|
if (delivered === "empty") return {
|
|
1009
1002
|
visibleReplySent: false,
|
|
1010
1003
|
suppression: { reason: "no_visible_result" }
|
|
1011
1004
|
};
|
|
1012
|
-
const
|
|
1005
|
+
const deliveryResult = createAcceptedChannelDeliveryResult({
|
|
1013
1006
|
results: accepted.map((result) => ({ receipt: result.receipt })),
|
|
1014
|
-
kind: delivered
|
|
1007
|
+
kind: delivered,
|
|
1008
|
+
content: accepted.map((result) => result.sentText).filter(Boolean).join("\n")
|
|
1015
1009
|
});
|
|
1016
1010
|
runtime.log?.(`imessage: delivered reply to ${target}`);
|
|
1017
|
-
return
|
|
1018
|
-
messageIds: listMessageReceiptPlatformIds(receipt),
|
|
1019
|
-
receipt,
|
|
1020
|
-
visibleReplySent: true,
|
|
1021
|
-
content: accepted.map((result) => result.sentText).filter(Boolean).join("\n")
|
|
1022
|
-
};
|
|
1011
|
+
return deliveryResult;
|
|
1023
1012
|
}
|
|
1024
1013
|
function createIMessageEchoCachingSend(params) {
|
|
1025
1014
|
return async (target, text, opts) => {
|
|
@@ -2799,17 +2788,16 @@ const IMESSAGE_DIAGNOSTIC_DROP_REASONS = /* @__PURE__ */ new Set([
|
|
|
2799
2788
|
"agent echo in self-chat",
|
|
2800
2789
|
"echo",
|
|
2801
2790
|
"from me",
|
|
2791
|
+
"no mention",
|
|
2802
2792
|
"reflected assistant content",
|
|
2803
2793
|
"self-chat echo"
|
|
2804
2794
|
]);
|
|
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
|
-
}
|
|
2795
|
+
const IMESSAGE_THROTTLED_DIAGNOSTIC_DROP_REASONS = /* @__PURE__ */ new Set(["from me", "no mention"]);
|
|
2809
2796
|
function describeIMessageInboundDropDiagnostic(params) {
|
|
2810
2797
|
if (!IMESSAGE_DIAGNOSTIC_DROP_REASONS.has(params.reason)) return null;
|
|
2811
2798
|
const messageId = typeof params.message.id === "number" || typeof params.message.id === "string" ? String(params.message.id) : "unknown";
|
|
2812
|
-
|
|
2799
|
+
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.` : "";
|
|
2800
|
+
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
2801
|
}
|
|
2814
2802
|
function describeIMessageWatchSubscribeStartupFailure(params) {
|
|
2815
2803
|
const retry = params.retryDelayMs !== void 0 ? ` retry_in_ms=${params.retryDelayMs}` : "";
|
|
@@ -2833,10 +2821,17 @@ async function waitForWatchSubscribeRetryDelay(params) {
|
|
|
2833
2821
|
async function monitorIMessageProvider(opts = {}) {
|
|
2834
2822
|
const runtime = resolveRuntime(opts);
|
|
2835
2823
|
const cfg = opts.config ?? getRuntimeConfig();
|
|
2824
|
+
const readConfig = createRuntimeConfigReader(cfg);
|
|
2836
2825
|
const accountInfo = resolveIMessageAccount({
|
|
2837
2826
|
cfg,
|
|
2838
2827
|
accountId: opts.accountId
|
|
2839
2828
|
});
|
|
2829
|
+
const groupsConfigPath = resolveChannelGroupsConfigPath({
|
|
2830
|
+
cfg,
|
|
2831
|
+
channel: "imessage",
|
|
2832
|
+
accountId: accountInfo.accountId,
|
|
2833
|
+
groups: resolveChannelGroups(cfg, "imessage", accountInfo.accountId)
|
|
2834
|
+
});
|
|
2840
2835
|
const approvalGatewayRuntime = opts.channelRuntime?.runtimeContexts.get({
|
|
2841
2836
|
channelId: "imessage",
|
|
2842
2837
|
accountId: accountInfo.accountId,
|
|
@@ -2941,6 +2936,10 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
2941
2936
|
const { debouncer: inboundDebouncer } = createChannelInboundDebouncer({
|
|
2942
2937
|
cfg,
|
|
2943
2938
|
channel: "imessage",
|
|
2939
|
+
resolveDebounceMs: () => resolveInboundDebounceMs({
|
|
2940
|
+
cfg: readConfig(),
|
|
2941
|
+
channel: "imessage"
|
|
2942
|
+
}),
|
|
2944
2943
|
buildKey: (entry) => {
|
|
2945
2944
|
const msg = entry.message;
|
|
2946
2945
|
const sender = msg.sender?.trim();
|
|
@@ -3041,9 +3040,6 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3041
3040
|
runtime.error?.(`imessage catchup: failed to advance pending live cursor: ${String(err)}`);
|
|
3042
3041
|
}
|
|
3043
3042
|
}
|
|
3044
|
-
async function handleMessageNow(message, ingressLifecycle) {
|
|
3045
|
-
await handleMessageNowInner(message, ingressLifecycle);
|
|
3046
|
-
}
|
|
3047
3043
|
const pollCommentFolder = createPollCommentFolder();
|
|
3048
3044
|
function resolveIMessageInboundBodyText(message) {
|
|
3049
3045
|
const messageText = ((message.poll ? renderIMessagePollBody(message.poll, message.sender, { preferOptionId: Boolean(remoteHost) }) : null) ?? message.text ?? "").trim();
|
|
@@ -3060,7 +3056,7 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3060
3056
|
effectiveAttachmentRoots
|
|
3061
3057
|
};
|
|
3062
3058
|
}
|
|
3063
|
-
async function
|
|
3059
|
+
async function handleMessageNow(rawMessage, ingressLifecycle) {
|
|
3064
3060
|
const message = await repairMessageConversationAnchor(rawMessage);
|
|
3065
3061
|
if (!message) return;
|
|
3066
3062
|
const pollFoldAtMs = message.created_at ? Date.parse(message.created_at) : NaN;
|
|
@@ -3105,12 +3101,13 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3105
3101
|
if (decision.reason === "echo" || decision.reason === "reflected assistant content") loopRateLimiter.record(rateLimitKey);
|
|
3106
3102
|
const diagnostic = describeIMessageInboundDropDiagnostic({
|
|
3107
3103
|
accountId: accountInfo.accountId,
|
|
3104
|
+
groupsConfigPath,
|
|
3108
3105
|
reason: decision.reason,
|
|
3109
3106
|
message
|
|
3110
3107
|
});
|
|
3111
3108
|
if (diagnostic) {
|
|
3112
3109
|
const throttleKey = `${rateLimitKey}:${decision.reason}`;
|
|
3113
|
-
if (!
|
|
3110
|
+
if (!IMESSAGE_THROTTLED_DIAGNOSTIC_DROP_REASONS.has(decision.reason) || !loggedThrottledDropDiagnostics.check(throttleKey)) runtime.log?.(warn(diagnostic));
|
|
3114
3111
|
}
|
|
3115
3112
|
if (decision.reason === "group id not in allowlist") warnGroupAllowlistDropPerChatOnce({
|
|
3116
3113
|
accountId: accountInfo.accountId,
|
|
@@ -3411,6 +3408,7 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3411
3408
|
let directTypingController;
|
|
3412
3409
|
const directToolTypingOptions = shouldUseDirectToolTypingOptions ? {
|
|
3413
3410
|
suppressDefaultToolProgressMessages: true,
|
|
3411
|
+
allowToolLifecycleWhenProgressHidden: true,
|
|
3414
3412
|
allowProgressCallbacksWhenSourceDeliverySuppressed: true,
|
|
3415
3413
|
onTypingController: (typing) => {
|
|
3416
3414
|
directTypingController = typing;
|
|
@@ -3539,7 +3537,7 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3539
3537
|
const repairedMessage = await repairMessageConversationAnchor(message);
|
|
3540
3538
|
if (!repairedMessage) return { kind: "completed" };
|
|
3541
3539
|
if (isApprovalCommand) {
|
|
3542
|
-
await
|
|
3540
|
+
await handleMessageNow(repairedMessage);
|
|
3543
3541
|
return { kind: "completed" };
|
|
3544
3542
|
}
|
|
3545
3543
|
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-
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
2
|
-
import {
|
|
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-C6UF2cvr.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 {
|
|
245
|
+
export { authorizeIMessageResourceReference as n, resolveAuthorizedIMessageReplyReference as r, withIMessageRemoteFile as t };
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
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-
|
|
2
|
+
import { c as normalizeIMessageMessagingTarget, d as imessageMessageActions, f as probeIMessage, n as resolveIMessageGroupToolPolicy, s as looksLikeIMessageTargetId, t as resolveIMessageGroupRequireMention } from "./group-policy-Duro87b4.js";
|
|
3
3
|
import { r as setIMessageRuntime } from "./runtime-Cza4CY5T.js";
|
|
4
|
-
import { n as IMessageConfigSchema } from "./config-schema-
|
|
5
|
-
import { t as sendMessageIMessage } from "./send-
|
|
6
|
-
import { t as monitorIMessageProvider } from "./monitor-
|
|
4
|
+
import { n as IMessageConfigSchema } from "./config-schema-CCbTcJEV.js";
|
|
5
|
+
import { t as sendMessageIMessage } from "./send-CIHiLtcY.js";
|
|
6
|
+
import { t as monitorIMessageProvider } from "./monitor-Dj3TAimI.js";
|
|
7
7
|
import { formatTrimmedAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
8
|
+
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
|
8
9
|
import { buildComputedAccountStatusSnapshot, collectStatusIssuesFromLastError } from "openclaw/plugin-sdk/status-helpers";
|
|
9
10
|
import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
|
|
10
11
|
import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
|
|
11
12
|
import { DEFAULT_ACCOUNT_ID, getChatChannelMeta } from "openclaw/plugin-sdk/core";
|
|
12
13
|
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
13
|
-
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
|
14
14
|
//#region extensions/imessage/src/config-accessors.ts
|
|
15
15
|
function resolveIMessageConfigAllowFrom(params) {
|
|
16
16
|
return (resolveIMessageAccount(params).config.allowFrom ?? []).map((entry) => String(entry));
|
|
@@ -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) {
|
|
@@ -378,6 +450,29 @@ function normalizeIMessageFullDiskAccessError(message) {
|
|
|
378
450
|
if (!normalized.includes("full disk access") || !normalized.includes("chat.db")) return;
|
|
379
451
|
return PUBLIC_IMESSAGE_FULL_DISK_ACCESS_ERROR;
|
|
380
452
|
}
|
|
453
|
+
function createLfLineFramer(onLine) {
|
|
454
|
+
const decoder = new StringDecoder("utf8");
|
|
455
|
+
let buffer = "";
|
|
456
|
+
return {
|
|
457
|
+
write(chunk) {
|
|
458
|
+
buffer += typeof chunk === "string" ? chunk : decoder.write(chunk);
|
|
459
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
460
|
+
while (newlineIndex !== -1) {
|
|
461
|
+
const line = buffer.slice(0, newlineIndex);
|
|
462
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
463
|
+
onLine(line);
|
|
464
|
+
newlineIndex = buffer.indexOf("\n");
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
flush() {
|
|
468
|
+
buffer += decoder.end();
|
|
469
|
+
if (!buffer) return;
|
|
470
|
+
const line = buffer;
|
|
471
|
+
buffer = "";
|
|
472
|
+
onLine(line);
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
}
|
|
381
476
|
var IMessageRpcClient = class {
|
|
382
477
|
constructor(opts = {}) {
|
|
383
478
|
this.pending = /* @__PURE__ */ new Map();
|
|
@@ -386,10 +481,8 @@ var IMessageRpcClient = class {
|
|
|
386
481
|
this.isReaped = false;
|
|
387
482
|
this.child = null;
|
|
388
483
|
this.stopPromise = null;
|
|
389
|
-
this.
|
|
390
|
-
this.
|
|
391
|
-
this.stderrBuffer = "";
|
|
392
|
-
this.stderrDecoder = new StringDecoder("utf8");
|
|
484
|
+
this.stdoutFramer = createLfLineFramer((line) => this.handleStdoutLine(line));
|
|
485
|
+
this.stderrFramer = createLfLineFramer((line) => this.handleStderrLine(line));
|
|
393
486
|
this.nextId = 1;
|
|
394
487
|
this.publicProcessError = null;
|
|
395
488
|
this.configuredCliPath = opts.cliPath?.trim() || "imsg";
|
|
@@ -418,21 +511,29 @@ var IMessageRpcClient = class {
|
|
|
418
511
|
this.child = child;
|
|
419
512
|
child.stdout.on("data", (chunk) => {
|
|
420
513
|
if (this.child !== child) return;
|
|
421
|
-
this.
|
|
514
|
+
this.stdoutFramer.write(chunk);
|
|
422
515
|
});
|
|
423
516
|
child.stderr?.on("data", (chunk) => {
|
|
424
517
|
if (this.child !== child) return;
|
|
425
|
-
this.
|
|
518
|
+
this.stderrFramer.write(chunk);
|
|
426
519
|
});
|
|
427
520
|
const failFromProcessError = (err) => this.failTransport(err, child);
|
|
428
521
|
child.on("error", failFromProcessError);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
522
|
+
for (const stream of [
|
|
523
|
+
child.stdin,
|
|
524
|
+
child.stdout,
|
|
525
|
+
child.stderr
|
|
526
|
+
]) {
|
|
527
|
+
stream.on("error", failFromProcessError);
|
|
528
|
+
stream.once("close", () => {
|
|
529
|
+
const error = stream.errored;
|
|
530
|
+
if (error) failFromProcessError(error);
|
|
531
|
+
});
|
|
532
|
+
}
|
|
432
533
|
child.on("close", (code, signal) => {
|
|
433
534
|
if (this.child === child) {
|
|
434
|
-
this.
|
|
435
|
-
this.
|
|
535
|
+
this.stdoutFramer.flush();
|
|
536
|
+
this.stderrFramer.flush();
|
|
436
537
|
this.child = null;
|
|
437
538
|
}
|
|
438
539
|
this.finish(this.buildCloseError(code, signal));
|
|
@@ -483,6 +584,11 @@ var IMessageRpcClient = class {
|
|
|
483
584
|
} catch (err) {
|
|
484
585
|
if (isIMessageBridgeStall(err)) {
|
|
485
586
|
invalidateCachedIMessagePrivateApiStatus(this.configuredCliPath);
|
|
587
|
+
try {
|
|
588
|
+
await recoverIMessageBridge(this.configuredCliPath);
|
|
589
|
+
} catch (recoveryError) {
|
|
590
|
+
this.runtime?.error?.(`imessage: automatic bridge recovery failed: ${formatErrorMessage(recoveryError)}`);
|
|
591
|
+
}
|
|
486
592
|
throw describeIMessageBridgeStall(err);
|
|
487
593
|
}
|
|
488
594
|
throw err;
|
|
@@ -520,48 +626,11 @@ var IMessageRpcClient = class {
|
|
|
520
626
|
if (!this.finish(err instanceof Error ? err : new Error(String(err)))) return;
|
|
521
627
|
if (child) this.signalChild(child, "SIGTERM");
|
|
522
628
|
}
|
|
523
|
-
handleStdoutChunk(chunk) {
|
|
524
|
-
const text = typeof chunk === "string" ? chunk : this.stdoutDecoder.write(chunk);
|
|
525
|
-
this.stdoutBuffer += text;
|
|
526
|
-
let newlineIndex = this.stdoutBuffer.indexOf("\n");
|
|
527
|
-
while (newlineIndex !== -1) {
|
|
528
|
-
const line = this.stdoutBuffer.slice(0, newlineIndex);
|
|
529
|
-
this.stdoutBuffer = this.stdoutBuffer.slice(newlineIndex + 1);
|
|
530
|
-
this.handleStdoutLine(line);
|
|
531
|
-
newlineIndex = this.stdoutBuffer.indexOf("\n");
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
flushStdoutBuffer() {
|
|
535
|
-
const tail = this.stdoutDecoder.end();
|
|
536
|
-
if (tail) this.stdoutBuffer += tail;
|
|
537
|
-
if (!this.stdoutBuffer) return;
|
|
538
|
-
const line = this.stdoutBuffer;
|
|
539
|
-
this.stdoutBuffer = "";
|
|
540
|
-
this.handleStdoutLine(line);
|
|
541
|
-
}
|
|
542
629
|
handleStdoutLine(line) {
|
|
543
630
|
const trimmed = line.trim();
|
|
544
631
|
if (!trimmed) return;
|
|
545
632
|
this.handleLine(trimmed);
|
|
546
633
|
}
|
|
547
|
-
handleStderrChunk(chunk) {
|
|
548
|
-
const text = typeof chunk === "string" ? chunk : this.stderrDecoder.write(chunk);
|
|
549
|
-
this.stderrBuffer += text;
|
|
550
|
-
let newlineIndex = this.stderrBuffer.indexOf("\n");
|
|
551
|
-
while (newlineIndex !== -1) {
|
|
552
|
-
const line = this.stderrBuffer.slice(0, newlineIndex);
|
|
553
|
-
this.stderrBuffer = this.stderrBuffer.slice(newlineIndex + 1);
|
|
554
|
-
this.handleStderrLine(line);
|
|
555
|
-
newlineIndex = this.stderrBuffer.indexOf("\n");
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
flushStderrBuffer() {
|
|
559
|
-
this.stderrBuffer += this.stderrDecoder.end();
|
|
560
|
-
if (!this.stderrBuffer) return;
|
|
561
|
-
const line = this.stderrBuffer;
|
|
562
|
-
this.stderrBuffer = "";
|
|
563
|
-
this.handleStderrLine(line);
|
|
564
|
-
}
|
|
565
634
|
handleStderrLine(line) {
|
|
566
635
|
const trimmed = line.trim();
|
|
567
636
|
if (!trimmed) return;
|
|
@@ -687,6 +756,10 @@ function codeDelimiter(content) {
|
|
|
687
756
|
return "`".repeat(longestRun + 1);
|
|
688
757
|
}
|
|
689
758
|
function restoreCodeMarkers(text, ranges, codeRanges) {
|
|
759
|
+
if (codeRanges.length === 0) return {
|
|
760
|
+
text,
|
|
761
|
+
ranges
|
|
762
|
+
};
|
|
690
763
|
let rendered = "";
|
|
691
764
|
let cursor = 0;
|
|
692
765
|
const edits = codeRanges.map((range) => {
|
|
@@ -735,12 +808,12 @@ function extractMarkdownFormatRuns(input) {
|
|
|
735
808
|
preserveSourceBlockSpacing: true
|
|
736
809
|
});
|
|
737
810
|
const rendered = renderMarkdownWithAttributedRanges(ir, { styleMap: IMESSAGE_STYLE_MAP }, IMESSAGE_FORMAT_PROFILE);
|
|
738
|
-
const
|
|
811
|
+
const codeRanges = ir.styles.some((span) => span.style === "code") ? renderMarkdownWithAttributedRanges(ir, { styleMap: { code: "code" } }, IMESSAGE_CODE_PROFILE).ranges : [];
|
|
739
812
|
return restoreCodeMarkers(rendered.text, rendered.ranges.map(({ start, length, style }) => ({
|
|
740
813
|
start,
|
|
741
814
|
length,
|
|
742
815
|
styles: [style]
|
|
743
|
-
})),
|
|
816
|
+
})), codeRanges);
|
|
744
817
|
}
|
|
745
818
|
//#endregion
|
|
746
819
|
//#region extensions/imessage/src/monitor/sanitize-outbound.ts
|
|
@@ -1204,4 +1277,4 @@ function sanitizeOutboundText(text) {
|
|
|
1204
1277
|
return cleaned;
|
|
1205
1278
|
}
|
|
1206
1279
|
//#endregion
|
|
1207
|
-
export {
|
|
1280
|
+
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,
|
|
4
|
-
import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-
|
|
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-C6UF2cvr.js";
|
|
4
|
+
import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-Duro87b4.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,
|
|
8
|
-
import {
|
|
7
|
+
import { d as normalizeConversationKey, i as registerIMessageApprovalReactionTarget, l as enumerateApprovalTargetKeys, s as buildIMessageApprovalConversationKeyForInbound, u as enumerateConversationKeyForms } from "./approval-reactions-BM_AwHPq.js";
|
|
8
|
+
import { n as normalizeIMessageGuid } from "./reaction-context-Br-vAJFp.js";
|
|
9
|
+
import { r as resolveAuthorizedIMessageReplyReference, t as withIMessageRemoteFile } from "./remote-file-5n5LznCa.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";
|