spectrum-ts 0.2.2 → 0.4.0

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.
@@ -0,0 +1,165 @@
1
+ // src/content/attachment.ts
2
+ import { createReadStream } from "fs";
3
+ import { readFile, stat } from "fs/promises";
4
+ import { basename } from "path";
5
+ import { Readable } from "stream";
6
+ import { lookup as lookupMimeType } from "mime-types";
7
+ import z from "zod";
8
+ var DEFAULT_ATTACHMENT_NAME = "attachment";
9
+ var readSchema = z.function({
10
+ input: [],
11
+ output: z.promise(z.instanceof(Buffer))
12
+ });
13
+ var streamSchema = z.function({
14
+ input: [],
15
+ output: z.promise(z.instanceof(ReadableStream))
16
+ });
17
+ var attachmentSchema = z.object({
18
+ type: z.literal("attachment"),
19
+ name: z.string().nonempty(),
20
+ mimeType: z.string().nonempty(),
21
+ size: z.number().int().nonnegative().optional(),
22
+ read: readSchema,
23
+ stream: streamSchema
24
+ });
25
+ var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
26
+ var resolveAttachmentMimeType = (name, mimeType) => {
27
+ if (mimeType) {
28
+ return mimeType;
29
+ }
30
+ const resolvedMimeType = lookupMimeType(name);
31
+ if (!resolvedMimeType) {
32
+ throw new Error(
33
+ `Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
34
+ );
35
+ }
36
+ return resolvedMimeType;
37
+ };
38
+ var bufferToStream = (buf) => new ReadableStream({
39
+ start(controller) {
40
+ controller.enqueue(buf);
41
+ controller.close();
42
+ }
43
+ });
44
+ var asAttachment = (input) => {
45
+ let cached;
46
+ const read = () => {
47
+ cached ??= input.read().catch((err) => {
48
+ cached = void 0;
49
+ throw err;
50
+ });
51
+ return cached;
52
+ };
53
+ const stream2 = input.stream ?? (async () => bufferToStream(await read()));
54
+ return attachmentSchema.parse({
55
+ type: "attachment",
56
+ name: input.name,
57
+ mimeType: input.mimeType,
58
+ size: input.size,
59
+ read,
60
+ stream: stream2
61
+ });
62
+ };
63
+ function attachment(input, options) {
64
+ return {
65
+ build: async () => {
66
+ const name = resolveAttachmentName(input, options?.name);
67
+ const mimeType = resolveAttachmentMimeType(name, options?.mimeType);
68
+ if (typeof input === "string") {
69
+ const stats = await stat(input);
70
+ return asAttachment({
71
+ name,
72
+ mimeType,
73
+ size: stats.size,
74
+ read: () => readFile(input),
75
+ stream: async () => Readable.toWeb(
76
+ createReadStream(input)
77
+ )
78
+ });
79
+ }
80
+ return asAttachment({
81
+ name,
82
+ mimeType,
83
+ size: input.byteLength,
84
+ read: async () => input,
85
+ stream: async () => bufferToStream(input)
86
+ });
87
+ }
88
+ };
89
+ }
90
+
91
+ // src/content/custom.ts
92
+ import z2 from "zod";
93
+ var customSchema = z2.object({
94
+ type: z2.literal("custom"),
95
+ raw: z2.unknown()
96
+ });
97
+ var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
98
+ function custom(raw) {
99
+ return {
100
+ build: async () => asCustom(raw)
101
+ };
102
+ }
103
+
104
+ // src/utils/stream.ts
105
+ import { Repeater } from "@repeaterjs/repeater";
106
+ function stream(setup) {
107
+ const repeater = new Repeater(async (push, stop) => {
108
+ const emit = (value) => {
109
+ Promise.resolve(push(value)).catch((error) => {
110
+ stop(error);
111
+ return void 0;
112
+ });
113
+ };
114
+ const end = (error) => {
115
+ stop(error);
116
+ };
117
+ const cleanup = await setup(emit, end);
118
+ try {
119
+ await stop;
120
+ } finally {
121
+ await cleanup?.();
122
+ }
123
+ });
124
+ return Object.assign(repeater, {
125
+ close: async () => {
126
+ await repeater.return(void 0);
127
+ }
128
+ });
129
+ }
130
+ function mergeStreams(streams) {
131
+ return stream((emit, end) => {
132
+ if (streams.length === 0) {
133
+ end();
134
+ return;
135
+ }
136
+ let openStreams = streams.length;
137
+ const workers = streams.map(async (source) => {
138
+ try {
139
+ for await (const value of source) {
140
+ emit(value);
141
+ }
142
+ } catch (error) {
143
+ end(error);
144
+ } finally {
145
+ openStreams -= 1;
146
+ if (openStreams === 0) {
147
+ end();
148
+ }
149
+ }
150
+ });
151
+ return async () => {
152
+ await Promise.allSettled(streams.map((source) => source.close()));
153
+ await Promise.allSettled(workers);
154
+ };
155
+ });
156
+ }
157
+
158
+ export {
159
+ asAttachment,
160
+ attachment,
161
+ asCustom,
162
+ custom,
163
+ stream,
164
+ mergeStreams
165
+ };
@@ -1,3 +1,21 @@
1
+ // src/content/text.ts
2
+ import z from "zod";
3
+ var textSchema = z.object({
4
+ type: z.literal("text"),
5
+ text: z.string().nonempty()
6
+ });
7
+ var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
8
+ function text(text2) {
9
+ return {
10
+ build: async () => asText(text2)
11
+ };
12
+ }
13
+
14
+ // src/content/resolve.ts
15
+ var resolveContents = (items) => Promise.all(
16
+ items.map((c) => typeof c === "string" ? text(c).build() : c.build())
17
+ );
18
+
1
19
  // src/platform/define.ts
2
20
  function createPlatformInstance(def, runtime) {
3
21
  const isPlatformUser = (value) => {
@@ -69,11 +87,13 @@ function createPlatformInstance(def, runtime) {
69
87
  ...parsedSpace,
70
88
  ...spaceRef,
71
89
  send: async (...content) => {
72
- const built = await Promise.all(content.map((c) => c.build()));
73
- await def.actions.send({
74
- ...typingCtx,
75
- content: built
76
- });
90
+ const built = await resolveContents(content);
91
+ for (const item of built) {
92
+ await def.actions.send({
93
+ ...typingCtx,
94
+ content: item
95
+ });
96
+ }
77
97
  },
78
98
  startTyping: async () => {
79
99
  await def.actions.startTyping?.(typingCtx);
@@ -172,5 +192,8 @@ function definePlatform(name, def) {
172
192
  }
173
193
 
174
194
  export {
195
+ asText,
196
+ text,
197
+ resolveContents,
175
198
  definePlatform
176
199
  };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,20 @@
1
+ import { C as ContentBuilder, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space, M as Message } from './types-BdWMydUJ.js';
2
+ export { A as AnyPlatformDef, E as EventProducer, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage, U as User } from './types-BdWMydUJ.js';
1
3
  import z__default from 'zod';
2
- import { P as ProviderMessage, a as PlatformDef, b as Platform, c as PlatformProviderConfig, S as SpectrumLike, C as CustomEventStreams, d as Space, M as Message, e as ContentBuilder } from './types-DPrSH21Q.js';
3
- export { A as AnyPlatformDef, f as Content, E as EventProducer, g as PlatformInstance, h as PlatformMessage, i as PlatformSpace, j as PlatformUser, k as SchemaMessage, U as User, l as attachment, m as custom, t as text } from './types-DPrSH21Q.js';
4
4
  export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-DGy4geUK.js';
5
5
  import 'hotscript';
6
6
 
7
+ declare function attachment(input: string | Buffer, options?: {
8
+ mimeType?: string;
9
+ name?: string;
10
+ }): ContentBuilder;
11
+
12
+ declare function custom(raw: unknown): ContentBuilder;
13
+
14
+ declare const resolveContents: (items: readonly ContentInput[]) => Promise<Content[]>;
15
+
16
+ declare function text(text: string): ContentBuilder;
17
+
7
18
  declare function definePlatform<_Name extends string, _ConfigSchema extends z__default.ZodType<object>, _UserSchema extends z__default.ZodType<object> | undefined, _SpaceSchema extends z__default.ZodType<object> | undefined, _SpaceParamsSchema extends z__default.ZodType<object> | undefined, _Client, _ResolvedUser extends {
8
19
  id: string;
9
20
  }, _ResolvedSpace extends {
@@ -25,7 +36,7 @@ declare function definePlatform<_Name extends string, _ConfigSchema extends z__d
25
36
  type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> = SpectrumLike<Providers> & CustomEventStreams<Providers> & {
26
37
  readonly messages: AsyncIterable<[Space, Message]>;
27
38
  stop(): Promise<void>;
28
- send(space: Space, ...content: [ContentBuilder, ...ContentBuilder[]]): Promise<void>;
39
+ send(space: Space, ...content: [ContentInput, ...ContentInput[]]): Promise<void>;
29
40
  responding<T>(space: Space, fn: () => T | Promise<T>): Promise<T>;
30
41
  };
31
42
  declare function Spectrum<const Providers extends PlatformProviderConfig[]>(options: {
@@ -75,4 +86,4 @@ declare const cloud: {
75
86
  togglePlatform: (projectId: string, projectSecret: string, platform: CloudPlatform, enabled: boolean) => Promise<PlatformsData>;
76
87
  };
77
88
 
78
- export { type CloudPlatform, ContentBuilder, type DedicatedTokenData, type ImessageInfoData, Message, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type SharedTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, cloud, definePlatform };
89
+ export { type CloudPlatform, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type ImessageInfoData, Message, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type SharedTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, attachment, cloud, custom, definePlatform, resolveContents, text };
package/dist/index.js CHANGED
@@ -3,12 +3,16 @@ import {
3
3
  cloud
4
4
  } from "./chunk-HXM64ENV.js";
5
5
  import {
6
+ attachment,
7
+ custom,
6
8
  mergeStreams,
7
9
  stream
8
- } from "./chunk-3TBRO2J7.js";
10
+ } from "./chunk-5XW4CAWS.js";
9
11
  import {
10
- definePlatform
11
- } from "./chunk-LIRM7SBA.js";
12
+ definePlatform,
13
+ resolveContents,
14
+ text
15
+ } from "./chunk-XEEDIGVK.js";
12
16
 
13
17
  // src/spectrum.ts
14
18
  import z from "zod";
@@ -93,11 +97,13 @@ async function Spectrum(options) {
93
97
  const space = {
94
98
  ...spaceRef,
95
99
  send: async (...content) => {
96
- const resolved = await Promise.all(content.map((c) => c.build()));
97
- await definition.actions.send({
98
- ...typingCtx,
99
- content: resolved
100
- });
100
+ const resolved = await resolveContents(content);
101
+ for (const item of resolved) {
102
+ await definition.actions.send({
103
+ ...typingCtx,
104
+ content: item
105
+ });
106
+ }
101
107
  },
102
108
  startTyping: async () => {
103
109
  await definition.actions.startTyping?.(typingCtx);
@@ -136,14 +142,16 @@ async function Spectrum(options) {
136
142
  if (!definition.actions.replyToMessage) {
137
143
  return;
138
144
  }
139
- const resolved = await Promise.all(content.map((c) => c.build()));
140
- await definition.actions.replyToMessage({
141
- space: spaceRef,
142
- messageId: msg.id,
143
- content: resolved,
144
- client,
145
- config
146
- });
145
+ const resolved = await resolveContents(content);
146
+ for (const item of resolved) {
147
+ await definition.actions.replyToMessage({
148
+ space: spaceRef,
149
+ messageId: msg.id,
150
+ content: item,
151
+ client,
152
+ config
153
+ });
154
+ }
147
155
  },
148
156
  sender: {
149
157
  ...msg.sender,
@@ -281,66 +289,6 @@ async function Spectrum(options) {
281
289
  }
282
290
  });
283
291
  }
284
-
285
- // src/types/content.ts
286
- import { readFile } from "fs/promises";
287
- import { basename } from "path";
288
- import { lookup as lookupMimeType } from "mime-types";
289
- import z2 from "zod";
290
- var DEFAULT_ATTACHMENT_NAME = "attachment";
291
- var contentSchema = z2.discriminatedUnion("type", [
292
- z2.object({
293
- type: z2.literal("plain_text"),
294
- text: z2.string().nonempty()
295
- }),
296
- z2.object({
297
- type: z2.literal("custom"),
298
- raw: z2.json()
299
- }),
300
- z2.object({
301
- type: z2.literal("attachment"),
302
- data: z2.instanceof(Buffer),
303
- mimeType: z2.string().nonempty(),
304
- name: z2.string().nonempty()
305
- })
306
- ]);
307
- function text(text2) {
308
- return {
309
- build: () => Promise.resolve({ type: "plain_text", text: text2 })
310
- };
311
- }
312
- function custom(raw) {
313
- return {
314
- build: () => Promise.resolve({ type: "custom", raw })
315
- };
316
- }
317
- var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
318
- var resolveAttachmentMimeType = (name, mimeType) => {
319
- if (mimeType) {
320
- return mimeType;
321
- }
322
- const resolvedMimeType = lookupMimeType(name);
323
- if (!resolvedMimeType) {
324
- throw new Error(
325
- `Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
326
- );
327
- }
328
- return resolvedMimeType;
329
- };
330
- function attachment(input, options) {
331
- return {
332
- build: async () => {
333
- const data = typeof input === "string" ? await readFile(input) : input;
334
- const name = resolveAttachmentName(input, options?.name);
335
- return {
336
- data,
337
- mimeType: resolveAttachmentMimeType(name, options?.mimeType),
338
- name,
339
- type: "attachment"
340
- };
341
- }
342
- };
343
- }
344
292
  export {
345
293
  Spectrum,
346
294
  SpectrumCloudError,
@@ -349,6 +297,7 @@ export {
349
297
  custom,
350
298
  definePlatform,
351
299
  mergeStreams,
300
+ resolveContents,
352
301
  stream,
353
302
  text
354
303
  };
@@ -3,7 +3,7 @@ import { AdvancedIMessage } from '@photon-ai/advanced-imessage';
3
3
  import { IMessageSDK } from '@photon-ai/imessage-kit';
4
4
  import * as z from 'zod';
5
5
  import z__default from 'zod';
6
- import { k as SchemaMessage, b as Platform, a as PlatformDef, P as ProviderMessage } from '../../types-DPrSH21Q.js';
6
+ import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-BdWMydUJ.js';
7
7
  import * as zod_v4_core from 'zod/v4/core';
8
8
  import 'hotscript';
9
9
 
@@ -2,12 +2,15 @@ import {
2
2
  cloud
3
3
  } from "../../chunk-HXM64ENV.js";
4
4
  import {
5
+ asAttachment,
6
+ asCustom,
5
7
  mergeStreams,
6
8
  stream
7
- } from "../../chunk-3TBRO2J7.js";
9
+ } from "../../chunk-5XW4CAWS.js";
8
10
  import {
11
+ asText,
9
12
  definePlatform
10
- } from "../../chunk-LIRM7SBA.js";
13
+ } from "../../chunk-XEEDIGVK.js";
11
14
 
