cclawd 1.0.7 → 1.0.8

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 (168) hide show
  1. package/dist/{active-listener-DYmI7imH.js → active-listener-Dkhmfuwx.js} +2 -2
  2. package/dist/{api-key-rotation-DLU4jvSu.js → api-key-rotation-BOfI3cG3.js} +1 -1
  3. package/dist/{audio-preflight-C9TMbRb4.js → audio-preflight-CtkZ5SAs.js} +15 -15
  4. package/dist/{audio-transcription-runner-Q5zG_hYd.js → audio-transcription-runner-CbPqoiHX.js} +10 -10
  5. package/dist/{audit-membership-runtime-DhxSwFnF.js → audit-membership-runtime-hXUuer4x.js} +6 -6
  6. package/dist/build-info.json +3 -3
  7. package/dist/bundled/boot-md/handler.js +35 -35
  8. package/dist/bundled/bootstrap-extra-files/handler.js +5 -5
  9. package/dist/bundled/command-logger/handler.js +2 -2
  10. package/dist/bundled/session-memory/handler.js +35 -35
  11. package/dist/{channel-activity-Bx08UTAg.js → channel-activity-DWAER4wd.js} +2 -2
  12. package/dist/{commands-registry-llLVCTH9.js → commands-registry-BUyiA7nE.js} +2 -2
  13. package/dist/compact.runtime-DpcZpcTl.js +39 -0
  14. package/dist/{deliver-DJf2ZBpe.js → deliver-aHOaRbkt.js} +19 -19
  15. package/dist/deliver-runtime-D4bCsr6d.js +19 -0
  16. package/dist/deps-send-discord.runtime-BziKU-pE.js +19 -0
  17. package/dist/deps-send-imessage.runtime-CFRnDTqp.js +18 -0
  18. package/dist/deps-send-signal.runtime-BuOtABJm.js +17 -0
  19. package/dist/deps-send-slack.runtime-BOLqvMxW.js +17 -0
  20. package/dist/deps-send-telegram.runtime-DeEoFLv5.js +20 -0
  21. package/dist/deps-send-whatsapp.runtime-CG1uXYLY.js +43 -0
  22. package/dist/{diagnostic-BCCMF3O_.js → diagnostic-BdcXX9iJ.js} +2 -2
  23. package/dist/{env-aYXLHjfZ.js → env-lw2hsIUY.js} +1 -1
  24. package/dist/{fetch-bvgIiupu.js → fetch-C0iyt-Iz.js} +3 -3
  25. package/dist/{fetch-DCTUdr1U.js → fetch-D9NUULbj.js} +5 -5
  26. package/dist/{fetch-guard-CqpEmMQ2.js → fetch-guard-B5ZMnGaN.js} +2 -2
  27. package/dist/{frontmatter-DjZuS525.js → frontmatter-C_obXuTp.js} +3 -3
  28. package/dist/{github-copilot-token-CQmATy5E.js → github-copilot-token-8N63GdbE.js} +7 -7
  29. package/dist/{image-Q8E1-lZn.js → image-4x07m4Jl.js} +4 -4
  30. package/dist/image-runtime-smkMrIol.js +12 -0
  31. package/dist/{ir-CzM3SxId.js → ir-CsgNUpOU.js} +6 -6
  32. package/dist/llm-slug-generator.js +35 -35
  33. package/dist/{logger-ChbX1G7s.js → logger-CbUVl62f.js} +7 -7
  34. package/dist/{login-B0mtU11X.js → login-p_O59TVQ.js} +4 -4
  35. package/dist/{login-qr-DY_i60f5.js → login-qr-BCJpDsAy.js} +10 -10
  36. package/dist/{manager-FAQPC0uO.js → manager-CwYv8O3T.js} +12 -12
  37. package/dist/manager-runtime-D_jEoBr9.js +15 -0
  38. package/dist/{model-selection-wf3OY5DX.js → model-selection-Cv2Puf5z.js} +122 -122
  39. package/dist/{outbound-Bw0dOVS7.js → outbound-Chpiwybe.js} +6 -6
  40. package/dist/{outbound-attachment-1R6r9Pg_.js → outbound-attachment-BnAVJDLe.js} +2 -2
  41. package/dist/{paths-C0HLtPu0.js → paths-CehYKFsO.js} +7 -7
  42. package/dist/{paths-hfkBoC7i.js → paths-DkxwiA8g.js} +5 -5
  43. package/dist/{pi-embedded-BAHaY-Oh.js → pi-embedded-CJVNBk0y.js} +150 -150
  44. package/dist/pi-model-discovery-7IzK0Uc3.js +131 -0
  45. package/dist/pi-model-discovery-runtime-DABef3qy.js +12 -0
  46. package/dist/{pi-tools.before-tool-call.runtime-D_mthvtC.js → pi-tools.before-tool-call.runtime-BP2UvGJb.js} +10 -10
  47. package/dist/plugin-sdk/active-listener-CN-tMEvN.js +35 -0
  48. package/dist/plugin-sdk/api-key-rotation-CimGYMBc.js +176 -0
  49. package/dist/plugin-sdk/audio-preflight-C-xXBoE2.js +51 -0
  50. package/dist/plugin-sdk/audio-transcription-runner-CTIHpebA.js +2173 -0
  51. package/dist/plugin-sdk/audit-membership-runtime-BFatB2LJ.js +58 -0
  52. package/dist/plugin-sdk/channel-activity-DO0FEzyj.js +95 -0
  53. package/dist/plugin-sdk/channel-web-Da-__nUF.js +2238 -0
  54. package/dist/plugin-sdk/commands-registry-6no2NNrY.js +1118 -0
  55. package/dist/plugin-sdk/compact.runtime-CCoclu5e.js +35 -0
  56. package/dist/plugin-sdk/compat.js +35 -35
  57. package/dist/plugin-sdk/config-B9ODwgpz.js +37426 -0
  58. package/dist/plugin-sdk/deliver-B1fFpKjV.js +1757 -0
  59. package/dist/plugin-sdk/deliver-runtime-DB-VRMe1.js +15 -0
  60. package/dist/plugin-sdk/deps-send-discord.runtime-DklqycYG.js +15 -0
  61. package/dist/plugin-sdk/deps-send-imessage.runtime-Chs8zeon.js +14 -0
  62. package/dist/plugin-sdk/deps-send-signal.runtime-clW9aSJP.js +13 -0
  63. package/dist/plugin-sdk/deps-send-slack.runtime-BUx0LYY1.js +13 -0
  64. package/dist/plugin-sdk/deps-send-telegram.runtime-LECSHgMG.js +16 -0
  65. package/dist/plugin-sdk/deps-send-whatsapp.runtime-D2d65fw0.js +40 -0
  66. package/dist/plugin-sdk/diagnostic-CxIvS-C2.js +315 -0
  67. package/dist/plugin-sdk/dispatch-BqlR4dPx.js +105863 -0
  68. package/dist/plugin-sdk/env-b9k1PHMI.js +34 -0
  69. package/dist/plugin-sdk/fetch-PoxzAANT.js +326 -0
  70. package/dist/plugin-sdk/fetch-guard-4UVSZ0uS.js +164 -0
  71. package/dist/plugin-sdk/image-Ch6M4tnJ.js +2420 -0
  72. package/dist/plugin-sdk/image-runtime-CSh2o5wY.js +8 -0
  73. package/dist/plugin-sdk/ir-CugsqGH8.js +1312 -0
  74. package/dist/plugin-sdk/local-roots-adnEg9zb.js +217 -0
  75. package/dist/plugin-sdk/logger-D6zRubj0.js +1164 -0
  76. package/dist/plugin-sdk/login-CYvkQ0At.js +54 -0
  77. package/dist/plugin-sdk/login-qr-ll4NtaT5.js +316 -0
  78. package/dist/plugin-sdk/manager-CHy8IclH.js +3959 -0
  79. package/dist/plugin-sdk/manager-runtime-C70EkEr7.js +11 -0
  80. package/dist/plugin-sdk/outbound-Wzs2iN7X.js +216 -0
  81. package/dist/plugin-sdk/outbound-attachment-khXJwucX.js +17 -0
  82. package/dist/plugin-sdk/paths-BtVqCdw4.js +3063 -0
  83. package/dist/{pi-model-discovery-ItS07aJB.js → plugin-sdk/pi-model-discovery-Dh4ziodY.js} +2 -2
  84. package/dist/plugin-sdk/pi-model-discovery-runtime-b83Xe-HT.js +8 -0
  85. package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-C1z5CDBF.js +349 -0
  86. package/dist/{proxy-fetch-c1ZUFFcO.js → plugin-sdk/proxy-fetch-CJEmoBxi.js} +1 -1
  87. package/dist/plugin-sdk/pw-ai-Dj3Cvlzl.js +1990 -0
  88. package/dist/plugin-sdk/qmd-manager-egHUAseQ.js +1581 -0
  89. package/dist/plugin-sdk/resolve-outbound-target-BiICvIKs.js +38 -0
  90. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-DNApufzW.js +9 -0
  91. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-CBmtfIQ8.js +13 -0
  92. package/dist/plugin-sdk/send-CScblaI4.js +532 -0
  93. package/dist/plugin-sdk/send-CeHhnld6.js +407 -0
  94. package/dist/plugin-sdk/send-DP_c8JfR.js +3277 -0
  95. package/dist/plugin-sdk/send-Dc5fI6e8.js +495 -0
  96. package/dist/plugin-sdk/send-l-77_s1_.js +2507 -0
  97. package/dist/plugin-sdk/session-CkOKZaqa.js +166 -0
  98. package/dist/plugin-sdk/signal.js +2 -2
  99. package/dist/plugin-sdk/skill-commands-BohYCgkq.js +336 -0
  100. package/dist/plugin-sdk/slash-commands.runtime-DpLfVTM6.js +8 -0
  101. package/dist/plugin-sdk/slash-dispatch.runtime-CASMHwpm.js +35 -0
  102. package/dist/plugin-sdk/slash-skill-commands.runtime-D7rrJEci.js +9 -0
  103. package/dist/plugin-sdk/sqlite-CJE3X7Mv.js +1005 -0
  104. package/dist/plugin-sdk/subagent-registry-runtime-B1oo5bih.js +35 -0
  105. package/dist/plugin-sdk/tables-D5VgpTmm.js +53 -0
  106. package/dist/plugin-sdk/target-errors-C6zZ_OpA.js +191 -0
  107. package/dist/{tokens-BWDIKewp.js → plugin-sdk/tokens-DUnJnpMS.js} +1 -1
  108. package/dist/plugin-sdk/web-TfUM1nSi.js +39 -0
  109. package/dist/plugin-sdk/whatsapp-actions-DuWJ0j1r.js +71 -0
  110. package/dist/proxy-fetch-BOh1PLOW.js +54 -0
  111. package/dist/{pw-ai-Ok6KGelf.js → pw-ai-DwH5GpEO.js} +9 -9
  112. package/dist/{qmd-manager-DhfEz4Ar.js → qmd-manager-DEscZz5_.js} +6 -6
  113. package/dist/{query-expansion-GqNV2iIE.js → query-expansion-BErUY8P2.js} +4 -4
  114. package/dist/runtime-whatsapp-login.runtime-BI3U306v.js +13 -0
  115. package/dist/runtime-whatsapp-outbound.runtime-Bsc2uD09.js +17 -0
  116. package/dist/{send-DwAoiT2p.js → send-BDnOgWIp.js} +25 -25
  117. package/dist/{send-CS0ocZHl.js → send-C-Q_WPMf.js} +3 -3
  118. package/dist/{send-6R8b9zsj.js → send-DUibfNQD.js} +5 -5
  119. package/dist/{send-DPflcjM5.js → send-DtBvCnPQ.js} +6 -6
  120. package/dist/{send-CEg4P96c.js → send-ORtn50qg.js} +5 -5
  121. package/dist/{session-BoIID5UR.js → session-B7imi6T5.js} +7 -7
  122. package/dist/{skill-commands-DhdiziMs.js → skill-commands-B9brPuiL.js} +9 -9
  123. package/dist/slash-commands.runtime-Cf6ygfBp.js +12 -0
  124. package/dist/slash-dispatch.runtime-CsmvhO5K.js +39 -0
  125. package/dist/slash-skill-commands.runtime-CX7stIEP.js +13 -0
  126. package/dist/subagent-registry-runtime-B_S1nf7y.js +39 -0
  127. package/dist/{subsystem-C8z6w6xC.js → subsystem-DfXy5gUB.js} +14 -14
  128. package/dist/{tables-DQusRhkD.js → tables-CjQqTOdD.js} +1 -1
  129. package/dist/{target-errors-CfavnC9U.js → target-errors-BZE1mc-W.js} +1 -1
  130. package/dist/tokens-6ul2IrzG.js +50 -0
  131. package/dist/{web-CrcrTQ2c.js → web-Cd8yK1Zq.js} +39 -39
  132. package/dist/{whatsapp-actions-B0u0ZAme.js → whatsapp-actions-CYEzUMBI.js} +15 -15
  133. package/dist/{workspace-CWDYHR27.js → workspace-DGIcKCCW.js} +20 -20
  134. package/extensions/cclawd-mfa-auth/README.md +118 -0
  135. package/extensions/cclawd-mfa-auth/index.ts +382 -0
  136. package/extensions/cclawd-mfa-auth/openclaw.plugin.json +34 -0
  137. package/extensions/cclawd-mfa-auth/package.json +27 -0
  138. package/extensions/cclawd-mfa-auth/src/auth-manager.ts +536 -0
  139. package/extensions/cclawd-mfa-auth/src/config.ts +82 -0
  140. package/extensions/cclawd-mfa-auth/src/dabby-client.ts +200 -0
  141. package/extensions/cclawd-mfa-auth/src/notification-service.ts +417 -0
  142. package/extensions/cclawd-mfa-auth/src/polling-manager.ts +232 -0
  143. package/extensions/cclawd-mfa-auth/src/providers/base.ts +25 -0
  144. package/extensions/cclawd-mfa-auth/src/providers/qr-code.ts +98 -0
  145. package/extensions/cclawd-mfa-auth/src/sensitive-detector.ts +159 -0
  146. package/extensions/cclawd-mfa-auth/src/session-resolver.ts +159 -0
  147. package/extensions/cclawd-mfa-auth/src/types.ts +156 -0
  148. package/extensions/mfa-auth/index.ts +675 -1028
  149. package/extensions/mfa-auth/openclaw.plugin.json +1 -1
  150. package/extensions/mfa-auth/src/notification-service.ts +2 -8
  151. package/package.json +453 -453
  152. package/dist/compact.runtime-BEn3giMt.js +0 -39
  153. package/dist/deliver-runtime-DkQ3XzGv.js +0 -19
  154. package/dist/deps-send-discord.runtime-BLpqSj6s.js +0 -19
  155. package/dist/deps-send-imessage.runtime-BFzyYqvR.js +0 -18
  156. package/dist/deps-send-signal.runtime-DT0TYCy1.js +0 -17
  157. package/dist/deps-send-slack.runtime-BhaGFfMX.js +0 -17
  158. package/dist/deps-send-telegram.runtime-B6Cic9NX.js +0 -20
  159. package/dist/deps-send-whatsapp.runtime-WtEhIq2S.js +0 -43
  160. package/dist/image-runtime-B1LFYfQ2.js +0 -12
  161. package/dist/manager-runtime-Da7ME9vS.js +0 -15
  162. package/dist/pi-model-discovery-runtime-DjM7Z1fx.js +0 -12
  163. package/dist/runtime-whatsapp-login.runtime-D4BRhQkK.js +0 -13
  164. package/dist/runtime-whatsapp-outbound.runtime-DJPpS6g-.js +0 -17
  165. package/dist/slash-commands.runtime-Cu1lTjV9.js +0 -12
  166. package/dist/slash-dispatch.runtime-DRVJEF4l.js +0 -39
  167. package/dist/slash-skill-commands.runtime-C373PJjv.js +0 -13
  168. package/dist/subagent-registry-runtime-D7hWBo1G.js +0 -39
