


























@@ -17,9 +17,11 @@ import {
1717type ChannelMessageActionAdapter,
1818type ChannelMessageActionName,
1919} from "./actions-api.js";
20+import type { BlueBubblesChatContext } from "./monitor-reply-cache.js";
2021import { getCachedBlueBubblesPrivateApiStatus, isMacOS26OrHigher } from "./probe.js";
2122import { normalizeSecretInputString } from "./secret-input.js";
2223import {
24+buildBlueBubblesChatContextFromTarget,
2325normalizeBlueBubblesHandle,
2426normalizeBlueBubblesMessagingTarget,
2527parseBlueBubblesTarget,
@@ -51,6 +53,32 @@ function mapTarget(raw: string): BlueBubblesSendTarget {
5153};
5254}
535556+/**
57+ * Collect any chat-identifying hints the action caller supplied, so short
58+ * message id resolution can reject cross-chat collisions. The order of
59+ * precedence mirrors resolveChatGuid: explicit chat* params first, then the
60+ * `to`/`target` param, then the current session channel as a last resort.
61+ */
62+function buildChatContextFromActionParams(params: {
63+actionParams: Record<string, unknown>;
64+currentChannelId?: string;
65+}): BlueBubblesChatContext {
66+const explicitChatGuid = readStringParam(params.actionParams, "chatGuid")?.trim();
67+const explicitChatIdentifier = readStringParam(params.actionParams, "chatIdentifier")?.trim();
68+const explicitChatId = readNumberParam(params.actionParams, "chatId", { integer: true });
69+const rawTarget =
70+readStringParam(params.actionParams, "to") ??
71+readStringParam(params.actionParams, "target") ??
72+params.currentChannelId ??
73+undefined;
74+const targetContext = buildBlueBubblesChatContextFromTarget(rawTarget);
75+return {
76+chatGuid: explicitChatGuid || targetContext.chatGuid,
77+chatIdentifier: explicitChatIdentifier || targetContext.chatIdentifier,
78+chatId: typeof explicitChatId === "number" ? explicitChatId : targetContext.chatId,
79+};
80+}
81+5482function readMessageText(params: Record<string, unknown>): string | undefined {
5583return readStringParam(params, "text") ?? readStringParam(params, "message");
5684}
@@ -201,9 +229,15 @@ export const bluebubblesMessageActions: ChannelMessageActionAdapter = {
201229"Use action=react with messageId=<message_id>, emoji=<emoji>, and to/chatGuid to identify the chat.",
202230);
203231}
204-// Resolve short ID (e.g., "1", "2") to full UUID
232+// Resolve short ID (e.g., "1", "2") to full UUID, scoped to the chat the
233+// caller is acting on so a short ID from a different chat cannot be
234+// silently accepted (see cross-chat guard in resolveBlueBubblesMessageId).
205235const messageId = runtime.resolveBlueBubblesMessageId(rawMessageId, {
206236requireKnownShortId: true,
237+chatContext: buildChatContextFromActionParams({
238+actionParams: params,
239+currentChannelId: toolContext?.currentChannelId,
240+}),
207241});
208242const partIndex = readNumberParam(params, "partIndex", { integer: true });
209243const resolvedChatGuid = await resolveChatGuid();
@@ -248,9 +282,14 @@ export const bluebubblesMessageActions: ChannelMessageActionAdapter = {
248282`Use action=edit with messageId=<message_id>, text=<new_content>.`,
249283);
250284}
251-// Resolve short ID (e.g., "1", "2") to full UUID
285+// Resolve short ID (e.g., "1", "2") to full UUID, scoped to the chat
286+// the caller is acting on (cross-chat guard).
252287const messageId = runtime.resolveBlueBubblesMessageId(rawMessageId, {
253288requireKnownShortId: true,
289+chatContext: buildChatContextFromActionParams({
290+actionParams: params,
291+currentChannelId: toolContext?.currentChannelId,
292+}),
254293});
255294const partIndex = readNumberParam(params, "partIndex", { integer: true });
256295const backwardsCompatMessage = readStringParam(params, "backwardsCompatMessage");
@@ -274,9 +313,14 @@ export const bluebubblesMessageActions: ChannelMessageActionAdapter = {
274313"Use action=unsend with messageId=<message_id>.",
275314);
276315}
277-// Resolve short ID (e.g., "1", "2") to full UUID
316+// Resolve short ID (e.g., "1", "2") to full UUID, scoped to the chat
317+// the caller is acting on (cross-chat guard).
278318const messageId = runtime.resolveBlueBubblesMessageId(rawMessageId, {
279319requireKnownShortId: true,
320+chatContext: buildChatContextFromActionParams({
321+actionParams: params,
322+currentChannelId: toolContext?.currentChannelId,
323+}),
280324});
281325const partIndex = readNumberParam(params, "partIndex", { integer: true });
282326@@ -310,9 +354,14 @@ export const bluebubblesMessageActions: ChannelMessageActionAdapter = {
310354`Use action=reply with messageId=<message_id>, message=<your reply>, target=<chat_target>.`,
311355);
312356}
313-// Resolve short ID (e.g., "1", "2") to full UUID
357+// Resolve short ID (e.g., "1", "2") to full UUID, scoped to the chat
358+// the caller is acting on (cross-chat guard).
314359const messageId = runtime.resolveBlueBubblesMessageId(rawMessageId, {
315360requireKnownShortId: true,
361+chatContext: buildChatContextFromActionParams({
362+actionParams: params,
363+currentChannelId: toolContext?.currentChannelId,
364+}),
316365});
317366const partIndex = readNumberParam(params, "partIndex", { integer: true });
318367此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。