12
15
  // src/providers/imessage/index.ts
13
16
  import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
@@ -100,36 +103,75 @@ async function disposeCloudAuth(clients) {
100
103
  }
101
104
 
102
105
  // src/providers/imessage/local.ts
106
+ import { createReadStream } from "fs";
103
107
  import { unlink, writeFile } from "fs/promises";
104
108
  import { tmpdir } from "os";
105
109
  import { join } from "path";
110
+ import { Readable } from "stream";
111
+ import {
112
+ readAttachmentBytes
113
+ } from "@photon-ai/imessage-kit";
114
+ var DEFAULT_ATTACHMENT_NAME = "attachment";
106
115
  var toSpace = (message) => ({
107
- id: `${message.isGroupChat ? "any;+;" : "any;-;"}${message.chatId}`,
108
- type: message.isGroupChat ? "group" : "dm"
109
- });
110
- var toMessage = (message) => ({
111
- id: message.guid,
112
- content: [{ type: "plain_text", text: message.text ?? "" }],
113
- sender: { id: message.sender ?? "" },
114
- space: toSpace(message),
115
- timestamp: message.date ?? /* @__PURE__ */ new Date()
116
+ id: message.chatId,
117
+ type: message.chatKind === "group" ? "group" : "dm"
116
118
  });