@@ -0,0 +1,495 @@
1
+ import { _o as isAllowedParsedChatSender, io as resolveIMessageAccount, js as kindFromMime, r as loadConfig } from "./config-B9ODwgpz.js";
2
+ import { C as normalizeE164, D as resolveUserPath } from "./logger-D6zRubj0.js";
3
+ import { i as resolveMarkdownTableMode } from "./ir-CugsqGH8.js";
4
+ import { t as convertMarkdownTables } from "./tables-D5VgpTmm.js";
5
+ import { t as resolveOutboundAttachmentFromUrl } from "./outbound-attachment-khXJwucX.js";
6
+ import { spawn } from "node:child_process";
7
+ import { createInterface } from "node:readline";
8
+ //#region src/imessage/target-parsing-helpers.ts
9
+ function stripPrefix(value, prefix) {
10
+ return value.slice(prefix.length).trim();
11
+ }
12
+ function startsWithAnyPrefix(value, prefixes) {
13
+ return prefixes.some((prefix) => value.startsWith(prefix));
14
+ }
15
+ function resolveServicePrefixedTarget(params) {
16
+ for (const { prefix, service } of params.servicePrefixes) {
17
+ if (!params.lower.startsWith(prefix)) continue;
18
+ const remainder = stripPrefix(params.trimmed, prefix);
19
+ if (!remainder) throw new Error(`${prefix} target is required`);
20
+ const remainderLower = remainder.toLowerCase();
21
+ if (params.isChatTarget(remainderLower)) return params.parseTarget(remainder);
22
+ return {
23
+ kind: "handle",
24
+ to: remainder,
25
+ service
26
+ };
27
+ }
28
+ return null;
29
+ }
30
+ function resolveServicePrefixedChatTarget(params) {
31
+ const chatPrefixes = [
32
+ ...params.chatIdPrefixes,
33
+ ...params.chatGuidPrefixes,
34
+ ...params.chatIdentifierPrefixes,
35
+ ...params.extraChatPrefixes ?? []
36
+ ];
37
+ return resolveServicePrefixedTarget({
38
+ trimmed: params.trimmed,
39
+ lower: params.lower,
40
+ servicePrefixes: params.servicePrefixes,
41
+ isChatTarget: (remainderLower) => startsWithAnyPrefix(remainderLower, chatPrefixes),
42
+ parseTarget: params.parseTarget
43
+ });
44
+ }
45
+ function parseChatTargetPrefixesOrThrow(params) {
46
+ for (const prefix of params.chatIdPrefixes) if (params.lower.startsWith(prefix)) {
47
+ const value = stripPrefix(params.trimmed, prefix);
48
+ const chatId = Number.parseInt(value, 10);
49
+ if (!Number.isFinite(chatId)) throw new Error(`Invalid chat_id: ${value}`);
50
+ return {
51
+ kind: "chat_id",
52
+ chatId
53
+ };
54
+ }
55
+ for (const prefix of params.chatGuidPrefixes) if (params.lower.startsWith(prefix)) {
56
+ const value = stripPrefix(params.trimmed, prefix);
57
+ if (!value) throw new Error("chat_guid is required");
58
+ return {
59
+ kind: "chat_guid",
60
+ chatGuid: value
61
+ };
62
+ }
63
+ for (const prefix of params.chatIdentifierPrefixes) if (params.lower.startsWith(prefix)) {
64
+ const value = stripPrefix(params.trimmed, prefix);
65
+ if (!value) throw new Error("chat_identifier is required");
66
+ return {
67
+ kind: "chat_identifier",
68
+ chatIdentifier: value
69
+ };
70
+ }
71
+ return null;
72
+ }
73
+ function resolveServicePrefixedAllowTarget(params) {
74
+ for (const { prefix } of params.servicePrefixes) {
75
+ if (!params.lower.startsWith(prefix)) continue;
76
+ const remainder = stripPrefix(params.trimmed, prefix);
77
+ if (!remainder) return {
78
+ kind: "handle",
79
+ handle: ""
80
+ };
81
+ return params.parseAllowTarget(remainder);
82
+ }
83
+ return null;
84
+ }
85
+ function resolveServicePrefixedOrChatAllowTarget(params) {
86
+ const servicePrefixed = resolveServicePrefixedAllowTarget({
87
+ trimmed: params.trimmed,
88
+ lower: params.lower,
89
+ servicePrefixes: params.servicePrefixes,
90
+ parseAllowTarget: params.parseAllowTarget
91
+ });
92
+ if (servicePrefixed) return servicePrefixed;
93
+ const chatTarget = parseChatAllowTargetPrefixes({
94
+ trimmed: params.trimmed,
95
+ lower: params.lower,
96
+ chatIdPrefixes: params.chatIdPrefixes,
97
+ chatGuidPrefixes: params.chatGuidPrefixes,
98
+ chatIdentifierPrefixes: params.chatIdentifierPrefixes
99
+ });
100
+ if (chatTarget) return chatTarget;
101
+ return null;
102
+ }
103
+ function createAllowedChatSenderMatcher(params) {
104
+ return (input) => isAllowedParsedChatSender({
105
+ allowFrom: input.allowFrom,
106
+ sender: input.sender,
107
+ chatId: input.chatId,
108
+ chatGuid: input.chatGuid,
109
+ chatIdentifier: input.chatIdentifier,
110
+ normalizeSender: params.normalizeSender,
111
+ parseAllowTarget: params.parseAllowTarget
112
+ });
113
+ }
114
+ function parseChatAllowTargetPrefixes(params) {
115
+ for (const prefix of params.chatIdPrefixes) if (params.lower.startsWith(prefix)) {
116
+ const value = stripPrefix(params.trimmed, prefix);
117
+ const chatId = Number.parseInt(value, 10);
118
+ if (Number.isFinite(chatId)) return {
119
+ kind: "chat_id",
120
+ chatId
121
+ };
122
+ }
123
+ for (const prefix of params.chatGuidPrefixes) if (params.lower.startsWith(prefix)) {
124
+ const value = stripPrefix(params.trimmed, prefix);
125
+ if (value) return {
126
+ kind: "chat_guid",
127
+ chatGuid: value
128
+ };
129
+ }
130
+ for (const prefix of params.chatIdentifierPrefixes) if (params.lower.startsWith(prefix)) {
131
+ const value = stripPrefix(params.trimmed, prefix);
132
+ if (value) return {
133
+ kind: "chat_identifier",
134
+ chatIdentifier: value
135
+ };
136
+ }
137
+ return null;
138
+ }
139
+ //#endregion
140
+ //#region src/imessage/targets.ts
141
+ const CHAT_ID_PREFIXES = [
142
+ "chat_id:",
143
+ "chatid:",
144
+ "chat:"
145
+ ];
146
+ const CHAT_GUID_PREFIXES = [
147
+ "chat_guid:",
148
+ "chatguid:",
149
+ "guid:"
150
+ ];
151
+ const CHAT_IDENTIFIER_PREFIXES = [
152
+ "chat_identifier:",
153
+ "chatidentifier:",
154
+ "chatident:"
155
+ ];
156
+ const SERVICE_PREFIXES = [
157
+ {
158
+ prefix: "imessage:",
159
+ service: "imessage"
160
+ },
161
+ {
162
+ prefix: "sms:",
163
+ service: "sms"
164
+ },
165
+ {
166
+ prefix: "auto:",
167
+ service: "auto"
168
+ }
169
+ ];
170
+ function normalizeIMessageHandle(raw) {
171
+ const trimmed = raw.trim();
172
+ if (!trimmed) return "";
173
+ const lowered = trimmed.toLowerCase();
174
+ if (lowered.startsWith("imessage:")) return normalizeIMessageHandle(trimmed.slice(9));
175
+ if (lowered.startsWith("sms:")) return normalizeIMessageHandle(trimmed.slice(4));
176
+ if (lowered.startsWith("auto:")) return normalizeIMessageHandle(trimmed.slice(5));
177
+ for (const prefix of CHAT_ID_PREFIXES) if (lowered.startsWith(prefix)) return `chat_id:${trimmed.slice(prefix.length).trim()}`;
178
+ for (const prefix of CHAT_GUID_PREFIXES) if (lowered.startsWith(prefix)) return `chat_guid:${trimmed.slice(prefix.length).trim()}`;
179
+ for (const prefix of CHAT_IDENTIFIER_PREFIXES) if (lowered.startsWith(prefix)) return `chat_identifier:${trimmed.slice(prefix.length).trim()}`;
180
+ if (trimmed.includes("@")) return trimmed.toLowerCase();
181
+ const normalized = normalizeE164(trimmed);
182
+ if (normalized) return normalized;
183
+ return trimmed.replace(/\s+/g, "");
184
+ }
185
+ function parseIMessageTarget(raw) {
186
+ const trimmed = raw.trim();
187
+ if (!trimmed) throw new Error("iMessage target is required");
188
+ const lower = trimmed.toLowerCase();
189
+ const servicePrefixed = resolveServicePrefixedChatTarget({
190
+ trimmed,
191
+ lower,
192
+ servicePrefixes: SERVICE_PREFIXES,
193
+ chatIdPrefixes: CHAT_ID_PREFIXES,
194
+ chatGuidPrefixes: CHAT_GUID_PREFIXES,
195
+ chatIdentifierPrefixes: CHAT_IDENTIFIER_PREFIXES,
196
+ parseTarget: parseIMessageTarget
197
+ });
198
+ if (servicePrefixed) return servicePrefixed;
199
+ const chatTarget = parseChatTargetPrefixesOrThrow({
200
+ trimmed,
201
+ lower,
202
+ chatIdPrefixes: CHAT_ID_PREFIXES,
203
+ chatGuidPrefixes: CHAT_GUID_PREFIXES,
204
+ chatIdentifierPrefixes: CHAT_IDENTIFIER_PREFIXES
205
+ });
206
+ if (chatTarget) return chatTarget;
207
+ return {
208
+ kind: "handle",
209
+ to: trimmed,
210
+ service: "auto"
211
+ };
212
+ }
213
+ function parseIMessageAllowTarget(raw) {
214
+ const trimmed = raw.trim();
215
+ if (!trimmed) return {
216
+ kind: "handle",
217
+ handle: ""
218
+ };
219
+ const servicePrefixed = resolveServicePrefixedOrChatAllowTarget({
220
+ trimmed,
221
+ lower: trimmed.toLowerCase(),
222
+ servicePrefixes: SERVICE_PREFIXES,
223
+ parseAllowTarget: parseIMessageAllowTarget,
224
+ chatIdPrefixes: CHAT_ID_PREFIXES,
225
+ chatGuidPrefixes: CHAT_GUID_PREFIXES,
226
+ chatIdentifierPrefixes: CHAT_IDENTIFIER_PREFIXES
227
+ });
228
+ if (servicePrefixed) return servicePrefixed;
229
+ return {
230
+ kind: "handle",
231
+ handle: normalizeIMessageHandle(trimmed)
232
+ };
233
+ }
234
+ const isAllowedIMessageSenderMatcher = createAllowedChatSenderMatcher({
235
+ normalizeSender: normalizeIMessageHandle,
236
+ parseAllowTarget: parseIMessageAllowTarget
237
+ });
238
+ function isAllowedIMessageSender(params) {
239
+ return isAllowedIMessageSenderMatcher(params);
240
+ }
241
+ function formatIMessageChatTarget(chatId) {
242
+ if (!chatId || !Number.isFinite(chatId)) return "";
243
+ return `chat_id:${chatId}`;
244
+ }
245
+ //#endregion
246
+ //#region src/imessage/constants.ts
247
+ /** Default timeout for iMessage probe/RPC operations (10 seconds). */
248
+ const DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS = 1e4;
249
+ //#endregion
250
+ //#region src/imessage/client.ts
251
+ function isTestEnv() {
252
+ const vitest = process.env.VITEST?.trim().toLowerCase();
253
+ return Boolean(vitest);
254
+ }
255
+ var IMessageRpcClient = class {
256
+ constructor(opts = {}) {
257
+ this.pending = /* @__PURE__ */ new Map();
258
+ this.closedResolve = null;
259
+ this.child = null;
260
+ this.reader = null;
261
+ this.nextId = 1;
262
+ this.cliPath = opts.cliPath?.trim() || "imsg";
263
+ this.dbPath = opts.dbPath?.trim() ? resolveUserPath(opts.dbPath) : void 0;
264
+ this.runtime = opts.runtime;
265
+ this.onNotification = opts.onNotification;
266
+ this.closed = new Promise((resolve) => {
267
+ this.closedResolve = resolve;
268
+ });
269
+ }
270
+ async start() {
271
+ if (this.child) return;
272
+ if (isTestEnv()) throw new Error("Refusing to start imsg rpc in test environment; mock iMessage RPC client");
273
+ const args = ["rpc"];
274
+ if (this.dbPath) args.push("--db", this.dbPath);
275
+ const child = spawn(this.cliPath, args, { stdio: [
276
+ "pipe",
277
+ "pipe",
278
+ "pipe"
279
+ ] });
280
+ this.child = child;
281
+ this.reader = createInterface({ input: child.stdout });
282
+ this.reader.on("line", (line) => {
283
+ const trimmed = line.trim();
284
+ if (!trimmed) return;
285
+ this.handleLine(trimmed);
286
+ });
287
+ child.stderr?.on("data", (chunk) => {
288
+ const lines = chunk.toString().split(/\r?\n/);
289
+ for (const line of lines) {
290
+ if (!line.trim()) continue;
291
+ this.runtime?.error?.(`imsg rpc: ${line.trim()}`);
292
+ }
293
+ });
294
+ child.on("error", (err) => {
295
+ this.failAll(err instanceof Error ? err : new Error(String(err)));
296
+ this.closedResolve?.();
297
+ });
298
+ child.on("close", (code, signal) => {
299
+ if (code !== 0 && code !== null) {
300
+ const reason = signal ? `signal ${signal}` : `code ${code}`;
301
+ this.failAll(/* @__PURE__ */ new Error(`imsg rpc exited (${reason})`));
302
+ } else this.failAll(/* @__PURE__ */ new Error("imsg rpc closed"));
303
+ this.closedResolve?.();
304
+ });
305
+ }
306
+ async stop() {
307
+ if (!this.child) return;
308
+ this.reader?.close();
309
+ this.reader = null;
310
+ this.child.stdin?.end();
311
+ const child = this.child;
312
+ this.child = null;
313
+ await Promise.race([this.closed, new Promise((resolve) => {
314
+ setTimeout(() => {
315
+ if (!child.killed) child.kill("SIGTERM");
316
+ resolve();
317
+ }, 500);
318
+ })]);
319
+ }
320
+ async waitForClose() {
321
+ await this.closed;
322
+ }
323
+ async request(method, params, opts) {
324
+ if (!this.child || !this.child.stdin) throw new Error("imsg rpc not running");
325
+ const id = this.nextId++;
326
+ const payload = {
327
+ jsonrpc: "2.0",
328
+ id,
329
+ method,
330
+ params: params ?? {}
331
+ };
332
+ const line = `${JSON.stringify(payload)}\n`;
333
+ const timeoutMs = opts?.timeoutMs ?? 1e4;
334
+ const response = new Promise((resolve, reject) => {
335
+ const key = String(id);
336
+ const timer = timeoutMs > 0 ? setTimeout(() => {
337
+ this.pending.delete(key);
338
+ reject(/* @__PURE__ */ new Error(`imsg rpc timeout (${method})`));
339
+ }, timeoutMs) : void 0;
340
+ this.pending.set(key, {
341
+ resolve: (value) => resolve(value),
342
+ reject,
343
+ timer
344
+ });
345
+ });
346
+ this.child.stdin.write(line);
347
+ return await response;
348
+ }
349
+ handleLine(line) {
350
+ let parsed;
351
+ try {
352
+ parsed = JSON.parse(line);
353
+ } catch (err) {
354
+ const detail = err instanceof Error ? err.message : String(err);
355
+ this.runtime?.error?.(`imsg rpc: failed to parse ${line}: ${detail}`);
356
+ return;
357
+ }
358
+ if (parsed.id !== void 0 && parsed.id !== null) {
359
+ const key = String(parsed.id);
360
+ const pending = this.pending.get(key);
361
+ if (!pending) return;
362
+ if (pending.timer) clearTimeout(pending.timer);
363
+ this.pending.delete(key);
364
+ if (parsed.error) {
365
+ const baseMessage = parsed.error.message ?? "imsg rpc error";
366
+ const details = parsed.error.data;
367
+ const code = parsed.error.code;
368
+ const suffixes = [];
369
+ if (typeof code === "number") suffixes.push(`code=${code}`);
370
+ if (details !== void 0) {
371
+ const detailText = typeof details === "string" ? details : JSON.stringify(details, null, 2);
372
+ if (detailText) suffixes.push(detailText);
373
+ }
374
+ const msg = suffixes.length > 0 ? `${baseMessage}: ${suffixes.join(" ")}` : baseMessage;
375
+ pending.reject(new Error(msg));
376
+ return;
377
+ }
378
+ pending.resolve(parsed.result);
379
+ return;
380
+ }
381
+ if (parsed.method) this.onNotification?.({
382
+ method: parsed.method,
383
+ params: parsed.params
384
+ });
385
+ }
386
+ failAll(err) {
387
+ for (const [key, pending] of this.pending.entries()) {
388
+ if (pending.timer) clearTimeout(pending.timer);
389
+ pending.reject(err);
390
+ this.pending.delete(key);
391
+ }
392
+ }
393
+ };
394
+ async function createIMessageRpcClient(opts = {}) {
395
+ const client = new IMessageRpcClient(opts);
396
+ await client.start();
397
+ return client;
398
+ }
399
+ //#endregion
400
+ //#region src/imessage/send.ts
401
+ const LEADING_REPLY_TAG_RE = /^\s*\[\[\s*reply_to\s*:\s*([^\]\n]+)\s*\]\]\s*/i;
402
+ const MAX_REPLY_TO_ID_LENGTH = 256;
403
+ function stripUnsafeReplyTagChars(value) {
404
+ let next = "";
405
+ for (const ch of value) {
406
+ const code = ch.charCodeAt(0);
407
+ if (code >= 0 && code <= 31 || code === 127 || ch === "[" || ch === "]") continue;
408
+ next += ch;
409
+ }
410
+ return next;
411
+ }
412
+ function sanitizeReplyToId(rawReplyToId) {
413
+ const trimmed = rawReplyToId?.trim();
414
+ if (!trimmed) return;
415
+ const sanitized = stripUnsafeReplyTagChars(trimmed).trim();
416
+ if (!sanitized) return;
417
+ if (sanitized.length > MAX_REPLY_TO_ID_LENGTH) return sanitized.slice(0, MAX_REPLY_TO_ID_LENGTH);
418
+ return sanitized;
419
+ }
420
+ function prependReplyTagIfNeeded(message, replyToId) {
421
+ const resolvedReplyToId = sanitizeReplyToId(replyToId);
422
+ if (!resolvedReplyToId) return message;
423
+ const replyTag = `[[reply_to:${resolvedReplyToId}]]`;
424
+ const existingLeadingTag = message.match(LEADING_REPLY_TAG_RE);
425
+ if (existingLeadingTag) {
426
+ const remainder = message.slice(existingLeadingTag[0].length).trimStart();
427
+ return remainder ? `${replyTag} ${remainder}` : replyTag;
428
+ }
429
+ const trimmedMessage = message.trimStart();
430
+ return trimmedMessage ? `${replyTag} ${trimmedMessage}` : replyTag;
431
+ }
432
+ function resolveMessageId(result) {
433
+ if (!result) return null;
434
+ const raw = typeof result.messageId === "string" && result.messageId.trim() || typeof result.message_id === "string" && result.message_id.trim() || typeof result.id === "string" && result.id.trim() || typeof result.guid === "string" && result.guid.trim() || (typeof result.message_id === "number" ? String(result.message_id) : null) || (typeof result.id === "number" ? String(result.id) : null);
435
+ return raw ? String(raw).trim() : null;
436
+ }
437
+ async function sendMessageIMessage(to, text, opts = {}) {
438
+ const cfg = opts.config ?? loadConfig();
439
+ const account = opts.account ?? resolveIMessageAccount({
440
+ cfg,
441
+ accountId: opts.accountId
442
+ });
443
+ const cliPath = opts.cliPath?.trim() || account.config.cliPath?.trim() || "imsg";
444
+ const dbPath = opts.dbPath?.trim() || account.config.dbPath?.trim();
445
+ const target = parseIMessageTarget(opts.chatId ? formatIMessageChatTarget(opts.chatId) : to);
446
+ const service = opts.service ?? (target.kind === "handle" ? target.service : void 0) ?? account.config.service;
447
+ const region = opts.region?.trim() || account.config.region?.trim() || "US";
448
+ const maxBytes = typeof opts.maxBytes === "number" ? opts.maxBytes : typeof account.config.mediaMaxMb === "number" ? account.config.mediaMaxMb * 1024 * 1024 : 16 * 1024 * 1024;
449
+ let message = text ?? "";
450
+ let filePath;
451
+ if (opts.mediaUrl?.trim()) {
452
+ const resolved = await (opts.resolveAttachmentImpl ?? resolveOutboundAttachmentFromUrl)(opts.mediaUrl.trim(), maxBytes, { localRoots: opts.mediaLocalRoots });
453
+ filePath = resolved.path;
454
+ if (!message.trim()) {
455
+ const kind = kindFromMime(resolved.contentType ?? void 0);
456
+ if (kind) message = kind === "image" ? "<media:image>" : `<media:${kind}>`;
457
+ }
458
+ }
459
+ if (!message.trim() && !filePath) throw new Error("iMessage send requires text or media");
460
+ if (message.trim()) {
461
+ const tableMode = resolveMarkdownTableMode({
462
+ cfg,
463
+ channel: "imessage",
464
+ accountId: account.accountId
465
+ });
466
+ message = convertMarkdownTables(message, tableMode);
467
+ }
468
+ message = prependReplyTagIfNeeded(message, opts.replyToId);
469
+ const params = {
470
+ text: message,
471
+ service: service || "auto",
472
+ region
473
+ };
474
+ if (filePath) params.file = filePath;
475
+ if (target.kind === "chat_id") params.chat_id = target.chatId;
476
+ else if (target.kind === "chat_guid") params.chat_guid = target.chatGuid;
477
+ else if (target.kind === "chat_identifier") params.chat_identifier = target.chatIdentifier;
478
+ else params.to = target.to;
479
+ const client = opts.client ?? (opts.createClient ? await opts.createClient({
480
+ cliPath,
481
+ dbPath
482
+ }) : await createIMessageRpcClient({
483
+ cliPath,
484
+ dbPath
485
+ }));
486
+ const shouldClose = !opts.client;
487
+ try {
488
+ const result = await client.request("send", params, { timeoutMs: opts.timeoutMs });
489
+ return { messageId: resolveMessageId(result) ?? (result?.ok ? "ok" : "unknown") };
490
+ } finally {
491
+ if (shouldClose) await client.stop();
492
+ }
493
+ }
494
+ //#endregion
495
+ export { isAllowedIMessageSender as a, createAllowedChatSenderMatcher as c, resolveServicePrefixedAllowTarget as d, resolveServicePrefixedChatTarget as f, formatIMessageChatTarget as i, parseChatAllowTargetPrefixes as l, resolveServicePrefixedTarget as m, createIMessageRpcClient as n, normalizeIMessageHandle as o, resolveServicePrefixedOrChatAllowTarget as p, DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS as r, parseIMessageTarget as s, sendMessageIMessage as t, parseChatTargetPrefixesOrThrow as u };