@openclaw/imessage 2026.9.6 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{accounts-CUxZrTcY.mjs → accounts-nzcU0cq2.mjs} +3 -6
- package/dist/.setup/{actions.runtime-D0zG_96v.mjs → actions.runtime-DdBN29zj.mjs} +3 -5
- package/dist/.setup/{api-RZv6yXul.mjs → api-B9Qx21G-.mjs} +6 -5
- package/dist/.setup/{api-VLVcFh7r.mjs → api-D2S6FhGw.mjs} +7 -7
- package/dist/.setup/{approval-handler.runtime-Bv5_XgNr.mjs → approval-handler.runtime-DKSq0DWq.mjs} +8 -8
- package/dist/.setup/{approval-reactions-D6RFg6lU.mjs → approval-reactions-Bp33xc83.mjs} +5 -5
- package/dist/.setup/{channel-BLTaKdSK.mjs → channel-9fyvuN_p.mjs} +97 -152
- package/dist/.setup/channel.runtime-n-MPKL8k.mjs +92 -0
- package/dist/.setup/{config-schema-CCbTcJEV.mjs → config-schema-4Q3_EqYt.mjs} +9 -1
- package/dist/.setup/{group-policy-Cjztkquv.mjs → group-policy-90pw4tyG.mjs} +48 -334
- package/dist/.setup/{media-contract-DKJK7rh3.mjs → media-contract-CagwSMvo.mjs} +1 -1
- package/dist/.setup/{message-tool-api-pvlcOJPG.mjs → message-tool-api-D032l82H.mjs} +3 -18
- package/dist/.setup/{monitor-BJ3Ozi6I.mjs → monitor-fv9nRuTH.mjs} +211 -280
- package/dist/.setup/{question-reactions-lm8OxWbb.mjs → question-reactions-Cy-dmU_j.mjs} +1 -1
- package/dist/.setup/{remote-file-Bye99O-C.mjs → remote-file-DRPCaVmg.mjs} +70 -21
- package/dist/.setup/rolldown-runtime-BBjsoOtd.mjs +27 -0
- package/dist/.setup/{sanitize-outbound-sJPF2DVM.mjs → sanitize-outbound-3MLljgtY.mjs} +86 -24
- package/dist/.setup/{send-odAfTQ2J.mjs → send-Cu9nl757.mjs} +28 -112
- package/dist/.setup/setup-core-8MDdYHj5.mjs +226 -0
- package/dist/.setup/{channel.runtime---s2k4YN.mjs → setup-surface-tGXFDdWh.mjs} +6 -103
- package/dist/.setup/state-migrations-B-Q7bO0Y.mjs +47 -0
- package/dist/.setup/{targets-Cc9vthzI.mjs → targets-BicBiYsM.mjs} +10 -16
- package/dist/api.js +7 -7
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/contract-api.js +1 -1
- package/dist/doctor-contract-api.js +168 -7
- package/dist/media-contract-api.js +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/runtime-api.js +6 -6
- package/dist/setup-entry.js +1 -1
- package/dist/src/chat-db.worker.js +6 -1
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/openclaw.plugin.json +14 -0
- package/package.json +5 -5
- package/dist/.setup/rolldown-runtime-D7D4PA-g.mjs +0 -13
- package/dist/.setup/state-contract-DvahEY4X.mjs +0 -56
- package/dist/.setup/state-migrations-DIDzI99d.mjs +0 -277
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { o as normalizeIMessageHandle } from "./targets-BicBiYsM.mjs";
|
|
2
|
+
import { a as resolveDefaultIMessageAccountId, o as resolveIMessageAccount } from "./accounts-nzcU0cq2.mjs";
|
|
3
|
+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
+
import { parseAllowFromEntries } from "openclaw/plugin-sdk/allow-from";
|
|
5
|
+
import { createChannelDmPolicy } from "openclaw/plugin-sdk/channel-dm-policy";
|
|
6
|
+
import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
|
|
7
|
+
import { createCliPathTextInput, createDelegatedSetupWizardProxy, createDelegatedTextInputShouldPrompt, createPatchedAccountSetupAdapter, createSetupTranslator, promptParsedAllowFromForAccount, setAccountAllowFromForChannel, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup-runtime";
|
|
8
|
+
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
9
|
+
//#region extensions/imessage/src/setup-core.ts
|
|
10
|
+
const t = createSetupTranslator();
|
|
11
|
+
const channel = "imessage";
|
|
12
|
+
const IMESSAGE_INSTALL_COMMAND = "brew install steipete/tap/imsg";
|
|
13
|
+
const IMESSAGE_UPDATE_COMMAND = "brew update && brew upgrade imsg";
|
|
14
|
+
const HOMEBREW_IMSG_PATHS = /* @__PURE__ */ new Set([
|
|
15
|
+
"/opt/homebrew/bin/imsg",
|
|
16
|
+
"/opt/homebrew/opt/imsg/bin/imsg",
|
|
17
|
+
"/usr/local/bin/imsg",
|
|
18
|
+
"/usr/local/opt/imsg/bin/imsg"
|
|
19
|
+
]);
|
|
20
|
+
function normalizeIMessageCliPathForSetup(cliPath) {
|
|
21
|
+
return cliPath?.trim() || "imsg";
|
|
22
|
+
}
|
|
23
|
+
function isAutoManagedIMessageCliPath(cliPath, opts) {
|
|
24
|
+
const normalized = normalizeIMessageCliPathForSetup(cliPath);
|
|
25
|
+
return !opts?.explicit && normalized === "imsg" || HOMEBREW_IMSG_PATHS.has(normalized);
|
|
26
|
+
}
|
|
27
|
+
const CHAT_TARGET_ALLOWFROM_PREFIXES = [
|
|
28
|
+
"chat_id:",
|
|
29
|
+
"chatid:",
|
|
30
|
+
"chat:",
|
|
31
|
+
"chat_guid:",
|
|
32
|
+
"chatguid:",
|
|
33
|
+
"guid:",
|
|
34
|
+
"chat_identifier:",
|
|
35
|
+
"chatidentifier:",
|
|
36
|
+
"chatident:"
|
|
37
|
+
];
|
|
38
|
+
const SERVICE_ALLOWFROM_PREFIXES = [
|
|
39
|
+
"imessage:",
|
|
40
|
+
"sms:",
|
|
41
|
+
"auto:"
|
|
42
|
+
];
|
|
43
|
+
function normalizeAllowFromEntryForPrefixCheck(entry) {
|
|
44
|
+
let lower = normalizeLowercaseStringOrEmpty(entry);
|
|
45
|
+
let stripped = true;
|
|
46
|
+
while (stripped) {
|
|
47
|
+
stripped = false;
|
|
48
|
+
for (const prefix of SERVICE_ALLOWFROM_PREFIXES) if (lower.startsWith(prefix)) {
|
|
49
|
+
lower = lower.slice(prefix.length).trim();
|
|
50
|
+
stripped = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return lower;
|
|
54
|
+
}
|
|
55
|
+
function parseIMessageAllowFromEntries(raw) {
|
|
56
|
+
return parseAllowFromEntries(raw, (entry) => {
|
|
57
|
+
const lower = normalizeAllowFromEntryForPrefixCheck(entry);
|
|
58
|
+
if (CHAT_TARGET_ALLOWFROM_PREFIXES.some((prefix) => lower.startsWith(prefix))) return { error: `iMessage allowFrom entries must be sender handles: ${entry}` };
|
|
59
|
+
if (!normalizeIMessageHandle(entry)) return { error: `Invalid handle: ${entry}` };
|
|
60
|
+
return { value: entry };
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function buildIMessageSetupPatch(input) {
|
|
64
|
+
return {
|
|
65
|
+
...input.cliPath ? { cliPath: input.cliPath } : {},
|
|
66
|
+
...input.dbPath ? { dbPath: input.dbPath } : {},
|
|
67
|
+
...input.service ? { service: input.service } : {},
|
|
68
|
+
...input.region ? { region: input.region } : {}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async function promptIMessageAllowFrom(params) {
|
|
72
|
+
return promptParsedAllowFromForAccount({
|
|
73
|
+
cfg: params.cfg,
|
|
74
|
+
accountId: params.accountId,
|
|
75
|
+
defaultAccountId: resolveDefaultIMessageAccountId(params.cfg),
|
|
76
|
+
prompter: params.prompter,
|
|
77
|
+
noteTitle: "iMessage allowlist",
|
|
78
|
+
noteLines: [
|
|
79
|
+
"Allowlist iMessage DMs by sender handle.",
|
|
80
|
+
"Examples:",
|
|
81
|
+
"- +15555550123",
|
|
82
|
+
"- user@example.com",
|
|
83
|
+
"Multiple entries: comma-separated.",
|
|
84
|
+
`Docs: ${formatDocsLink("/imessage", "imessage")}`
|
|
85
|
+
],
|
|
86
|
+
message: "iMessage allowFrom (sender handle)",
|
|
87
|
+
placeholder: "+15555550123, user@example.com",
|
|
88
|
+
parseEntries: parseIMessageAllowFromEntries,
|
|
89
|
+
getExistingAllowFrom: ({ cfg, accountId }) => resolveIMessageAccount({
|
|
90
|
+
cfg,
|
|
91
|
+
accountId
|
|
92
|
+
}).config.allowFrom ?? [],
|
|
93
|
+
applyAllowFrom: ({ cfg, accountId, allowFrom }) => setAccountAllowFromForChannel({
|
|
94
|
+
cfg,
|
|
95
|
+
channel,
|
|
96
|
+
accountId,
|
|
97
|
+
allowFrom,
|
|
98
|
+
setupSurface: imessageSetupAdapter
|
|
99
|
+
})
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const imessageDmPolicy = createChannelDmPolicy({
|
|
103
|
+
label: "iMessage",
|
|
104
|
+
channel,
|
|
105
|
+
resolveAccount: (cfg, accountId) => resolveIMessageAccount({
|
|
106
|
+
cfg,
|
|
107
|
+
accountId: accountId ?? resolveDefaultIMessageAccountId(cfg)
|
|
108
|
+
}),
|
|
109
|
+
setupSurface: () => imessageSetupAdapter,
|
|
110
|
+
promptAllowFrom: promptIMessageAllowFrom
|
|
111
|
+
});
|
|
112
|
+
function createIMessageCliPathTextInput(shouldPrompt) {
|
|
113
|
+
return createCliPathTextInput({
|
|
114
|
+
inputKey: "cliPath",
|
|
115
|
+
message: "imsg CLI path",
|
|
116
|
+
resolvePath: ({ cfg, accountId }) => resolveIMessageAccount({
|
|
117
|
+
cfg,
|
|
118
|
+
accountId
|
|
119
|
+
}).config.cliPath ?? "imsg",
|
|
120
|
+
shouldPrompt,
|
|
121
|
+
helpTitle: "iMessage",
|
|
122
|
+
helpLines: [
|
|
123
|
+
"imsg CLI path required to enable iMessage.",
|
|
124
|
+
`Install imsg on the Messages Mac: ${IMESSAGE_INSTALL_COMMAND}`,
|
|
125
|
+
`Update imsg when channel probes report missing RPC or private API capabilities: ${IMESSAGE_UPDATE_COMMAND}`
|
|
126
|
+
]
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
const imessageCompletionNote = {
|
|
130
|
+
title: "iMessage next steps",
|
|
131
|
+
lines: [
|
|
132
|
+
"For the usual setup, run OpenClaw on the Mac signed into Messages.",
|
|
133
|
+
"If the Gateway runs elsewhere, set cliPath to a transparent SSH wrapper that runs imsg on the Messages Mac.",
|
|
134
|
+
`Install imsg on the Messages Mac: ${IMESSAGE_INSTALL_COMMAND}`,
|
|
135
|
+
`Update imsg after imsg fixes or missing-capability errors: ${IMESSAGE_UPDATE_COMMAND}`,
|
|
136
|
+
"Private API mode is strongly encouraged for replies, tapbacks, effects, polls, attachments, and group actions.",
|
|
137
|
+
"After Private API setup, run `imsg launch`, then `openclaw channels status --probe`.",
|
|
138
|
+
"Ensure OpenClaw has Full Disk Access to Messages DB.",
|
|
139
|
+
"Grant Automation permission for Messages when prompted.",
|
|
140
|
+
"List chats with: imsg chats --limit 20",
|
|
141
|
+
`Docs: ${formatDocsLink("/imessage", "imessage")}`
|
|
142
|
+
]
|
|
143
|
+
};
|
|
144
|
+
const imessageSetupAdapter = {
|
|
145
|
+
...createPatchedAccountSetupAdapter({
|
|
146
|
+
channelKey: channel,
|
|
147
|
+
buildPatch: (input) => buildIMessageSetupPatch(input)
|
|
148
|
+
}),
|
|
149
|
+
singleAccountKeysToMove: [
|
|
150
|
+
"cliPath",
|
|
151
|
+
"dbPath",
|
|
152
|
+
"service",
|
|
153
|
+
"region"
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
const imessageSetupContract = defineChannelSetupContract({
|
|
157
|
+
fields: {
|
|
158
|
+
cliPath: {
|
|
159
|
+
kind: "string",
|
|
160
|
+
cli: {
|
|
161
|
+
flags: "--cli-path <path>",
|
|
162
|
+
description: "iMessage CLI path"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
dbPath: {
|
|
166
|
+
kind: "string",
|
|
167
|
+
cli: {
|
|
168
|
+
flags: "--db-path <path>",
|
|
169
|
+
description: "iMessage database path"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
service: {
|
|
173
|
+
kind: "choice",
|
|
174
|
+
choices: [
|
|
175
|
+
"imessage",
|
|
176
|
+
"sms",
|
|
177
|
+
"auto"
|
|
178
|
+
],
|
|
179
|
+
cli: {
|
|
180
|
+
flags: "--service <service>",
|
|
181
|
+
description: "iMessage service"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
region: {
|
|
185
|
+
kind: "string",
|
|
186
|
+
cli: {
|
|
187
|
+
flags: "--region <region>",
|
|
188
|
+
description: "SMS region"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
legacyAdapter: imessageSetupAdapter
|
|
193
|
+
});
|
|
194
|
+
const imessageSetupStatusLabels = {
|
|
195
|
+
configuredLabel: t("wizard.channels.statusConfigured"),
|
|
196
|
+
unconfiguredLabel: t("wizard.channels.statusNeedsSetup"),
|
|
197
|
+
configuredHint: t("wizard.imessage.imsgFound"),
|
|
198
|
+
unconfiguredHint: t("wizard.imessage.imsgMissing"),
|
|
199
|
+
configuredScore: 1,
|
|
200
|
+
unconfiguredScore: 0
|
|
201
|
+
};
|
|
202
|
+
const imessageSetupStatusBase = {
|
|
203
|
+
...imessageSetupStatusLabels,
|
|
204
|
+
resolveConfigured: ({ cfg, accountId }) => resolveIMessageAccount({
|
|
205
|
+
cfg,
|
|
206
|
+
accountId
|
|
207
|
+
}).configured
|
|
208
|
+
};
|
|
209
|
+
function createIMessageSetupWizardProxy(loadWizard) {
|
|
210
|
+
return createDelegatedSetupWizardProxy({
|
|
211
|
+
channel,
|
|
212
|
+
loadWizard,
|
|
213
|
+
status: imessageSetupStatusLabels,
|
|
214
|
+
delegatePrepare: true,
|
|
215
|
+
credentials: [],
|
|
216
|
+
textInputs: [createIMessageCliPathTextInput(createDelegatedTextInputShouldPrompt({
|
|
217
|
+
loadWizard,
|
|
218
|
+
inputKey: "cliPath"
|
|
219
|
+
}))],
|
|
220
|
+
completionNote: imessageCompletionNote,
|
|
221
|
+
dmPolicy: imessageDmPolicy,
|
|
222
|
+
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
//#endregion
|
|
226
|
+
export { imessageCompletionNote as a, imessageSetupStatusBase as c, parseIMessageAllowFromEntries as d, createIMessageSetupWizardProxy as i, isAutoManagedIMessageCliPath as l, IMESSAGE_UPDATE_COMMAND as n, imessageDmPolicy as o, createIMessageCliPathTextInput as r, imessageSetupContract as s, IMESSAGE_INSTALL_COMMAND as t, normalizeIMessageCliPathForSetup as u };
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps-B-QEsLSM.mjs";
|
|
4
|
-
import { t as sendMessageIMessage } from "./send-odAfTQ2J.mjs";
|
|
5
|
-
import { t as monitorIMessageProvider } from "./monitor-BJ3Ozi6I.mjs";
|
|
6
|
-
import { createAccountStatusSink, resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
|
|
1
|
+
import { o as resolveIMessageAccount } from "./accounts-nzcU0cq2.mjs";
|
|
2
|
+
import { a as imessageCompletionNote, c as imessageSetupStatusBase, l as isAutoManagedIMessageCliPath, o as imessageDmPolicy, r as createIMessageCliPathTextInput, t as IMESSAGE_INSTALL_COMMAND, u as normalizeIMessageCliPathForSetup } from "./setup-core-8MDdYHj5.mjs";
|
|
7
3
|
import path from "node:path";
|
|
8
|
-
import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
|
|
9
4
|
import fs from "node:fs/promises";
|
|
10
5
|
import { createDetectedBinaryStatus, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
11
6
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
12
7
|
import { detectBinary as detectBinary$1, resolveBrewExecutable } from "openclaw/plugin-sdk/setup-tools";
|
|
8
|
+
import { isPathStrictlyInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
13
9
|
import { runPluginCommandWithTimeout } from "openclaw/plugin-sdk/run-command";
|
|
14
10
|
//#region extensions/imessage/src/install-imsg.ts
|
|
15
11
|
const IMESSAGE_BREW_FORMULA = "steipete/tap/imsg";
|
|
16
|
-
function isPathInside(parentPath, candidatePath) {
|
|
17
|
-
const relative = path.relative(parentPath, candidatePath);
|
|
18
|
-
return relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
|
|
19
|
-
}
|
|
20
12
|
async function resolveBrewManagedIMessageCliPath(brewExe, cliPath) {
|
|
21
13
|
try {
|
|
22
14
|
const formulae = await runPluginCommandWithTimeout({
|
|
@@ -49,7 +41,7 @@ async function resolveBrewManagedIMessageCliPath(brewExe, cliPath) {
|
|
|
49
41
|
});
|
|
50
42
|
if (cellar.code !== 0 || !cellar.stdout.trim()) return null;
|
|
51
43
|
const [realCliPath, realFormulaPath] = await Promise.all([fs.realpath(resolvedCliPath), fs.realpath(path.join(cellar.stdout.trim(), "imsg"))]);
|
|
52
|
-
return
|
|
44
|
+
return isPathStrictlyInside(realFormulaPath, realCliPath) ? resolvedCliPath : null;
|
|
53
45
|
} catch {
|
|
54
46
|
return null;
|
|
55
47
|
}
|
|
@@ -126,13 +118,7 @@ const channel = "imessage";
|
|
|
126
118
|
const imessageDetectedBinaryStatus = createDetectedBinaryStatus({
|
|
127
119
|
channelLabel: "iMessage",
|
|
128
120
|
binaryLabel: "imsg",
|
|
129
|
-
|
|
130
|
-
unconfiguredLabel: imessageSetupStatusBase.unconfiguredLabel,
|
|
131
|
-
configuredHint: imessageSetupStatusBase.configuredHint,
|
|
132
|
-
unconfiguredHint: imessageSetupStatusBase.unconfiguredHint,
|
|
133
|
-
configuredScore: imessageSetupStatusBase.configuredScore,
|
|
134
|
-
unconfiguredScore: imessageSetupStatusBase.unconfiguredScore,
|
|
135
|
-
resolveConfigured: imessageSetupStatusBase.resolveConfigured,
|
|
121
|
+
...imessageSetupStatusBase,
|
|
136
122
|
resolveBinaryPath: ({ cfg, accountId }) => resolveIMessageAccount({
|
|
137
123
|
cfg,
|
|
138
124
|
accountId
|
|
@@ -195,87 +181,4 @@ const imessageSetupWizard = {
|
|
|
195
181
|
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
|
|
196
182
|
};
|
|
197
183
|
//#endregion
|
|
198
|
-
|
|
199
|
-
async function sendIMessageOutbound(params) {
|
|
200
|
-
const send = resolveOutboundSendDep(params.deps, "imessage", { legacyKeys: IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS }) ?? sendMessageIMessage;
|
|
201
|
-
const maxBytes = resolveChannelMediaMaxBytes({
|
|
202
|
-
cfg: params.cfg,
|
|
203
|
-
resolveChannelLimitMb: () => resolveIMessageAccount(params).config.mediaMaxMb
|
|
204
|
-
});
|
|
205
|
-
const result = await send(params.to, params.text, {
|
|
206
|
-
config: params.cfg,
|
|
207
|
-
...params.mediaUrl ? { mediaUrl: params.mediaUrl } : {},
|
|
208
|
-
...params.mediaAccess ? { mediaAccess: params.mediaAccess } : {},
|
|
209
|
-
...params.mediaLocalRoots?.length ? { mediaLocalRoots: params.mediaLocalRoots } : {},
|
|
210
|
-
...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {},
|
|
211
|
-
...params.audioAsVoice ? { audioAsVoice: true } : {},
|
|
212
|
-
maxBytes,
|
|
213
|
-
accountId: params.accountId ?? void 0,
|
|
214
|
-
replyToId: params.replyToId ?? void 0,
|
|
215
|
-
conversationReadOrigin: params.conversationReadOrigin,
|
|
216
|
-
assertDirectAdapterHandoff: params.assertDirectAdapterHandoff,
|
|
217
|
-
onPlatformSendDispatch: params.onPlatformSendDispatch,
|
|
218
|
-
...params.onDeliveryResult ? { onDeliveryResult: params.onDeliveryResult } : {}
|
|
219
|
-
});
|
|
220
|
-
const meta = {
|
|
221
|
-
...result.meta,
|
|
222
|
-
...result.guid ? { imessageMessageGuid: result.guid } : {},
|
|
223
|
-
...result.sentText ? { imessageVisibleText: result.sentText } : {}
|
|
224
|
-
};
|
|
225
|
-
return Object.keys(meta).length > 0 ? {
|
|
226
|
-
...result,
|
|
227
|
-
meta
|
|
228
|
-
} : result;
|
|
229
|
-
}
|
|
230
|
-
async function probeIMessageAccount(params) {
|
|
231
|
-
return await probeIMessage(params?.timeoutMs, {
|
|
232
|
-
cliPath: params?.cliPath,
|
|
233
|
-
dbPath: params?.dbPath,
|
|
234
|
-
remoteHost: params?.remoteHost,
|
|
235
|
-
forceRefresh: true
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
async function startIMessageGatewayAccount(ctx) {
|
|
239
|
-
const account = ctx.account;
|
|
240
|
-
const cliPath = account.config.cliPath?.trim() || "imsg";
|
|
241
|
-
const dbPath = account.config.dbPath?.trim();
|
|
242
|
-
ctx.setStatus({
|
|
243
|
-
accountId: account.accountId,
|
|
244
|
-
cliPath,
|
|
245
|
-
dbPath: dbPath ?? null
|
|
246
|
-
});
|
|
247
|
-
await Promise.all(listEnabledIMessageAccounts(ctx.cfg).map(async (candidate) => {
|
|
248
|
-
await resolveIMessageRemoteHost({
|
|
249
|
-
cliPath: candidate.config.cliPath?.trim() || "imsg",
|
|
250
|
-
remoteHost: candidate.config.remoteHost
|
|
251
|
-
});
|
|
252
|
-
}));
|
|
253
|
-
const ownerAccountId = resolveIMessageDuplicateSourceOwner({
|
|
254
|
-
cfg: ctx.cfg,
|
|
255
|
-
account
|
|
256
|
-
});
|
|
257
|
-
if (ownerAccountId) {
|
|
258
|
-
ctx.log?.info?.(`[${account.accountId}] skipping watcher: duplicate iMessage source; using account "${ownerAccountId}"`);
|
|
259
|
-
if (ctx.abortSignal.aborted) return;
|
|
260
|
-
await new Promise((resolve) => {
|
|
261
|
-
ctx.abortSignal.addEventListener("abort", () => resolve(), { once: true });
|
|
262
|
-
});
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
const statusSink = createAccountStatusSink({
|
|
266
|
-
accountId: account.accountId,
|
|
267
|
-
setStatus: ctx.setStatus
|
|
268
|
-
});
|
|
269
|
-
statusSink({ lifecycle: "starting" });
|
|
270
|
-
ctx.log?.info?.(`[${account.accountId}] starting provider (${cliPath}${dbPath ? ` db=${dbPath}` : ""})`);
|
|
271
|
-
return await monitorIMessageProvider({
|
|
272
|
-
accountId: account.accountId,
|
|
273
|
-
config: ctx.cfg,
|
|
274
|
-
runtime: ctx.runtime,
|
|
275
|
-
abortSignal: ctx.abortSignal,
|
|
276
|
-
channelRuntime: ctx.channelRuntime,
|
|
277
|
-
statusSink
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
//#endregion
|
|
281
|
-
export { imessageSetupWizard, probeIMessageAccount, sendIMessageOutbound, startIMessageGatewayAccount };
|
|
184
|
+
export { imessageSetupWizard };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { extractErrorCode } from "openclaw/plugin-sdk/error-runtime";
|
|
4
|
+
//#region extensions/imessage/src/state-migrations.ts
|
|
5
|
+
async function retiredSourceWarnings(stateDir) {
|
|
6
|
+
const imessageDir = path.join(stateDir, "imessage");
|
|
7
|
+
const catchupDir = path.join(imessageDir, "catchup");
|
|
8
|
+
let catchupFiles;
|
|
9
|
+
try {
|
|
10
|
+
catchupFiles = await fs.readdir(catchupDir);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (extractErrorCode(error) !== "ENOENT") throw error;
|
|
13
|
+
catchupFiles = [];
|
|
14
|
+
}
|
|
15
|
+
const candidates = [
|
|
16
|
+
path.join(imessageDir, "reply-cache.jsonl"),
|
|
17
|
+
path.join(imessageDir, "sent-echoes.jsonl"),
|
|
18
|
+
...catchupFiles.filter((name) => name.endsWith(".json")).toSorted().map((name) => path.join(catchupDir, name))
|
|
19
|
+
];
|
|
20
|
+
const warnings = [];
|
|
21
|
+
for (const sourcePath of candidates) {
|
|
22
|
+
try {
|
|
23
|
+
await fs.lstat(sourcePath);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (extractErrorCode(error) === "ENOENT") continue;
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
warnings.push(`Preserved retired iMessage state at ${sourcePath}. Install OpenClaw 2026.9.5, run "openclaw doctor --fix", then upgrade to latest. See https://docs.openclaw.ai/install/updating#upgrading-very-old-versions.`);
|
|
29
|
+
}
|
|
30
|
+
return warnings;
|
|
31
|
+
}
|
|
32
|
+
const imessageRetiredStateMigration = {
|
|
33
|
+
id: "imessage-legacy-state",
|
|
34
|
+
label: "iMessage legacy state",
|
|
35
|
+
async detectLegacyState({ stateDir }) {
|
|
36
|
+
const preview = await retiredSourceWarnings(stateDir);
|
|
37
|
+
return preview.length > 0 ? { preview } : null;
|
|
38
|
+
},
|
|
39
|
+
async migrateLegacyState({ stateDir }) {
|
|
40
|
+
return {
|
|
41
|
+
changes: [],
|
|
42
|
+
warnings: await retiredSourceWarnings(stateDir)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { imessageRetiredStateMigration };
|
|
@@ -30,12 +30,9 @@ function normalizeIMessageHandle$1(raw, allowContactName = false) {
|
|
|
30
30
|
const trimmed = raw.trim();
|
|
31
31
|
if (!trimmed) return "";
|
|
32
32
|
const lowered = normalizeLowercaseStringOrEmpty(trimmed);
|
|
33
|
-
if (lowered.startsWith(
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
if (CHAT_TARGET_PREFIX_RE.test(trimmed)) {
|
|
37
|
-
const prefix = trimmed.match(CHAT_TARGET_PREFIX_RE)?.[0];
|
|
38
|
-
if (!prefix) return "";
|
|
33
|
+
for (const prefix of SERVICE_PREFIXES$1) if (lowered.startsWith(prefix)) return normalizeIMessageHandle$1(trimmed.slice(prefix.length));
|
|
34
|
+
const prefix = trimmed.match(CHAT_TARGET_PREFIX_RE)?.[0];
|
|
35
|
+
if (prefix) {
|
|
39
36
|
const value = trimmed.slice(prefix.length).trim();
|
|
40
37
|
return `${normalizeLowercaseStringOrEmpty(prefix)}${value}`;
|
|
41
38
|
}
|
|
@@ -105,12 +102,12 @@ function normalizeIMessageHandle(raw) {
|
|
|
105
102
|
const trimmed = raw.trim();
|
|
106
103
|
if (!trimmed) return "";
|
|
107
104
|
const lowered = normalizeLowercaseStringOrEmpty(trimmed);
|
|
108
|
-
if (lowered.startsWith(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
for (const prefix of
|
|
105
|
+
for (const { prefix } of SERVICE_PREFIXES) if (lowered.startsWith(prefix)) return normalizeIMessageHandle(trimmed.slice(prefix.length));
|
|
106
|
+
for (const [kind, prefixes] of [
|
|
107
|
+
["chat_id", CHAT_ID_PREFIXES],
|
|
108
|
+
["chat_guid", CHAT_GUID_PREFIXES],
|
|
109
|
+
["chat_identifier", CHAT_IDENTIFIER_PREFIXES]
|
|
110
|
+
]) for (const prefix of prefixes) if (lowered.startsWith(prefix)) return `${kind}:${trimmed.slice(prefix.length).trim()}`;
|
|
114
111
|
return normalizeIMessageHandleValue(trimmed) ?? trimmed.replace(/\s+/g, "");
|
|
115
112
|
}
|
|
116
113
|
function parseIMessageTarget(raw) {
|
|
@@ -205,14 +202,11 @@ function isAllowedIMessageSender(params) {
|
|
|
205
202
|
allowConversationTargets: false
|
|
206
203
|
});
|
|
207
204
|
}
|
|
208
|
-
const
|
|
205
|
+
const isAllowedIMessageReplyContextSender = createAllowedChatSenderMatcher({
|
|
209
206
|
normalizeSender: normalizeIMessageHandle,
|
|
210
207
|
parseAllowTarget: parseIMessageAllowTarget,
|
|
211
208
|
allowConversationTargets: true
|
|
212
209
|
});
|
|
213
|
-
function isAllowedIMessageReplyContextSender(params) {
|
|
214
|
-
return isAllowedIMessageReplyContextSenderMatcher(params);
|
|
215
|
-
}
|
|
216
210
|
function formatIMessageChatTarget(chatId) {
|
|
217
211
|
if (!chatId || !Number.isFinite(chatId)) return "";
|
|
218
212
|
return `chat_id:${chatId}`;
|
package/dist/api.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as looksLikeIMessageExplicitTargetId, c as parseIMessageTarget, i as isAllowedIMessageSender, l as looksLikeIMessageTargetId, n as inferIMessageTargetChatType, o as normalizeIMessageHandle, s as parseIMessageAllowTarget, t as formatIMessageChatTarget, u as normalizeIMessageMessagingTarget } from "./.setup/targets-
|
|
2
|
-
import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./.setup/accounts-
|
|
3
|
-
import { o as IMESSAGE_ACTIONS, s as IMESSAGE_ACTION_NAMES } from "./.setup/message-tool-api-
|
|
4
|
-
import {
|
|
5
|
-
import { a as matchIMessageAcpConversation, d as probeIMessage, i as resolveIMessageInboundConversationId, o as normalizeIMessageAcpConversationId, r as resolveIMessageGroupToolPolicy, s as resolveIMessageConversationIdFromTarget, t as resolveIMessageGroupRequireMention } from "./.setup/group-policy-
|
|
6
|
-
import { t as imessagePlugin } from "./.setup/channel-
|
|
1
|
+
import { a as looksLikeIMessageExplicitTargetId, c as parseIMessageTarget, i as isAllowedIMessageSender, l as looksLikeIMessageTargetId, n as inferIMessageTargetChatType, o as normalizeIMessageHandle, s as parseIMessageAllowTarget, t as formatIMessageChatTarget, u as normalizeIMessageMessagingTarget } from "./.setup/targets-BicBiYsM.mjs";
|
|
2
|
+
import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./.setup/accounts-nzcU0cq2.mjs";
|
|
3
|
+
import { o as IMESSAGE_ACTIONS, s as IMESSAGE_ACTION_NAMES } from "./.setup/message-tool-api-D032l82H.mjs";
|
|
4
|
+
import { S as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./.setup/sanitize-outbound-3MLljgtY.mjs";
|
|
5
|
+
import { a as matchIMessageAcpConversation, d as probeIMessage, i as resolveIMessageInboundConversationId, o as normalizeIMessageAcpConversationId, r as resolveIMessageGroupToolPolicy, s as resolveIMessageConversationIdFromTarget, t as resolveIMessageGroupRequireMention } from "./.setup/group-policy-90pw4tyG.mjs";
|
|
6
|
+
import { t as imessagePlugin } from "./.setup/channel-9fyvuN_p.mjs";
|
|
7
7
|
import { t as createIMessageConversationBindingManager } from "./.setup/conversation-bindings-GDQ_Laxj.mjs";
|
|
8
|
-
import { a as resolveServicePrefixedChatTarget, c as imessageSetupPlugin, i as resolveServicePrefixedAllowTarget, n as parseChatAllowTargetPrefixes, o as resolveServicePrefixedOrChatAllowTarget, r as parseChatTargetPrefixesOrThrow, s as resolveServicePrefixedTarget, t as createAllowedChatSenderMatcher } from "./.setup/api-
|
|
8
|
+
import { a as resolveServicePrefixedChatTarget, c as imessageSetupPlugin, i as resolveServicePrefixedAllowTarget, n as parseChatAllowTargetPrefixes, o as resolveServicePrefixedOrChatAllowTarget, r as parseChatTargetPrefixesOrThrow, s as resolveServicePrefixedTarget, t as createAllowedChatSenderMatcher } from "./.setup/api-B9Qx21G-.mjs";
|
|
9
9
|
import { t as IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./.setup/outbound-send-deps-B-QEsLSM.mjs";
|
|
10
10
|
export { DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS, IMESSAGE_ACTIONS, IMESSAGE_ACTION_NAMES, IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS, createAllowedChatSenderMatcher, createIMessageConversationBindingManager, formatIMessageChatTarget, imessagePlugin, imessageSetupPlugin, inferIMessageTargetChatType, isAllowedIMessageSender, listEnabledIMessageAccounts, listIMessageAccountIds, looksLikeIMessageExplicitTargetId, looksLikeIMessageTargetId, matchIMessageAcpConversation, normalizeIMessageAcpConversationId, normalizeIMessageHandle, normalizeIMessageMessagingTarget, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow, parseIMessageAllowTarget, parseIMessageTarget, probeIMessage, resolveDefaultIMessageAccountId, resolveIMessageAccount, resolveIMessageConversationIdFromTarget, resolveIMessageGroupRequireMention, resolveIMessageGroupToolPolicy, resolveIMessageInboundConversationId, resolveServicePrefixedAllowTarget, resolveServicePrefixedChatTarget, resolveServicePrefixedOrChatAllowTarget, resolveServicePrefixedTarget };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as IMessageChannelConfigSchema } from "./.setup/config-schema-
|
|
1
|
+
import { t as IMessageChannelConfigSchema } from "./.setup/config-schema-4Q3_EqYt.mjs";
|
|
2
2
|
export { IMessageChannelConfigSchema };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as imessagePlugin } from "./.setup/channel-
|
|
1
|
+
import { t as imessagePlugin } from "./.setup/channel-9fyvuN_p.mjs";
|
|
2
2
|
export { imessagePlugin };
|
package/dist/contract-api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as resolveIMessageAttachmentRoots, r as resolveIMessageRemoteAttachmentRoots, t as DEFAULT_IMESSAGE_ATTACHMENT_ROOTS } from "./.setup/media-contract-
|
|
1
|
+
import { n as resolveIMessageAttachmentRoots, r as resolveIMessageRemoteAttachmentRoots, t as DEFAULT_IMESSAGE_ATTACHMENT_ROOTS } from "./.setup/media-contract-CagwSMvo.mjs";
|
|
2
2
|
import "./media-contract-api.js";
|
|
3
3
|
export { DEFAULT_IMESSAGE_ATTACHMENT_ROOTS, resolveIMessageAttachmentRoots, resolveIMessageAttachmentRoots as resolveInboundAttachmentRoots, resolveIMessageRemoteAttachmentRoots, resolveIMessageRemoteAttachmentRoots as resolveRemoteInboundAttachmentRoots };
|