117
- var messages = (client) => stream((emit) => {
119
+ var toMessages = (message) => {
120
+ const base = {
121
+ sender: { id: message.participant ?? "" },
122
+ space: toSpace(message),
123
+ timestamp: message.createdAt
124
+ };
125
+ if (message.attachments.length > 0) {
126
+ return message.attachments.map((att) => {
127
+ const { localPath } = att;
128
+ return {
129
+ ...base,
130
+ id: `${message.id}:${att.id}`,
131
+ content: asAttachment({
132
+ name: att.fileName ?? DEFAULT_ATTACHMENT_NAME,
133
+ mimeType: att.mimeType,
134
+ size: att.sizeBytes,
135
+ read: () => readAttachmentBytes(att),
136
+ stream: localPath ? async () => Readable.toWeb(
137
+ createReadStream(localPath)
138
+ ) : void 0
139
+ })
140
+ };
141
+ });
142
+ }
143
+ return [
144
+ {
145
+ ...base,
146
+ id: message.id,
147
+ content: { type: "text", text: message.text ?? "" }
148
+ }
149
+ ];
150
+ };
151
+ var messages = (client) => stream((emit, end) => {
118
152
  client.startWatching({
119
- onMessage: (message) => emit(toMessage(message))
153
+ onMessage: (message) => {
154
+ try {
155
+ for (const m of toMessages(message)) {
156
+ emit(m);
157
+ }
158
+ } catch (error) {
159
+ end(error);
160
+ }
161
+ }
120
162
  });
121
163
  return () => client.stopWatching();
122
164
  });
123
165
  var send = async (client, spaceId, content) => {
124
166
  switch (content.type) {
125
- case "plain_text":
167
+ case "text":
126
168
  await client.send(spaceId, content.text);
127
169
  break;
128
170
  case "attachment": {
129
171
  const tmp = join(tmpdir(), `spectrum-${Date.now()}-${content.name}`);
130
- await writeFile(tmp, content.data);
172
+ await writeFile(tmp, await content.read());
131
173
  try {
132
- await client.send(spaceId, { files: [tmp] });
174
+ await client.send(spaceId, { attachments: [tmp] });
133
175
  } finally {
134
176
  await unlink(tmp).catch(() => {
135
177
  });
@@ -150,9 +192,7 @@ import {
150
192
  var TAPBACK_NAMES = new Set(
151
193
  Object.values(Reaction).filter((r) => r !== "emoji" && r !== "sticker")
152
194
  );
153
- var toMessage2 = (event) => ({
154
- id: event.message.guid,
155
- content: [{ type: "plain_text", text: event.message.text ?? "" }],
195
+ var baseMessage = (event) => ({
156
196
  sender: { id: event.message.sender?.address ?? "" },
157
197
  space: {
158
198
  id: event.chatGuid,
@@ -160,13 +200,40 @@ var toMessage2 = (event) => ({
160
200
  },
161
201
  timestamp: event.timestamp
162
202
  });
203
+ var toMessages2 = (client, event) => {
204
+ const base = baseMessage(event);
205
+ const messageGuidStr = event.message.guid;
206
+ if (event.message.attachments.length > 0) {
207
+ return event.message.attachments.map((info) => ({
208
+ ...base,
209
+ id: `${messageGuidStr}:${info.guid}`,
210
+ content: asAttachment({
211
+ name: info.fileName,
212
+ mimeType: info.mimeType,
213
+ size: info.totalBytes,
214
+ read: async () => Buffer.from(await client.attachments.downloadBuffer(info.guid)),
215
+ stream: async () => client.attachments.download(info.guid).stream
216
+ })
217
+ }));
218
+ }
219
+ const text = event.message.text;
220
+ return [
221
+ {
222
+ ...base,
223
+ id: messageGuidStr,
224
+ content: text ? asText(text) : asCustom(event.message)
225
+ }
226
+ ];
227
+ };
163
228
  var clientStream = (client) => {
164
229
  const sub = client.messages.subscribe("message.received");
165
230
  return stream((emit, end) => {
166
231
  (async () => {
167
232
  try {
168
233
  for await (const event of sub) {
169
- emit(toMessage2(event));
234
+ for (const message of toMessages2(client, event)) {
235
+ emit(message);
236
+ }
170
237
  }
171
238
  end();
172
239
  } catch (e) {
@@ -197,12 +264,12 @@ var send2 = async (clients, spaceId, content) => {
197
264
  return;
198
265
  }
199
266
  switch (content.type) {
200
- case "plain_text":
267
+ case "text":
201
268
  await remote.messages.send(chatGuid(spaceId), content.text);
202
269
  break;
203
270
  case "attachment": {
204
271
  const attachment = await remote.attachments.upload({
205
- data: content.data,
272
+ data: await content.read(),
206
273
  fileName: content.name,
207
274
  mimeType: content.mimeType
208
275
  });
@@ -212,7 +279,7 @@ var send2 = async (clients, spaceId, content) => {
212
279
  break;
213
280
  }
214
281
  default:
215
- break;
282
+ throw new Error(`Unsupported iMessage content type: ${content.type}`);
216
283
  }
217
284
  };
218
285
  var replyToMessage = async (clients, spaceId, msgId, content) => {
@@ -223,12 +290,12 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
223
290
  const chat = chatGuid(spaceId);
224
291
  const replyTo = messageGuid(msgId);
225
292
  switch (content.type) {
226
- case "plain_text":
293
+ case "text":
227
294
  await remote.messages.send(chat, content.text, { replyTo });
228
295
  break;
229
296
  case "attachment": {
230
297
  const attachment = await remote.attachments.upload({
231
- data: content.data,
298
+ data: await content.read(),
232
299
  fileName: content.name,
233
300
  mimeType: content.mimeType
234
301
  });
@@ -239,7 +306,7 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
239
306
  break;
240
307
  }
241
308
  default:
242
- break;
309
+ throw new Error(`Unsupported iMessage content type: ${content.type}`);
243
310
  }
244
311
  };
245
312
  var reactToMessage = async (clients, spaceId, msgId, reaction) => {
@@ -352,12 +419,10 @@ var imessage = definePlatform("iMessage", {
352
419
  },
353
420
  actions: {
354
421
  send: async ({ space, content, client }) => {
355
- for (const item of content) {
356
- if (isLocal(client)) {
357
- await send(client, space.id, item);
358
- } else {
359
- await send2(client, space.id, item);
360
- }
422
+ if (isLocal(client)) {
423
+ await send(client, space.id, content);
424
+ } else {
425
+ await send2(client, space.id, content);
361
426
  }
362
427
  },
363
428
  startTyping: async ({ space, client }) => {
@@ -382,9 +447,7 @@ var imessage = definePlatform("iMessage", {
382
447
  if (isLocal(client)) {
383
448
  return;
384
449
  }
385
- for (const item of content) {
386
- await replyToMessage(client, space.id, messageId, item);
387
- }
450
+ await replyToMessage(client, space.id, messageId, content);
388
451
  }
389
452
  }
390
453
  });
@@ -1,4 +1,4 @@
1
- import { b as Platform, a as PlatformDef, P as ProviderMessage } from '../../types-DPrSH21Q.js';
1
+ import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-BdWMydUJ.js';
2
2
  import * as node_readline from 'node:readline';
3
3
  import z__default from 'zod';
4
4
  import 'hotscript';
@@ -18,9 +18,9 @@ declare const terminal: Platform<PlatformDef<"terminal", z__default.ZodObject<{}
18
18
  }): AsyncGenerator<{
19
19
  id: `${string}-${string}-${string}-${string}-${string}`;
20
20
  content: {
21
- type: "plain_text";
21
+ type: "text";
22
22
  text: string;
23
- }[];
23
+ };
24
24
  sender: {
25
25
  id: string;
26
26
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  definePlatform
3
- } from "../../chunk-LIRM7SBA.js";
3
+ } from "../../chunk-XEEDIGVK.js";
4
4
 
5
5
  // src/providers/terminal/index.ts
6
6
  import { createInterface } from "readline";
@@ -39,7 +39,7 @@ var terminal = definePlatform("terminal", {
39
39
  for await (const line of client) {
40
40
  yield {
41
41
  id: crypto.randomUUID(),
42
- content: [{ type: "plain_text", text: line }],
42
+ content: { type: "text", text: line },
43
43
  sender: { id: "terminal-user" },
44
44
  space: { id: "terminal" },
45
45
  timestamp: /* @__PURE__ */ new Date()
@@ -49,9 +49,8 @@ var terminal = definePlatform("terminal", {
49
49
  },
50
50
  actions: {
51
51
  send: async ({ content }) => {
52
- const outputs = content.filter((c) => c.type === "plain_text").map((c) => c.text);
53
- for (const output of outputs) {
54
- console.log(output);
52
+ if (content.type === "text") {
53
+ console.log(content.text);
55
54
  }
56
55
  }
57
56
  }
@@ -1,7 +1,7 @@
1
1
  import { M as ManagedStream } from '../../stream-DGy4geUK.js';
2
2
  import * as z from 'zod';
3
3
  import z__default from 'zod';
4
- import { k as SchemaMessage, b as Platform, a as PlatformDef, P as ProviderMessage } from '../../types-DPrSH21Q.js';
4
+ import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-BdWMydUJ.js';
5
5
  import * as zod_v4_core from 'zod/v4/core';
6
6
  import { WhatsAppClient } from '@photon-ai/whatsapp-business';
7
7
  import 'hotscript';