cclawd 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/{active-listener-Dkhmfuwx.js → active-listener-BLd27Pxd.js} +1 -1
  2. package/dist/{api-key-rotation-BOfI3cG3.js → api-key-rotation-Dg3JlNDQ.js} +1 -1
  3. package/dist/{audio-preflight-CtkZ5SAs.js → audio-preflight-eV5m9mMp.js} +6 -6
  4. package/dist/{audio-transcription-runner-CbPqoiHX.js → audio-transcription-runner-CQU4Eg1M.js} +6 -6
  5. package/dist/build-info.json +3 -3
  6. package/dist/bundled/boot-md/handler.js +23 -23
  7. package/dist/bundled/session-memory/handler.js +23 -23
  8. package/dist/{channel-activity-DWAER4wd.js → channel-activity-dT3cYb0e.js} +1 -1
  9. package/dist/{commands-registry-BUyiA7nE.js → commands-registry-CyLMCPuP.js} +1 -1
  10. package/dist/compact.runtime-DGRl4st4.js +39 -0
  11. package/dist/{deliver-aHOaRbkt.js → deliver-B6eTtXSk.js} +4 -4
  12. package/dist/{deliver-runtime-D4bCsr6d.js → deliver-runtime-CLDpY6AW.js} +7 -7
  13. package/dist/{deps-send-discord.runtime-BziKU-pE.js → deps-send-discord.runtime-CxADlame.js} +7 -7
  14. package/dist/{deps-send-imessage.runtime-CFRnDTqp.js → deps-send-imessage.runtime-Wi79xm6H.js} +7 -7
  15. package/dist/{deps-send-signal.runtime-BuOtABJm.js → deps-send-signal.runtime-BDtzvsnR.js} +6 -6
  16. package/dist/{deps-send-slack.runtime-BOLqvMxW.js → deps-send-slack.runtime-CgX24hgT.js} +5 -5
  17. package/dist/{deps-send-telegram.runtime-DeEoFLv5.js → deps-send-telegram.runtime-CEWc7ePn.js} +6 -6
  18. package/dist/deps-send-whatsapp.runtime-B1KJ7YOp.js +43 -0
  19. package/dist/{diagnostic-BdcXX9iJ.js → diagnostic-BZmAxdu9.js} +1 -1
  20. package/dist/{fetch-D9NUULbj.js → fetch-CMLoICyN.js} +2 -2
  21. package/dist/{fetch-guard-B5ZMnGaN.js → fetch-guard-DCj3k042.js} +1 -1
  22. package/dist/{image-4x07m4Jl.js → image-Bt49ybRv.js} +2 -2
  23. package/dist/{image-runtime-smkMrIol.js → image-runtime-Cilhq73U.js} +2 -2
  24. package/dist/{ir-CsgNUpOU.js → ir-CVtBjUiL.js} +2 -2
  25. package/dist/llm-slug-generator.js +23 -23
  26. package/dist/{login-p_O59TVQ.js → login-D0fUoX-p.js} +2 -2
  27. package/dist/{login-qr-BCJpDsAy.js → login-qr-ClBxstxZ.js} +2 -2
  28. package/dist/{manager-CwYv8O3T.js → manager-DSfEj66R.js} +3 -3
  29. package/dist/{manager-runtime-D_jEoBr9.js → manager-runtime-BrZlGJsj.js} +4 -4
  30. package/dist/{model-selection-Cv2Puf5z.js → model-selection-CMEj8bpy.js} +11 -11
  31. package/dist/{outbound-Chpiwybe.js → outbound-BxIJyMzV.js} +4 -4
  32. package/dist/{outbound-attachment-BnAVJDLe.js → outbound-attachment-CVJwpypG.js} +2 -2
  33. package/dist/{pi-embedded-CJVNBk0y.js → pi-embedded-CHNPEUAv.js} +57 -57
  34. package/dist/{pi-model-discovery-7IzK0Uc3.js → pi-model-discovery-D-r5y7kV.js} +1 -1
  35. package/dist/{pi-model-discovery-runtime-DABef3qy.js → pi-model-discovery-runtime-DZQXYmdu.js} +2 -2
  36. package/dist/{pi-tools.before-tool-call.runtime-BP2UvGJb.js → pi-tools.before-tool-call.runtime-DagGpfw0.js} +2 -2
  37. package/dist/plugin-sdk/compat.js +35 -35
  38. package/dist/{pw-ai-DwH5GpEO.js → pw-ai-CoIUdns_.js} +1 -1
  39. package/dist/{runtime-whatsapp-login.runtime-BI3U306v.js → runtime-whatsapp-login.runtime-ChqE9BkX.js} +3 -3
  40. package/dist/{runtime-whatsapp-outbound.runtime-Bsc2uD09.js → runtime-whatsapp-outbound.runtime-yiy6jzKk.js} +6 -6
  41. package/dist/{send-DtBvCnPQ.js → send-4rRrSKp9.js} +4 -4
  42. package/dist/{send-ORtn50qg.js → send-BKO1-P1t.js} +3 -3
  43. package/dist/{send-C-Q_WPMf.js → send-EDBPXjTT.js} +3 -3
  44. package/dist/{send-DUibfNQD.js → send-K2mAG7KC.js} +4 -4
  45. package/dist/{send-BDnOgWIp.js → send-V1MRV7QF.js} +3 -3
  46. package/dist/{session-B7imi6T5.js → session-CuVCho2m.js} +1 -1
  47. package/dist/{skill-commands-B9brPuiL.js → skill-commands-B55LOaMB.js} +2 -2
  48. package/dist/{slash-commands.runtime-Cf6ygfBp.js → slash-commands.runtime-BchS0VkW.js} +2 -2
  49. package/dist/{slash-dispatch.runtime-CsmvhO5K.js → slash-dispatch.runtime-BIKRY3fr.js} +23 -23
  50. package/dist/{slash-skill-commands.runtime-CX7stIEP.js → slash-skill-commands.runtime-BP4jBHU9.js} +3 -3
  51. package/dist/{subagent-registry-runtime-B_S1nf7y.js → subagent-registry-runtime-DjEYzSyM.js} +23 -23
  52. package/dist/{tables-CjQqTOdD.js → tables-BAGqh2XD.js} +1 -1
  53. package/dist/{target-errors-BZE1mc-W.js → target-errors-CeBF8Pws.js} +1 -1
  54. package/dist/{web-Cd8yK1Zq.js → web-BRSmQdtm.js} +27 -27
  55. package/dist/{whatsapp-actions-CYEzUMBI.js → whatsapp-actions-Dxb2K2Xh.js} +7 -7
  56. package/extensions/mfa-auth/index.ts +3 -3
  57. package/extensions/mfa-auth/src/notification-service.ts +2 -2
  58. package/package.json +458 -458
  59. package/dist/compact.runtime-DpcZpcTl.js +0 -39
  60. package/dist/deps-send-whatsapp.runtime-CG1uXYLY.js +0 -43
  61. package/dist/plugin-sdk/active-listener-CN-tMEvN.js +0 -35
  62. package/dist/plugin-sdk/api-key-rotation-CimGYMBc.js +0 -176
  63. package/dist/plugin-sdk/audio-preflight-C-xXBoE2.js +0 -51
  64. package/dist/plugin-sdk/audio-transcription-runner-CTIHpebA.js +0 -2173
  65. package/dist/plugin-sdk/audit-membership-runtime-BFatB2LJ.js +0 -58
  66. package/dist/plugin-sdk/channel-activity-DO0FEzyj.js +0 -95
  67. package/dist/plugin-sdk/channel-web-Da-__nUF.js +0 -2238
  68. package/dist/plugin-sdk/commands-registry-6no2NNrY.js +0 -1118
  69. package/dist/plugin-sdk/compact.runtime-CCoclu5e.js +0 -35
  70. package/dist/plugin-sdk/config-B9ODwgpz.js +0 -37426
  71. package/dist/plugin-sdk/deliver-B1fFpKjV.js +0 -1757
  72. package/dist/plugin-sdk/deliver-runtime-DB-VRMe1.js +0 -15
  73. package/dist/plugin-sdk/deps-send-discord.runtime-DklqycYG.js +0 -15
  74. package/dist/plugin-sdk/deps-send-imessage.runtime-Chs8zeon.js +0 -14
  75. package/dist/plugin-sdk/deps-send-signal.runtime-clW9aSJP.js +0 -13
  76. package/dist/plugin-sdk/deps-send-slack.runtime-BUx0LYY1.js +0 -13
  77. package/dist/plugin-sdk/deps-send-telegram.runtime-LECSHgMG.js +0 -16
  78. package/dist/plugin-sdk/deps-send-whatsapp.runtime-D2d65fw0.js +0 -40
  79. package/dist/plugin-sdk/diagnostic-CxIvS-C2.js +0 -315
  80. package/dist/plugin-sdk/dispatch-BqlR4dPx.js +0 -105863
  81. package/dist/plugin-sdk/env-b9k1PHMI.js +0 -34
  82. package/dist/plugin-sdk/fetch-PoxzAANT.js +0 -326
  83. package/dist/plugin-sdk/fetch-guard-4UVSZ0uS.js +0 -164
  84. package/dist/plugin-sdk/image-Ch6M4tnJ.js +0 -2420
  85. package/dist/plugin-sdk/image-runtime-CSh2o5wY.js +0 -8
  86. package/dist/plugin-sdk/ir-CugsqGH8.js +0 -1312
  87. package/dist/plugin-sdk/local-roots-adnEg9zb.js +0 -217
  88. package/dist/plugin-sdk/logger-D6zRubj0.js +0 -1164
  89. package/dist/plugin-sdk/login-CYvkQ0At.js +0 -54
  90. package/dist/plugin-sdk/login-qr-ll4NtaT5.js +0 -316
  91. package/dist/plugin-sdk/manager-CHy8IclH.js +0 -3959
  92. package/dist/plugin-sdk/manager-runtime-C70EkEr7.js +0 -11
  93. package/dist/plugin-sdk/outbound-Wzs2iN7X.js +0 -216
  94. package/dist/plugin-sdk/outbound-attachment-khXJwucX.js +0 -17
  95. package/dist/plugin-sdk/paths-BtVqCdw4.js +0 -3063
  96. package/dist/plugin-sdk/pi-model-discovery-Dh4ziodY.js +0 -131
  97. package/dist/plugin-sdk/pi-model-discovery-runtime-b83Xe-HT.js +0 -8
  98. package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-C1z5CDBF.js +0 -349
  99. package/dist/plugin-sdk/proxy-fetch-CJEmoBxi.js +0 -54
  100. package/dist/plugin-sdk/pw-ai-Dj3Cvlzl.js +0 -1990
  101. package/dist/plugin-sdk/qmd-manager-egHUAseQ.js +0 -1581
  102. package/dist/plugin-sdk/resolve-outbound-target-BiICvIKs.js +0 -38
  103. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-DNApufzW.js +0 -9
  104. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-CBmtfIQ8.js +0 -13
  105. package/dist/plugin-sdk/send-CScblaI4.js +0 -532
  106. package/dist/plugin-sdk/send-CeHhnld6.js +0 -407
  107. package/dist/plugin-sdk/send-DP_c8JfR.js +0 -3277
  108. package/dist/plugin-sdk/send-Dc5fI6e8.js +0 -495
  109. package/dist/plugin-sdk/send-l-77_s1_.js +0 -2507
  110. package/dist/plugin-sdk/session-CkOKZaqa.js +0 -166
  111. package/dist/plugin-sdk/skill-commands-BohYCgkq.js +0 -336
  112. package/dist/plugin-sdk/slash-commands.runtime-DpLfVTM6.js +0 -8
  113. package/dist/plugin-sdk/slash-dispatch.runtime-CASMHwpm.js +0 -35
  114. package/dist/plugin-sdk/slash-skill-commands.runtime-D7rrJEci.js +0 -9
  115. package/dist/plugin-sdk/sqlite-CJE3X7Mv.js +0 -1005
  116. package/dist/plugin-sdk/subagent-registry-runtime-B1oo5bih.js +0 -35
  117. package/dist/plugin-sdk/tables-D5VgpTmm.js +0 -53
  118. package/dist/plugin-sdk/target-errors-C6zZ_OpA.js +0 -191
  119. package/dist/plugin-sdk/tokens-DUnJnpMS.js +0 -50
  120. package/dist/plugin-sdk/web-TfUM1nSi.js +0 -39
  121. package/dist/plugin-sdk/whatsapp-actions-DuWJ0j1r.js +0 -71
@@ -1,495 +0,0 @@
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 };