spectrum-ts 1.1.2 → 1.2.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License Copyright (c) 2025 Photon AI
2
+
3
+ Permission is hereby granted,
4
+ free of charge, to any person obtaining a copy of this software and associated
5
+ documentation files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use, copy, modify, merge,
7
+ publish, distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice
12
+ (including the next paragraph) shall be included in all copies or substantial
13
+ portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
16
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
18
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ <div align="center">
2
+ <h1>Spectrum</h1>
3
+ <p><strong>Bring agents to any interface.</strong></p>
4
+ <p>
5
+ <a href="https://www.npmjs.com/package/spectrum-ts"><img src="https://img.shields.io/npm/v/spectrum-ts.svg?style=flat&colorA=1a1a1a&colorB=3178c6" alt="npm version" /></a>
6
+ <a href="https://www.npmjs.com/package/spectrum-ts"><img src="https://img.shields.io/npm/dm/spectrum-ts.svg?style=flat&colorA=1a1a1a&colorB=3178c6" alt="npm downloads" /></a>
7
+ <a href="https://github.com/photon-hq/spectrum-ts/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/spectrum-ts.svg?style=flat&colorA=1a1a1a&colorB=3178c6" alt="license" /></a>
8
+ <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5+-3178c6?style=flat&colorA=1a1a1a&colorB=3178c6" alt="TypeScript" /></a>
9
+ <a href="https://github.com/photon-hq/spectrum-ts/stargazers"><img src="https://img.shields.io/github/stars/photon-hq/spectrum-ts.svg?style=flat&colorA=1a1a1a&colorB=3178c6" alt="github stars" /></a>
10
+ </p>
11
+ </div>
12
+
13
+ Spectrum is a unified messaging SDK for TypeScript. Write your agent logic once and deliver it across every messaging platform — iMessage, WhatsApp, terminal, or your own — through one fully type-safe interface.
14
+
15
+ ## Getting Started
16
+
17
+ The fastest way to ship is with **Spectrum Cloud** — hosted infrastructure for platforms like iMessage, with credentials ready in minutes.
18
+
19
+ 1. Sign up at **[app.photon.codes](https://app.photon.codes)** to get your project ID and secret.
20
+ 2. Install the SDK:
21
+
22
+ ```bash
23
+ bun add spectrum-ts
24
+ ```
25
+
26
+ 3. Start your app:
27
+
28
+ ```typescript
29
+ import { Spectrum } from "spectrum-ts";
30
+ import { imessage } from "spectrum-ts/providers/imessage";
31
+
32
+ const app = await Spectrum({
33
+ projectId: process.env.PROJECT_ID,
34
+ projectSecret: process.env.PROJECT_SECRET,
35
+ providers: [imessage.config()],
36
+ });
37
+
38
+ for await (const [space, message] of app.messages) {
39
+ await space.responding(async () => {
40
+ await message.reply("Hello from Spectrum.");
41
+ });
42
+ }
43
+ ```
44
+
45
+ Spectrum also runs fully standalone — you can connect to a local iMessage database, bring your own gRPC endpoints, or build your own platform provider. See the [docs](https://docs.photon.codes) for self-hosted setups.
46
+
47
+ ## Documentation
48
+
49
+ Visit **[docs.photon.codes](https://docs.photon.codes)** to view the full documentation.
50
+
51
+ ## Platforms
52
+
53
+ | Platform | Package |
54
+ |----------|---------|
55
+ | iMessage | `spectrum-ts/providers/imessage` |
56
+ | WhatsApp | `spectrum-ts/providers/whatsapp` |
57
+ | Terminal | `spectrum-ts/providers/terminal` |
58
+ | Custom | `definePlatform` from `spectrum-ts` |
59
+
60
+ ## Issues
61
+
62
+ Found a bug or have a feature request? Please [open an issue](https://github.com/photon-hq/spectrum-ts/issues) on GitHub. Before filing, search existing issues to avoid duplicates.
63
+
64
+ ## Contributing
65
+
66
+ Contributions are welcome. Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
67
+
68
+ ## License
69
+
70
+ [MIT](./LICENSE) © [Photon](https://photon.codes)
@@ -2,7 +2,7 @@ import {
2
2
  bufferToStream,
3
3
  readSchema,
4
4
  streamSchema
5
- } from "./chunk-5GQ2OMFY.js";
5
+ } from "./chunk-UQPIWAHH.js";
6
6
 
7
7
  // src/content/voice.ts
8
8
  import { createReadStream } from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  readSchema,
4
4
  resolveContents,
5
5
  streamSchema
6
- } from "./chunk-5GQ2OMFY.js";
6
+ } from "./chunk-UQPIWAHH.js";
7
7
 
8
8
  // src/content/group.ts
9
9
  import z from "zod";
@@ -658,6 +658,43 @@ var warnUnsupported = (err, fallbackPlatform) => {
658
658
  supportsAnsiColor() ? `${ANSI_YELLOW}${body}${ANSI_RESET}` : body
659
659
  );
660
660
  };
661
+ var contentPlatform = (content) => {
662
+ const platform = content.__platform;
663
+ return typeof platform === "string" ? platform : void 0;
664
+ };
665
+ var findUnsupportedPlatformContent = (content, platform) => {
666
+ const scopedPlatform = contentPlatform(content);
667
+ if (scopedPlatform && scopedPlatform !== platform) {
668
+ return scopedPlatform;
669
+ }
670
+ if (content.type !== "group") {
671
+ return;
672
+ }
673
+ for (const item of content.items) {
674
+ const nested = item.content;
675
+ if (typeof nested !== "object" || nested === null || !("type" in nested)) {
676
+ continue;
677
+ }
678
+ const unsupported = findUnsupportedPlatformContent(
679
+ nested,
680
+ platform
681
+ );
682
+ if (unsupported) {
683
+ return unsupported;
684
+ }
685
+ }
686
+ };
687
+ var unsupportedPlatformContentError = (content, platform) => {
688
+ const requiredPlatform = findUnsupportedPlatformContent(content, platform);
689
+ if (!requiredPlatform) {
690
+ return;
691
+ }
692
+ return UnsupportedError.content(
693
+ content.type,
694
+ platform,
695
+ `requires ${requiredPlatform}`
696
+ );
697
+ };
661
698
  var providerMessageCoreKeys = /* @__PURE__ */ new Set([
662
699
  "content",
663
700
  "id",
@@ -751,6 +788,13 @@ function buildSpace(params) {
751
788
  async function dispatchSend(item) {
752
789
  let raw;
753
790
  try {
791
+ const platformError = unsupportedPlatformContentError(
792
+ item,
793
+ definition.name
794
+ );
795
+ if (platformError) {
796
+ throw platformError;
797
+ }
754
798
  raw = await definition.actions.send({
755
799
  ...typingCtx,
756
800
  content: item
@@ -892,6 +936,13 @@ function buildMessage(params) {
892
936
  const dispatchReplyItem = async (item, target, replyToMessage) => {
893
937
  let raw;
894
938
  try {
939
+ const platformError = unsupportedPlatformContentError(
940
+ item,
941
+ definition.name
942
+ );
943
+ if (platformError) {
944
+ throw platformError;
945
+ }
895
946
  raw = await replyToMessage({
896
947
  space: spaceRef,
897
948
  messageId: params.id,
@@ -963,6 +1014,14 @@ function buildMessage(params) {
963
1014
  if (!resolved) {
964
1015
  return;
965
1016
  }
1017
+ const platformError = unsupportedPlatformContentError(
1018
+ resolved,
1019
+ definition.name
1020
+ );
1021
+ if (platformError) {
1022
+ warnUnsupported(platformError, definition.name);
1023
+ return;
1024
+ }
966
1025
  try {
967
1026
  await definition.actions.editMessage({
968
1027
  space: spaceRef,
@@ -1183,6 +1242,18 @@ function definePlatform(name, def) {
1183
1242
  __definition: fullDef
1184
1243
  };
1185
1244
  };
1245
+ narrower.is = ((input) => {
1246
+ if (typeof input !== "object" || input === null) {
1247
+ return false;
1248
+ }
1249
+ if ("__platform" in input) {
1250
+ return input.__platform === name;
1251
+ }
1252
+ if ("platform" in input) {
1253
+ return input.platform === name;
1254
+ }
1255
+ return false;
1256
+ });
1186
1257
  if (def.static) {
1187
1258
  Object.assign(narrower, def.static);
1188
1259
  }
@@ -1193,6 +1264,7 @@ export {
1193
1264
  readSchema,
1194
1265
  streamSchema,
1195
1266
  bufferToStream,
1267
+ attachmentSchema,
1196
1268
  asAttachment,
1197
1269
  attachment,
1198
1270
  fromVCard,
@@ -1201,6 +1273,7 @@ export {
1201
1273
  contact,
1202
1274
  asCustom,
1203
1275
  custom,
1276
+ textSchema,
1204
1277
  asText,
1205
1278
  text,
1206
1279
  resolveContents,
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ContentBuilder, U as User, M as Message, 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, I as InboundMessage, O as OutboundMessage } from './types-GhOtIIqj.js';
2
- export { A as AnyPlatformDef, B as Broadcaster, E as EventProducer, h as InboundPlatformMessage, i as ManagedStream, j as PlatformInstance, k as PlatformMessage, l as PlatformRuntime, m as PlatformSpace, n as PlatformUser, o as SchemaMessage, p as broadcast, q as mergeStreams, s as stream } from './types-GhOtIIqj.js';
1
+ import { C as ContentBuilder, U as User, M as Message, 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, I as InboundMessage, O as OutboundMessage } from './types-Dvp0I86h.js';
2
+ export { A as AnyPlatformDef, B as Broadcaster, E as EventProducer, h as InboundPlatformMessage, i as ManagedStream, j as PlatformInstance, k as PlatformMessage, l as PlatformRuntime, m as PlatformSpace, n as PlatformUser, o as SchemaMessage, p as broadcast, q as mergeStreams, s as stream } from './types-Dvp0I86h.js';
3
3
  import vCard from 'vcf';
4
4
  import z__default from 'zod';
5
5
  import 'hotscript';
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  group,
3
3
  richlink
4
- } from "./chunk-UWUPCIB4.js";
4
+ } from "./chunk-K3CTEGCZ.js";
5
5
  import {
6
6
  voice
7
- } from "./chunk-QZ5DJ7VR.js";
7
+ } from "./chunk-I7EKZS5C.js";
8
8
  import {
9
9
  SpectrumCloudError,
10
10
  broadcast,
@@ -27,7 +27,7 @@ import {
27
27
  text,
28
28
  toVCard,
29
29
  wrapProviderMessage
30
- } from "./chunk-5GQ2OMFY.js";
30
+ } from "./chunk-UQPIWAHH.js";
31
31
 
32
32
  // src/emoji/generated.ts
33
33
  var GeneratedEmoji = {
@@ -1,11 +1,14 @@
1
- import { o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-GhOtIIqj.js';
1
+ import { a as ContentInput, C as ContentBuilder, o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-Dvp0I86h.js';
2
2
  import * as zod_v4_core from 'zod/v4/core';
3
3
  import * as z from 'zod';
4
4
  import z__default from 'zod';
5
- import { AdvancedIMessage } from '@photon-ai/advanced-imessage';
5
+ import { MessageEffect, AdvancedIMessage } from '@photon-ai/advanced-imessage';
6
6
  import { IMessageSDK } from '@photon-ai/imessage-kit';
7
7
  import 'hotscript';
8
8
 
9
+ type IMessageMessageEffect = MessageEffect;
10
+ declare function effect(input: ContentInput, messageEffect: IMessageMessageEffect): ContentBuilder;
11
+
9
12
  type IMessageClient = IMessageSDK | AdvancedIMessage[];
10
13
  declare const userSchema: z__default.ZodObject<{}, z__default.core.$strip>;
11
14
  declare const spaceSchema: z__default.ZodObject<{
@@ -75,6 +78,24 @@ declare const imessage: Platform<PlatformDef<"iMessage", z.ZodUnion<readonly [z.
75
78
  }[] | undefined;
76
79
  };
77
80
  }) => ManagedStream<IMessageMessage>;
78
- }>> & Readonly<Record<never, never>>;
81
+ }>> & Readonly<{
82
+ effect: {
83
+ message: {
84
+ readonly slam: "com.apple.MobileSMS.expressivesend.impact";
85
+ readonly loud: "com.apple.MobileSMS.expressivesend.loud";
86
+ readonly gentle: "com.apple.MobileSMS.expressivesend.gentle";
87
+ readonly invisible: "com.apple.MobileSMS.expressivesend.invisibleink";
88
+ readonly confetti: "com.apple.messages.effect.CKConfettiEffect";
89
+ readonly fireworks: "com.apple.messages.effect.CKFireworksEffect";
90
+ readonly balloons: "com.apple.messages.effect.CKBalloonEffect";
91
+ readonly heart: "com.apple.messages.effect.CKHeartEffect";
92
+ readonly lasers: "com.apple.messages.effect.CKLasersEffect";
93
+ readonly celebration: "com.apple.messages.effect.CKHappyBirthdayEffect";
94
+ readonly sparkles: "com.apple.messages.effect.CKSparklesEffect";
95
+ readonly spotlight: "com.apple.messages.effect.CKSpotlightEffect";
96
+ readonly echo: "com.apple.messages.effect.CKEchoEffect";
97
+ };
98
+ };
99
+ }>;
79
100
 
80
- export { imessage };
101
+ export { type IMessageMessageEffect, effect, imessage };
@@ -2,7 +2,7 @@ import {
2
2
  asGroup,
3
3
  asRichlink,
4
4
  groupSchema
5
- } from "../../chunk-UWUPCIB4.js";
5
+ } from "../../chunk-K3CTEGCZ.js";
6
6
  import {
7
7
  asPoll,
8
8
  asPollOption,
@@ -16,16 +16,66 @@ import {
16
16
  asContact,
17
17
  asCustom,
18
18
  asText,
19
+ attachmentSchema,
19
20
  definePlatform,
20
21
  fromVCard,
21
22
  reactionSchema,
23
+ text,
24
+ textSchema,
22
25
  toVCard
23
- } from "../../chunk-5GQ2OMFY.js";
26
+ } from "../../chunk-UQPIWAHH.js";
24
27
 
25
28
  // src/providers/imessage/index.ts
26
- import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
29
+ import {
30
+ createClient as createClient2,
31
+ directChat,
32
+ MessageEffect as MessageEffect2
33
+ } from "@photon-ai/advanced-imessage";
27
34
  import { IMessageSDK as IMessageSDK2 } from "@photon-ai/imessage-kit";
28
35
 
36
+ // src/providers/imessage/content/effect.ts
37
+ import {
38
+ MessageEffect
39
+ } from "@photon-ai/advanced-imessage";
40
+
41
+ // src/content/effect.ts
42
+ import z from "zod";
43
+ var effectInnerSchema = z.discriminatedUnion("type", [
44
+ textSchema,
45
+ attachmentSchema
46
+ ]);
47
+ var messageEffectSchema = z.object({
48
+ type: z.literal("effect"),
49
+ content: effectInnerSchema,
50
+ effect: z.string().nonempty()
51
+ });
52
+
53
+ // src/providers/imessage/content/effect.ts
54
+ var SUPPORTED_EFFECTS = new Set(Object.values(MessageEffect));
55
+ var resolveContent = (input) => typeof input === "string" ? text(input).build() : input.build();
56
+ function effect(input, messageEffect) {
57
+ return {
58
+ build: async () => {
59
+ if (!SUPPORTED_EFFECTS.has(messageEffect)) {
60
+ throw new Error(
61
+ `Unsupported iMessage message effect "${messageEffect}"`
62
+ );
63
+ }
64
+ const inner = await resolveContent(input);
65
+ if (inner.type !== "text" && inner.type !== "attachment") {
66
+ throw new Error(
67
+ `imessage effect() only supports text and attachment content, got "${inner.type}"`
68
+ );
69
+ }
70
+ return messageEffectSchema.parse({
71
+ type: "effect",
72
+ content: inner,
73
+ effect: messageEffect
74
+ });
75
+ }
76
+ };
77
+ }
78
+
29
79
  // src/providers/imessage/auth.ts
30
80
  import {
31
81
  createClient
@@ -230,7 +280,7 @@ import { basename, join } from "path";
230
280
  var IMESSAGE_PLATFORM = "iMessage";
231
281
  var LOCAL_IMESSAGE_PLATFORM = "iMessage (local mode)";
232
282
  var unsupportedRemoteContent = (type, detail) => UnsupportedError.content(type, IMESSAGE_PLATFORM, detail);
233
- var unsupportedLocalContent = (type) => UnsupportedError.content(type, LOCAL_IMESSAGE_PLATFORM);
283
+ var unsupportedLocalContent = (type, detail) => UnsupportedError.content(type, LOCAL_IMESSAGE_PLATFORM, detail);
234
284
 
235
285
  // src/providers/imessage/local/send.ts
236
286
  var synthRecord = (spaceId, content) => ({
@@ -269,6 +319,11 @@ var send = async (client, spaceId, content) => {
269
319
  );
270
320
  return synthRecord(spaceId, content);
271
321
  }
322
+ case "effect":
323
+ throw unsupportedLocalContent(
324
+ "effect",
325
+ "message effects require remote iMessage"
326
+ );
272
327
  case "poll":
273
328
  throw unsupportedLocalContent("poll");
274
329
  default:
@@ -564,11 +619,11 @@ var rebuildFromAppleMessage = async (client, message, chatGuidHint) => {
564
619
  if (getBalloonBundleId(message) === URL_BALLOON_BUNDLE_ID) {
565
620
  return toRichlinkMessage(message, base, messageGuidStr);
566
621
  }
567
- const text = message.text;
622
+ const text2 = message.text;
568
623
  return {
569
624
  ...base,
570
625
  id: messageGuidStr,
571
- content: text ? asText(text) : asCustom(message)
626
+ content: text2 ? asText(text2) : asCustom(message)
572
627
  };
573
628
  };
574
629
  var cacheMessage = (cache, message) => {
@@ -630,11 +685,11 @@ var toInboundMessages = async (client, cache, event) => {
630
685
  cacheMessage(cache, parent);
631
686
  return [parent];
632
687
  }
633
- const text = event.message.text;
688
+ const text2 = event.message.text;
634
689
  const msg = {
635
690
  ...base,
636
691
  id: messageGuidStr,
637
- content: text ? asText(text) : asCustom(event.message)
692
+ content: text2 ? asText(text2) : asCustom(event.message)
638
693
  };
639
694
  cacheMessage(cache, msg);
640
695
  return [msg];
@@ -879,9 +934,9 @@ var runFfmpeg = (ffmpegPath, args) => {
879
934
  );
880
935
  proc.on("exit", (code) => resolve(code ?? -1));
881
936
  });
882
- return Promise.all([exit, stderr]).then(([code, text]) => ({
937
+ return Promise.all([exit, stderr]).then(([code, text2]) => ({
883
938
  code,
884
- stderr: text
939
+ stderr: text2
885
940
  }));
886
941
  };
887
942
  var DURATION_PATTERN = /Duration:\s*(\d+):(\d{2}):(\d{2})(?:\.(\d{1,3}))?/;
@@ -961,6 +1016,7 @@ var outboundRecord = (spaceId, id, content, timestamp, extras) => ({
961
1016
  });
962
1017
  var withReply = (options, replyTo) => replyTo ? { ...options, replyTo } : options;
963
1018
  var replyOptions = (replyTo) => replyTo ? { replyTo } : void 0;
1019
+ var effectOption = (effect2) => effect2 ? { effect: effect2 } : {};
964
1020
  var sendVCardAttachment = (remote, name, vcf) => remote.attachments.upload({
965
1021
  data: Buffer.from(vcf, "utf8"),
966
1022
  fileName: name,
@@ -990,13 +1046,22 @@ var uploadVoice = async (remote, content) => {
990
1046
  });
991
1047
  return { guid: attachment.guid, name };
992
1048
  };
993
- var sendContent = async (remote, spaceId, chat, content, replyTo) => {
1049
+ var sendContent = async (remote, spaceId, chat, content, replyTo, effect2) => {
994
1050
  switch (content.type) {
1051
+ case "effect":
1052
+ return sendContent(
1053
+ remote,
1054
+ spaceId,
1055
+ chat,
1056
+ content.content,
1057
+ replyTo,
1058
+ content.effect
1059
+ );
995
1060
  case "text": {
996
1061
  const receipt = await remote.messages.send(
997
1062
  chat,
998
1063
  content.text,
999
- withReply({}, replyTo)
1064
+ withReply(effectOption(effect2), replyTo)
1000
1065
  );
1001
1066
  return outboundRecord(
1002
1067
  spaceId,
@@ -1022,6 +1087,7 @@ var sendContent = async (remote, spaceId, chat, content, replyTo) => {
1022
1087
  const { guid } = await uploadAttachment(remote, content);
1023
1088
  const receipt = await remote.messages.send(chat, "", {
1024
1089
  attachment: guid,
1090
+ ...effectOption(effect2),
1025
1091
  ...replyOptions(replyTo)
1026
1092
  });
1027
1093
  return outboundRecord(
@@ -1762,30 +1828,35 @@ var getMessage4 = async (clients, spaceId, msgId) => {
1762
1828
 
1763
1829
  // src/providers/imessage/types.ts
1764
1830
  import { IMessageSDK } from "@photon-ai/imessage-kit";
1765
- import z from "zod";
1831
+ import z2 from "zod";
1766
1832
  var isLocal = (client) => client instanceof IMessageSDK;
1767
- var clientEntry = z.object({ address: z.string(), token: z.string() });
1768
- var configSchema = z.union([
1769
- z.object({ local: z.literal(true) }),
1770
- z.object({
1771
- local: z.literal(false).optional().default(false),
1772
- clients: clientEntry.or(z.array(clientEntry)).optional()
1833
+ var clientEntry = z2.object({ address: z2.string(), token: z2.string() });
1834
+ var configSchema = z2.union([
1835
+ z2.object({ local: z2.literal(true) }),
1836
+ z2.object({
1837
+ local: z2.literal(false).optional().default(false),
1838
+ clients: clientEntry.or(z2.array(clientEntry)).optional()
1773
1839
  })
1774
1840
  ]);
1775
- var userSchema = z.object({});
1776
- var spaceSchema = z.object({
1777
- id: z.string(),
1778
- type: z.enum(["dm", "group"])
1841
+ var userSchema = z2.object({});
1842
+ var spaceSchema = z2.object({
1843
+ id: z2.string(),
1844
+ type: z2.enum(["dm", "group"])
1779
1845
  });
1780
- var messageSchema = z.object({
1781
- partIndex: z.number().int().nonnegative().optional(),
1782
- parentId: z.string().optional()
1846
+ var messageSchema = z2.object({
1847
+ partIndex: z2.number().int().nonnegative().optional(),
1848
+ parentId: z2.string().optional()
1783
1849
  });
1784
1850
 
1785
1851
  // src/providers/imessage/index.ts
1786
1852
  var isPollContent = (content) => content.type === "poll" || content.type === "poll_option";
1787
1853
  var imessage = definePlatform("iMessage", {
1788
1854
  config: configSchema,
1855
+ static: {
1856
+ effect: {
1857
+ message: MessageEffect2
1858
+ }
1859
+ },
1789
1860
  user: {
1790
1861
  resolve: async ({ input }) => ({ id: input.userID })
1791
1862
  },
@@ -1919,5 +1990,6 @@ var imessage = definePlatform("iMessage", {
1919
1990
  }
1920
1991
  });
1921
1992
  export {
1993
+ effect,
1922
1994
  imessage
1923
1995
  };
@@ -1,4 +1,4 @@
1
- import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-GhOtIIqj.js';
1
+ import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-Dvp0I86h.js';
2
2
  import z__default from 'zod';
3
3
  import 'hotscript';
4
4
 
@@ -42,9 +42,6 @@ declare const terminal: Platform<PlatformDef<"terminal", z__default.ZodObject<{
42
42
  content: {
43
43
  type: "text";
44
44
  text: string;
45
- } | {
46
- type: "custom";
47
- raw: unknown;
48
45
  } | {
49
46
  type: "attachment";
50
47
  name: string;
@@ -52,6 +49,9 @@ declare const terminal: Platform<PlatformDef<"terminal", z__default.ZodObject<{
52
49
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
53
50
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
54
51
  size?: number | undefined;
52
+ } | {
53
+ type: "custom";
54
+ raw: unknown;
55
55
  } | {
56
56
  type: "contact";
57
57
  user?: {
@@ -140,6 +140,20 @@ declare const terminal: Platform<PlatformDef<"terminal", z__default.ZodObject<{
140
140
  };
141
141
  selected: boolean;
142
142
  title: string;
143
+ } | {
144
+ type: "effect";
145
+ content: {
146
+ type: "text";
147
+ text: string;
148
+ } | {
149
+ type: "attachment";
150
+ name: string;
151
+ mimeType: string;
152
+ read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
153
+ stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
154
+ size?: number | undefined;
155
+ };
156
+ effect: string;
143
157
  };
144
158
  sender: {
145
159
  id: string;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  asVoice
3
- } from "../../chunk-QZ5DJ7VR.js";
3
+ } from "../../chunk-I7EKZS5C.js";
4
4
  import {
5
5
  UnsupportedError,
6
6
  asAttachment,
@@ -10,7 +10,7 @@ import {
10
10
  fromVCard,
11
11
  reactionSchema,
12
12
  toVCard
13
- } from "../../chunk-5GQ2OMFY.js";
13
+ } from "../../chunk-UQPIWAHH.js";
14
14
 
15
15
  // src/providers/terminal/index.ts
16
16
  import { spawn } from "child_process";
@@ -1,4 +1,4 @@
1
- import { o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-GhOtIIqj.js';
1
+ import { o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-Dvp0I86h.js';
2
2
  import { WhatsAppClient } from '@photon-ai/whatsapp-business';
3
3
  import * as z from 'zod';
4
4
  import z__default from 'zod';
@@ -12,7 +12,7 @@ import {
12
12
  asReaction,
13
13
  asText,
14
14
  definePlatform
15
- } from "../../chunk-5GQ2OMFY.js";
15
+ } from "../../chunk-UQPIWAHH.js";
16
16
 
17
17
  // src/providers/whatsapp-business/index.ts
18
18
  import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
@@ -115,6 +115,20 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
115
115
  }, z__default.core.$strip>;
116
116
  selected: z__default.ZodBoolean;
117
117
  title: z__default.ZodString;
118
+ }, z__default.core.$strip>, z__default.ZodObject<{
119
+ type: z__default.ZodLiteral<"effect">;
120
+ content: z__default.ZodDiscriminatedUnion<[z__default.ZodObject<{
121
+ type: z__default.ZodLiteral<"text">;
122
+ text: z__default.ZodString;
123
+ }, z__default.core.$strip>, z__default.ZodObject<{
124
+ type: z__default.ZodLiteral<"attachment">;
125
+ name: z__default.ZodString;
126
+ mimeType: z__default.ZodString;
127
+ size: z__default.ZodOptional<z__default.ZodNumber>;
128
+ read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
129
+ stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
130
+ }, z__default.core.$strip>], "type">;
131
+ effect: z__default.ZodString;
118
132
  }, z__default.core.$strip>], "type">;
119
133
  type Content = z__default.infer<typeof contentSchema>;
120
134
  interface ContentBuilder {
@@ -427,6 +441,9 @@ interface SpectrumLike<Providers extends PlatformProviderConfig[] = PlatformProv
427
441
  }
428
442
  interface Platform<Def extends AnyPlatformDef> {
429
443
  config(...args: Record<string, never> extends z__default.input<Def["config"]> ? [config?: z__default.input<Def["config"]>] : [config: z__default.input<Def["config"]>]): PlatformProviderConfig<Def>;
444
+ is(input: Message): input is PlatformMessage<Def>;
445
+ is(input: Space): input is PlatformSpace<Def>;
446
+ is(input: unknown): input is PlatformMessage<Def> | PlatformSpace<Def>;
430
447
  <Providers extends PlatformProviderConfig[]>(spectrum: SpectrumLike<Providers>): HasProvider<Providers, Def["name"]> extends true ? PlatformInstance<Def> : never;
431
448
  (space: Space): PlatformSpace<Def>;
432
449
  (message: Message): PlatformMessage<Def>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",