spectrum-ts 1.14.0 → 1.15.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.
@@ -3,7 +3,7 @@ import {
3
3
  fetchUrlBytes,
4
4
  readSchema,
5
5
  streamSchema
6
- } from "./chunk-JTS25BT3.js";
6
+ } from "./chunk-YFCDKZ6W.js";
7
7
 
8
8
  // src/content/voice.ts
9
9
  import { createReadStream } from "fs";
@@ -2,7 +2,7 @@ import {
2
2
  asGroup,
3
3
  asRichlink,
4
4
  groupSchema
5
- } from "./chunk-TOJQ6DPE.js";
5
+ } from "./chunk-JBMQ5GEW.js";
6
6
  import {
7
7
  asPoll,
8
8
  asPollOption
@@ -16,7 +16,7 @@ import {
16
16
  asContact,
17
17
  fromVCard,
18
18
  toVCard
19
- } from "./chunk-YZ226L5Y.js";
19
+ } from "./chunk-J2ANGYYW.js";
20
20
  import {
21
21
  UnsupportedError,
22
22
  asAttachment,
@@ -29,11 +29,12 @@ import {
29
29
  reactionSchema,
30
30
  text,
31
31
  textSchema
32
- } from "./chunk-JTS25BT3.js";
32
+ } from "./chunk-YFCDKZ6W.js";
33
33
 
34
34
  // src/providers/imessage/index.ts
35
35
  import { createClient as createClient2, MessageEffect as MessageEffect2 } from "@photon-ai/advanced-imessage";
36
36
  import { IMessageSDK as IMessageSDK2 } from "@photon-ai/imessage-kit";
37
+ import { withSpan } from "@photon-ai/otel";
37
38
 
38
39
  // src/providers/imessage/content/background.ts
39
40
  import z from "zod";
@@ -322,6 +323,7 @@ var readLocalAttachment = async (att) => {
322
323
  var toAttachmentContent = (att) => {
323
324
  const { localPath } = att;
324
325
  return asAttachment({
326
+ id: att.id,
325
327
  name: att.fileName ?? DEFAULT_ATTACHMENT_NAME,
326
328
  mimeType: att.mimeType,
327
329
  size: att.sizeBytes,
@@ -546,7 +548,7 @@ var setBackground = async (remote, spaceId, content) => {
546
548
 
547
549
  // src/providers/imessage/remote/inbound.ts
548
550
  import {
549
- NotFoundError
551
+ NotFoundError as NotFoundError2
550
552
  } from "@photon-ai/advanced-imessage";
551
553
 
552
554
  // src/providers/imessage/cache.ts
@@ -620,45 +622,10 @@ var getPollCache = (owner) => {
620
622
  return cache;
621
623
  };
622
624
 
623
- // src/providers/imessage/remote/inbound.ts
624
- var URL_BALLOON_BUNDLE_ID = "com.apple.messages.URLBalloonProvider";
625
- var getBalloonBundleId = (message) => message.content.balloonBundleId;
626
- var messageAttachments = (message) => message.content.attachments;
627
- var resolveChatGuid = (message, hint) => {
628
- if (hint) {
629
- return hint;
630
- }
631
- const first = message.chatGuids?.[0];
632
- return first ?? "";
633
- };
634
- var resolveSenderId = (message) => message.sender?.address ?? "";
635
- var isIMessageMessage = (value) => {
636
- if (typeof value !== "object" || value === null) {
637
- return false;
638
- }
639
- const record = value;
640
- return typeof record.id === "string" && record.id.length > 0 && typeof record.content === "object" && record.content !== null && typeof record.sender === "object" && record.sender !== null && typeof record.space === "object" && record.space !== null;
641
- };
642
- var asProviderGroup = (items) => groupSchema.parse({ type: "group", items });
643
- var buildMessageBase = (message, chatGuidHint, timestamp, phone) => {
644
- const chat = resolveChatGuid(message, chatGuidHint);
645
- return {
646
- sender: { id: resolveSenderId(message) },
647
- space: {
648
- id: chat,
649
- type: chat.includes(";+;") ? "group" : "dm",
650
- phone
651
- },
652
- timestamp
653
- };
654
- };
655
- var toAttachmentContent2 = (client, info) => asAttachment({
656
- name: info.fileName,
657
- mimeType: info.mimeType,
658
- size: info.totalBytes,
659
- read: async () => await downloadPrimaryAttachment(client, info.guid),
660
- stream: async () => downloadPrimaryAttachmentStream(client, info.guid)
661
- });
625
+ // src/providers/imessage/remote/attachments.ts
626
+ import {
627
+ NotFoundError
628
+ } from "@photon-ai/advanced-imessage";
662
629
  var downloadPrimaryAttachmentStream = (client, attachmentGuid) => {
663
630
  const frames = client.attachments.downloadStream(attachmentGuid);
664
631
  const iterator = frames[Symbol.asyncIterator]();
@@ -713,6 +680,66 @@ var downloadPrimaryAttachment = async (client, attachmentGuid) => {
713
680
  }
714
681
  return Buffer.concat(chunks);
715
682
  };
683
+ var getRemoteAttachment = async (client, guid) => {
684
+ let info;
685
+ try {
686
+ info = await client.attachments.get(guid);
687
+ } catch (err) {
688
+ if (err instanceof NotFoundError) {
689
+ return;
690
+ }
691
+ throw err;
692
+ }
693
+ return asAttachment({
694
+ id: info.guid,
695
+ name: info.fileName,
696
+ mimeType: info.mimeType,
697
+ size: info.totalBytes,
698
+ read: () => downloadPrimaryAttachment(client, info.guid),
699
+ stream: async () => downloadPrimaryAttachmentStream(client, info.guid)
700
+ });
701
+ };
702
+
703
+ // src/providers/imessage/remote/inbound.ts
704
+ var URL_BALLOON_BUNDLE_ID = "com.apple.messages.URLBalloonProvider";
705
+ var getBalloonBundleId = (message) => message.content.balloonBundleId;
706
+ var messageAttachments = (message) => message.content.attachments;
707
+ var resolveChatGuid = (message, hint) => {
708
+ if (hint) {
709
+ return hint;
710
+ }
711
+ const first = message.chatGuids?.[0];
712
+ return first ?? "";
713
+ };
714
+ var resolveSenderId = (message) => message.sender?.address ?? "";
715
+ var isIMessageMessage = (value) => {
716
+ if (typeof value !== "object" || value === null) {
717
+ return false;
718
+ }
719
+ const record = value;
720
+ return typeof record.id === "string" && record.id.length > 0 && typeof record.content === "object" && record.content !== null && typeof record.sender === "object" && record.sender !== null && typeof record.space === "object" && record.space !== null;
721
+ };
722
+ var asProviderGroup = (items) => groupSchema.parse({ type: "group", items });
723
+ var buildMessageBase = (message, chatGuidHint, timestamp, phone) => {
724
+ const chat = resolveChatGuid(message, chatGuidHint);
725
+ return {
726
+ sender: { id: resolveSenderId(message) },
727
+ space: {
728
+ id: chat,
729
+ type: chat.includes(";+;") ? "group" : "dm",
730
+ phone
731
+ },
732
+ timestamp
733
+ };
734
+ };
735
+ var toAttachmentContent2 = (client, info) => asAttachment({
736
+ id: info.guid,
737
+ name: info.fileName,
738
+ mimeType: info.mimeType,
739
+ size: info.totalBytes,
740
+ read: async () => await downloadPrimaryAttachment(client, info.guid),
741
+ stream: async () => downloadPrimaryAttachmentStream(client, info.guid)
742
+ });
716
743
  var toVCardContent2 = async (client, info) => {
717
744
  try {
718
745
  const buf = await downloadPrimaryAttachment(client, info.guid);
@@ -896,7 +923,7 @@ var getMessage3 = async (remote, spaceId, msgId, phone) => {
896
923
  const item = parent.content.items[childRef.partIndex];
897
924
  return isIMessageMessage(item) ? item : void 0;
898
925
  } catch (err) {
899
- if (err instanceof NotFoundError) {
926
+ if (err instanceof NotFoundError2) {
900
927
  return;
901
928
  }
902
929
  throw err;
@@ -916,7 +943,7 @@ var getMessage3 = async (remote, spaceId, msgId, phone) => {
916
943
  cacheMessage(cache, rebuilt);
917
944
  return rebuilt;
918
945
  } catch (err) {
919
- if (err instanceof NotFoundError) {
946
+ if (err instanceof NotFoundError2) {
920
947
  return;
921
948
  }
922
949
  throw err;
@@ -1375,7 +1402,7 @@ var editMessage = async (remote, spaceId, msgId, content) => {
1375
1402
  import {
1376
1403
  AuthenticationError,
1377
1404
  IMessageError,
1378
- NotFoundError as NotFoundError2,
1405
+ NotFoundError as NotFoundError3,
1379
1406
  ValidationError
1380
1407
  } from "@photon-ai/advanced-imessage";
1381
1408
 
@@ -1751,7 +1778,7 @@ var toPollDeltaMessages = async (client, pollCache, event, phone) => {
1751
1778
 
1752
1779
  // src/providers/imessage/remote/stream.ts
1753
1780
  var isRetryableIMessageStreamError = (error) => {
1754
- if (error instanceof AuthenticationError || error instanceof NotFoundError2 || error instanceof ValidationError) {
1781
+ if (error instanceof AuthenticationError || error instanceof NotFoundError3 || error instanceof ValidationError) {
1755
1782
  return false;
1756
1783
  }
1757
1784
  if (error instanceof IMessageError) {
@@ -2202,12 +2229,53 @@ var imessage = definePlatform("iMessage", {
2202
2229
  return await send4(remote, space.id, content);
2203
2230
  },
2204
2231
  actions: {
2205
- getMessage: async ({ space, messageId, client }) => {
2232
+ getMessage: async ({ client }, space, messageId) => {
2206
2233
  if (isLocal(client)) {
2207
2234
  return getMessage2(client, messageId);
2208
2235
  }
2209
2236
  const remote = clientForPhone(client, space.phone);
2210
2237
  return getMessage4(remote, space.id, messageId, space.phone);
2238
+ },
2239
+ // Fetch an attachment by GUID. Returns a spectrum `Attachment` whose
2240
+ // `.read()` / `.stream()` lazily download the bytes — calling both
2241
+ // issues two independent gRPC downloads, so cache `.read()` if you
2242
+ // need the bytes more than once. Returns `undefined` for unknown
2243
+ // GUIDs. Local-mode iMessage is not supported.
2244
+ getAttachment: async ({ client }, guid, phone) => {
2245
+ if (isLocal(client)) {
2246
+ throw UnsupportedError.action(
2247
+ "getAttachment",
2248
+ "iMessage (local mode)",
2249
+ "fetching attachments by GUID requires remote iMessage"
2250
+ );
2251
+ }
2252
+ if (client.length === 0) {
2253
+ throw new Error("No iMessage clients configured");
2254
+ }
2255
+ const routedPhone = (() => {
2256
+ if (isSharedMode(client)) {
2257
+ return SHARED_PHONE;
2258
+ }
2259
+ if (phone) {
2260
+ return phone;
2261
+ }
2262
+ if (client.length === 1) {
2263
+ return client[0].phone;
2264
+ }
2265
+ throw new Error(
2266
+ `imessage.getAttachment requires a phone in multi-phone mode. Available: ${availablePhones(client).join(", ")}`
2267
+ );
2268
+ })();
2269
+ const remote = clientForPhone(client, routedPhone);
2270
+ return withSpan(
2271
+ "spectrum.imessage.getAttachment",
2272
+ {
2273
+ "spectrum.provider": "iMessage",
2274
+ "spectrum.imessage.attachment.guid": guid,
2275
+ "spectrum.imessage.phone": routedPhone
2276
+ },
2277
+ () => getRemoteAttachment(remote, guid)
2278
+ );
2211
2279
  }
2212
2280
  }
2213
2281
  });
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readSchema
3
- } from "./chunk-JTS25BT3.js";
3
+ } from "./chunk-YFCDKZ6W.js";
4
4
 
5
5
  // src/utils/vcard.ts
6
6
  import vCard from "vcf";
@@ -4,7 +4,7 @@ import {
4
4
  readSchema,
5
5
  resolveContents,
6
6
  streamSchema
7
- } from "./chunk-JTS25BT3.js";
7
+ } from "./chunk-YFCDKZ6W.js";
8
8
 
9
9
  // src/content/group.ts
10
10
  import z from "zod";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  asVoice
3
- } from "./chunk-ODO6KRGX.js";
3
+ } from "./chunk-2B76JFHX.js";
4
4
  import {
5
5
  asContact,
6
6
  fromVCard,
7
7
  toVCard
8
- } from "./chunk-YZ226L5Y.js";
8
+ } from "./chunk-J2ANGYYW.js";
9
9
  import {
10
10
  UnsupportedError,
11
11
  asAttachment,
12
12
  asCustom,
13
13
  definePlatform,
14
14
  reactionSchema
15
- } from "./chunk-JTS25BT3.js";
15
+ } from "./chunk-YFCDKZ6W.js";
16
16
 
17
17
  // src/providers/terminal/index.ts
18
18
  import { spawn } from "child_process";
@@ -10,7 +10,7 @@ import {
10
10
  asReaction,
11
11
  asText,
12
12
  definePlatform
13
- } from "./chunk-JTS25BT3.js";
13
+ } from "./chunk-YFCDKZ6W.js";
14
14
 
15
15
  // src/providers/slack/index.ts
16
16
  import { createClient as createClient2, staticTokens } from "@photon-ai/slack";
@@ -169,6 +169,7 @@ var tsToDate = (ts) => {
169
169
  return new Date(seconds * 1e3);
170
170
  };
171
171
  var lazySlackFile = (client, teamId, file) => asAttachment({
172
+ id: file.id,
172
173
  name: file.name,
173
174
  mimeType: file.mimeType,
174
175
  size: file.size,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-YKWKZ2PZ.js";
9
9
  import {
10
10
  asContact
11
- } from "./chunk-YZ226L5Y.js";
11
+ } from "./chunk-J2ANGYYW.js";
12
12
  import {
13
13
  UnsupportedError,
14
14
  asAttachment,
@@ -16,7 +16,7 @@ import {
16
16
  asReaction,
17
17
  asText,
18
18
  definePlatform
19
- } from "./chunk-JTS25BT3.js";
19
+ } from "./chunk-YFCDKZ6W.js";
20
20
 
21
21
  // src/providers/whatsapp-business/index.ts
22
22
  import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
@@ -508,6 +508,7 @@ var fetchMedia = async (client, mediaId) => {
508
508
  return response;
509
509
  };
510
510
  var lazyMedia = (client, media) => asAttachment({
511
+ id: media.id,
511
512
  name: media.filename ?? `media-${media.id}`,
512
513
  mimeType: media.mimeType,
513
514
  read: async () => Buffer.from(await (await fetchMedia(client, media.id)).arrayBuffer()),
@@ -1,4 +1,5 @@
1
1
  // src/content/attachment.ts
2
+ import { randomUUID } from "crypto";
2
3
  import { createReadStream } from "fs";
3
4
  import { readFile, stat } from "fs/promises";
4
5
  import { basename } from "path";
@@ -49,6 +50,7 @@ var fetchUrlBytes = async (url, options) => {
49
50
  var DEFAULT_ATTACHMENT_NAME = "attachment";
50
51
  var attachmentSchema = z2.object({
51
52
  type: z2.literal("attachment"),
53
+ id: z2.string().nonempty(),
52
54
  name: z2.string().nonempty(),
53
55
  mimeType: z2.string().nonempty(),
54
56
  size: z2.number().int().nonnegative().optional(),
@@ -91,6 +93,7 @@ var asAttachment = (input) => {
91
93
  const stream = input.stream ?? (async () => bufferToStream(await read()));
92
94
  return attachmentSchema.parse({
93
95
  type: "attachment",
96
+ id: input.id ?? randomUUID(),
94
97
  name: input.name,
95
98
  mimeType: input.mimeType,
96
99
  size: input.size,
@@ -101,10 +104,12 @@ var asAttachment = (input) => {
101
104
  function attachment(input, options) {
102
105
  return {
103
106
  build: async () => {
107
+ const id = options?.id;
104
108
  const name = resolveAttachmentName(input, options?.name);
105
109
  const mimeType = resolveAttachmentMimeType(name, options?.mimeType);
106
110
  if (input instanceof URL) {
107
111
  return asAttachment({
112
+ id,
108
113
  name,
109
114
  mimeType,
110
115
  read: async () => (await fetchUrlBytes(input)).data
@@ -113,6 +118,7 @@ function attachment(input, options) {
113
118
  if (typeof input === "string") {
114
119
  const stats = await stat(input);
115
120
  return asAttachment({
121
+ id,
116
122
  name,
117
123
  mimeType,
118
124
  size: stats.size,
@@ -123,6 +129,7 @@ function attachment(input, options) {
123
129
  });
124
130
  }
125
131
  return asAttachment({
132
+ id,
126
133
  name,
127
134
  mimeType,
128
135
  size: input.byteLength,
@@ -549,6 +556,7 @@ var RESERVED_SPACE_KEYS = /* @__PURE__ */ new Set([
549
556
  "stopTyping",
550
557
  "responding"
551
558
  ]);
559
+ var PLATFORM_WISE_ACTION_KEYS = /* @__PURE__ */ new Set(["getMessage"]);
552
560
  var RESERVED_MESSAGE_KEYS = /* @__PURE__ */ new Set([
553
561
  "content",
554
562
  "direction",
@@ -561,8 +569,17 @@ var RESERVED_MESSAGE_KEYS = /* @__PURE__ */ new Set([
561
569
  "space",
562
570
  "timestamp"
563
571
  ]);
572
+ var scopeLabel = (scope) => {
573
+ if (scope === "space") {
574
+ return "Space";
575
+ }
576
+ if (scope === "message") {
577
+ return "Message";
578
+ }
579
+ return "PlatformInstance";
580
+ };
564
581
  var warnReservedAction = (scope, name, platform) => {
565
- const body = `[spectrum-ts] ${platform} declared ${scope} action "${name}" which collides with a reserved ${scope === "space" ? "Space" : "Message"} key; skipping.`;
582
+ const body = `[spectrum-ts] ${platform} declared ${scope} action "${name}" which collides with a reserved ${scopeLabel(scope)} key; skipping.`;
566
583
  console.warn(
567
584
  supportsAnsiColor() ? `${ANSI_YELLOW}${body}${ANSI_RESET}` : body
568
585
  );
@@ -765,11 +782,7 @@ function buildSpace(params) {
765
782
  async function getMessageImpl(id) {
766
783
  const getMessage = definition.actions?.getMessage;
767
784
  if (!getMessage) {
768
- warnUnsupported(
769
- UnsupportedError.action("getMessage", definition.name),
770
- definition.name
771
- );
772
- return;
785
+ throw UnsupportedError.action("getMessage", definition.name);
773
786
  }
774
787
  return withSpan(
775
788
  "spectrum.message.get",
@@ -779,22 +792,11 @@ function buildSpace(params) {
779
792
  "spectrum.message.id": id
780
793
  },
781
794
  async () => {
782
- let raw;
783
- try {
784
- raw = await getMessage({
785
- space: spaceRef,
786
- messageId: id,
787
- client,
788
- config,
789
- store
790
- });
791
- } catch (err) {
792
- if (err instanceof UnsupportedError) {
793
- warnUnsupported(err, definition.name);
794
- return;
795
- }
796
- throw err;
797
- }
795
+ const raw = await getMessage(
796
+ { client, config, store },
797
+ spaceRef,
798
+ id
799
+ );
798
800
  if (!raw) {
799
801
  return;
800
802
  }
@@ -952,6 +954,36 @@ function classifySpaceIdentifier(args) {
952
954
  }
953
955
  return { kind, identifier };
954
956
  }
957
+ function buildInstanceActions(platformName, declared, reservedKeys, buildCtx) {
958
+ const out = {};
959
+ for (const key of PLATFORM_WISE_ACTION_KEYS) {
960
+ const override = declared?.[key];
961
+ if (override && typeof override === "function") {
962
+ out[key] = (...args) => override(buildCtx(), ...args);
963
+ } else {
964
+ out[key] = () => {
965
+ throw UnsupportedError.action(key, platformName);
966
+ };
967
+ }
968
+ }
969
+ if (!declared) {
970
+ return out;
971
+ }
972
+ for (const [name, factory] of Object.entries(declared)) {
973
+ if (PLATFORM_WISE_ACTION_KEYS.has(name)) {
974
+ continue;
975
+ }
976
+ if (reservedKeys.has(name)) {
977
+ warnReservedAction("instance", name, platformName);
978
+ continue;
979
+ }
980
+ if (typeof factory !== "function") {
981
+ continue;
982
+ }
983
+ out[name] = (...args) => factory(buildCtx(), ...args);
984
+ }
985
+ return out;
986
+ }
955
987
  function createPlatformInstance(def, runtime) {
956
988
  const isPlatformUser = (value) => typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
957
989
  const resolveUserID = async (userID) => {
@@ -1087,7 +1119,26 @@ function createPlatformInstance(def, runtime) {
1087
1119
  return messagesIterable;
1088
1120
  }
1089
1121
  });
1090
- return Object.assign(base, eventProperties);
1122
+ const instanceActions = buildInstanceActions(
1123
+ def.name,
1124
+ def.actions,
1125
+ /* @__PURE__ */ new Set([
1126
+ "user",
1127
+ "space",
1128
+ "messages",
1129
+ ...Object.keys(customEvents)
1130
+ ]),
1131
+ () => ({
1132
+ client: runtime.client,
1133
+ config: runtime.config,
1134
+ store: runtime.store
1135
+ })
1136
+ );
1137
+ return Object.assign(
1138
+ base,
1139
+ instanceActions,
1140
+ eventProperties
1141
+ );
1091
1142
  }
1092
1143
  function definePlatform(name, def) {
1093
1144
  const fullDef = { name, ...def };
package/dist/index.d.ts CHANGED
@@ -1,16 +1,11 @@
1
- import { C as ContentBuilder, U as User, M as Message, b as Space, c as ContentInput, d as Content, e as ProviderMessage, E as EventProducer, f as SpaceActionFn, g as MessageActionFn, h as CreateClientContext, i as Store, a as PlatformDef, P as Platform, j as PlatformProviderConfig, k as SpectrumLike, l as CustomEventStreams, A as AgentSender } from './types-CtsphK2p.js';
2
- export { m as AnyPlatformDef, B as Broadcaster, n as ManagedStream, o as PlatformInstance, p as PlatformMessage, q as PlatformRuntime, r as PlatformSpace, s as PlatformUser, S as SchemaMessage, t as broadcast, u as mergeStreams, v as stream } from './types-CtsphK2p.js';
1
+ import { P as PhotoInput } from './photo-content-Deq7T2tO.js';
2
+ export { A as Attachment, a as AttachmentInput, b as attachment } from './photo-content-Deq7T2tO.js';
3
3
  import z__default from 'zod';
4
- import { P as PhotoInput } from './photo-content-BJKnqgN-.js';
4
+ import { C as ContentBuilder, U as User, M as Message, b as Space, c as ContentInput, e as Content, f as ProviderMessage, E as EventProducer, g as SpaceActionFn, h as MessageActionFn, I as InstanceActionFn, i as CreateClientContext, d as Store, a as PlatformDef, P as Platform, j as PlatformProviderConfig, k as SpectrumLike, l as CustomEventStreams, A as AgentSender } from './types-kk0L8kFG.js';
5
+ export { m as AnyPlatformDef, B as Broadcaster, n as ManagedStream, o as PlatformInstance, p as PlatformMessage, q as PlatformRuntime, r as PlatformSpace, s as PlatformUser, S as SchemaMessage, t as broadcast, u as mergeStreams, v as stream } from './types-kk0L8kFG.js';
5
6
  import vCard from 'vcf';
6
7
  import 'hotscript';
7
8
 
8
- type AttachmentInput = string | Buffer | URL;
9
- declare function attachment(input: AttachmentInput, options?: {
10
- mimeType?: string;
11
- name?: string;
12
- }): ContentBuilder;
13
-
14
9
  /**
15
10
  * Set or clear the chat avatar (group icon). Universal content — providers
16
11
  * dispatch by `content.type === "avatar"` in their `send` action and decide
@@ -198,6 +193,7 @@ declare const editSchema: z__default.ZodObject<{
198
193
  text: string;
199
194
  } | {
200
195
  type: "attachment";
196
+ id: string;
201
197
  name: string;
202
198
  mimeType: string;
203
199
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -301,6 +297,7 @@ declare const editSchema: z__default.ZodObject<{
301
297
  text: string;
302
298
  } | {
303
299
  type: "attachment";
300
+ id: string;
304
301
  name: string;
305
302
  mimeType: string;
306
303
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -328,6 +325,7 @@ declare const editSchema: z__default.ZodObject<{
328
325
  text: string;
329
326
  } | {
330
327
  type: "attachment";
328
+ id: string;
331
329
  name: string;
332
330
  mimeType: string;
333
331
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -431,6 +429,7 @@ declare const editSchema: z__default.ZodObject<{
431
429
  text: string;
432
430
  } | {
433
431
  type: "attachment";
432
+ id: string;
434
433
  name: string;
435
434
  mimeType: string;
436
435
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -572,6 +571,7 @@ declare const replySchema: z__default.ZodObject<{
572
571
  text: string;
573
572
  } | {
574
573
  type: "attachment";
574
+ id: string;
575
575
  name: string;
576
576
  mimeType: string;
577
577
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -675,6 +675,7 @@ declare const replySchema: z__default.ZodObject<{
675
675
  text: string;
676
676
  } | {
677
677
  type: "attachment";
678
+ id: string;
678
679
  name: string;
679
680
  mimeType: string;
680
681
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -702,6 +703,7 @@ declare const replySchema: z__default.ZodObject<{
702
703
  text: string;
703
704
  } | {
704
705
  type: "attachment";
706
+ id: string;
705
707
  name: string;
706
708
  mimeType: string;
707
709
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -805,6 +807,7 @@ declare const replySchema: z__default.ZodObject<{
805
807
  text: string;
806
808
  } | {
807
809
  type: "attachment";
810
+ id: string;
808
811
  name: string;
809
812
  mimeType: string;
810
813
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -2817,7 +2820,7 @@ declare function definePlatform<_Name extends string, _ConfigSchema extends z__d
2817
2820
  id: string;
2818
2821
  }, _MessageSchema extends z__default.ZodType<object> | undefined = undefined, _MessageType extends ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>> = ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>>, _Events extends (Record<string, EventProducer<unknown, _Client, z__default.infer<_ConfigSchema>>> & {
2819
2822
  messages?: never;
2820
- }) | undefined = undefined, _Static extends Record<string, unknown> = Record<never, never>, _SpaceActions extends Record<string, SpaceActionFn> = Record<never, never>, _MessageActions extends Record<string, MessageActionFn> = Record<never, never>>(name: _Name, def: {
2823
+ }) | undefined = undefined, _Static extends Record<string, unknown> = Record<never, never>, _SpaceActions extends Record<string, SpaceActionFn> = Record<never, never>, _MessageActions extends Record<string, MessageActionFn> = Record<never, never>, _Actions extends Record<string, InstanceActionFn> = Record<never, never>>(name: _Name, def: {
2821
2824
  lifecycle: {
2822
2825
  createClient: (ctx: CreateClientContext<_ConfigSchema>) => Promise<_Client>;
2823
2826
  destroyClient?: (ctx: {
@@ -2825,9 +2828,9 @@ declare function definePlatform<_Name extends string, _ConfigSchema extends z__d
2825
2828
  store: Store;
2826
2829
  }) => Promise<void>;
2827
2830
  };
2828
- } & Omit<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events, _SpaceActions, _MessageActions>, "lifecycle" | "name"> & {
2831
+ } & Omit<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events, _SpaceActions, _MessageActions, _Actions>, "lifecycle" | "name"> & {
2829
2832
  static?: _Static;
2830
- }): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events, _SpaceActions, _MessageActions>> & Readonly<_Static>;
2833
+ }): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events, _SpaceActions, _MessageActions, _Actions>> & Readonly<_Static>;
2831
2834
 
2832
2835
  type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> = SpectrumLike<Providers> & CustomEventStreams<Providers> & {
2833
2836
  readonly messages: AsyncIterable<[Space, Message]>;
@@ -2946,4 +2949,4 @@ declare class UnsupportedError extends Error {
2946
2949
  declare const fromVCard: (vcf: string) => ContactInput;
2947
2950
  declare const toVCard: (contact: Contact) => Promise<string>;
2948
2951
 
2949
- export { AgentSender, type Avatar, type AvatarInput, type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type Edit, Emoji, type EmojiKey, EventProducer, type Group, type ImessageInfoData, Message, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type Poll, type PollChoice, type PollChoiceInput, type PollOption, type Reaction, type Rename, type Reply, type Richlink, type SharedTokenData, type SlackTeamMeta, type SlackTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, type Typing, UnsupportedError, type UnsupportedKind, User, type Voice, attachment, avatar, cloud, contact, custom, definePlatform, edit, fromVCard, group, option, poll, reaction, rename, reply, resolveContents, richlink, text, toVCard, typing, voice };
2952
+ export { AgentSender, type Avatar, type AvatarInput, type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type Edit, Emoji, type EmojiKey, EventProducer, type Group, type ImessageInfoData, Message, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type Poll, type PollChoice, type PollChoiceInput, type PollOption, type Reaction, type Rename, type Reply, type Richlink, type SharedTokenData, type SlackTeamMeta, type SlackTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, type Typing, UnsupportedError, type UnsupportedKind, User, type Voice, avatar, cloud, contact, custom, definePlatform, edit, fromVCard, group, option, poll, reaction, rename, reply, resolveContents, richlink, text, toVCard, typing, voice };
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  group,
3
3
  richlink
4
- } from "./chunk-TOJQ6DPE.js";
4
+ } from "./chunk-JBMQ5GEW.js";
5
5
  import {
6
6
  voice
7
- } from "./chunk-ODO6KRGX.js";
7
+ } from "./chunk-2B76JFHX.js";
8
8
  import {
9
9
  option,
10
10
  poll
@@ -20,7 +20,7 @@ import {
20
20
  contact,
21
21
  fromVCard,
22
22
  toVCard
23
- } from "./chunk-YZ226L5Y.js";
23
+ } from "./chunk-J2ANGYYW.js";
24
24
  import {
25
25
  UnsupportedError,
26
26
  attachment,
@@ -38,7 +38,7 @@ import {
38
38
  text,
39
39
  typing,
40
40
  wrapProviderMessage
41
- } from "./chunk-JTS25BT3.js";
41
+ } from "./chunk-YFCDKZ6W.js";
42
42
 
43
43
  // src/emoji/generated.ts
44
44
  var GeneratedEmoji = {
@@ -0,0 +1,33 @@
1
+ import z__default from 'zod';
2
+ import { C as ContentBuilder } from './types-kk0L8kFG.js';
3
+
4
+ declare const attachmentSchema: z__default.ZodObject<{
5
+ type: z__default.ZodLiteral<"attachment">;
6
+ id: z__default.ZodString;
7
+ name: z__default.ZodString;
8
+ mimeType: z__default.ZodString;
9
+ size: z__default.ZodOptional<z__default.ZodNumber>;
10
+ read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
11
+ stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
12
+ }, z__default.core.$strip>;
13
+ type Attachment = z__default.infer<typeof attachmentSchema>;
14
+ type AttachmentInput = string | Buffer | URL;
15
+ declare function attachment(input: AttachmentInput, options?: {
16
+ id?: string;
17
+ mimeType?: string;
18
+ name?: string;
19
+ }): ContentBuilder;
20
+
21
+ /**
22
+ * Shared building blocks for photo-style content (chat background, group
23
+ * avatar/icon, …) whose builders all share the same `set | clear` shape and
24
+ * the same `"clear"` reserved-string sentinel.
25
+ *
26
+ * Keeping the action schema and `buildPhotoAction` factory here means both
27
+ * `background()` and `avatar()` parse against the same structural definition
28
+ * and any DX fix (mime inference, read caching, sentinel docs) lands once.
29
+ */
30
+ declare const CLEAR_SENTINEL: "clear";
31
+ type PhotoInput = typeof CLEAR_SENTINEL | string | Buffer | URL;
32
+
33
+ export { type Attachment as A, type PhotoInput as P, type AttachmentInput as a, attachment as b };
@@ -1,8 +1,8 @@
1
- import { C as ContentBuilder, c as ContentInput, M as Message, S as SchemaMessage, P as Platform, a as PlatformDef, b as Space } from '../../types-CtsphK2p.js';
1
+ import { C as ContentBuilder, c as ContentInput, M as Message, S as SchemaMessage, P as Platform, a as PlatformDef, b as Space, d as Store } from '../../types-kk0L8kFG.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 { P as PhotoInput } from '../../photo-content-BJKnqgN-.js';
5
+ import { P as PhotoInput, A as Attachment } from '../../photo-content-Deq7T2tO.js';
6
6
  import { MessageEffect, AdvancedIMessage } from '@photon-ai/advanced-imessage';
7
7
  import { IMessageSDK } from '@photon-ai/imessage-kit';
8
8
  import 'hotscript';
@@ -122,6 +122,39 @@ declare const imessage: Platform<PlatformDef<"iMessage", z.ZodUnion<readonly [z.
122
122
  read: (space: Space, message: Message) => Promise<void>;
123
123
  }, {
124
124
  read: (message: Message) => Promise<void>;
125
+ }, {
126
+ getMessage: ({ client }: {
127
+ client: IMessageClient;
128
+ config: {
129
+ local: true;
130
+ } | {
131
+ local: false;
132
+ clients?: {
133
+ address: string;
134
+ token: string;
135
+ phone: string;
136
+ } | {
137
+ address: string;
138
+ token: string;
139
+ phone: string;
140
+ }[] | undefined;
141
+ };
142
+ store: Store;
143
+ }, space: ({
144
+ id: string;
145
+ type: "dm";
146
+ phone: string;
147
+ } | {
148
+ id: string;
149
+ type: "group";
150
+ phone: string;
151
+ }) & {
152
+ id: string;
153
+ __platform: string;
154
+ }, messageId: string) => Promise<IMessageMessage | undefined>;
155
+ getAttachment: ({ client }: {
156
+ client: IMessageClient;
157
+ }, guid: string, phone?: string) => Promise<Attachment | undefined>;
125
158
  }>> & Readonly<{
126
159
  effect: {
127
160
  message: {
@@ -3,12 +3,12 @@ import {
3
3
  effect,
4
4
  imessage,
5
5
  read
6
- } from "../../chunk-UGBHJEX2.js";
7
- import "../../chunk-TOJQ6DPE.js";
6
+ } from "../../chunk-BGV4SFVJ.js";
7
+ import "../../chunk-JBMQ5GEW.js";
8
8
  import "../../chunk-KO67KDBD.js";
9
9
  import "../../chunk-YKWKZ2PZ.js";
10
- import "../../chunk-YZ226L5Y.js";
11
- import "../../chunk-JTS25BT3.js";
10
+ import "../../chunk-J2ANGYYW.js";
11
+ import "../../chunk-YFCDKZ6W.js";
12
12
  export {
13
13
  background,
14
14
  effect,
@@ -2,11 +2,11 @@ export { imessage } from './imessage/index.js';
2
2
  export { slack } from './slack/index.js';
3
3
  export { terminal } from './terminal/index.js';
4
4
  export { whatsappBusiness } from './whatsapp-business/index.js';
5
- import '../types-CtsphK2p.js';
5
+ import '../types-kk0L8kFG.js';
6
6
  import 'hotscript';
7
7
  import 'zod';
8
8
  import 'zod/v4/core';
9
- import '../photo-content-BJKnqgN-.js';
9
+ import '../photo-content-Deq7T2tO.js';
10
10
  import '@photon-ai/advanced-imessage';
11
11
  import '@photon-ai/imessage-kit';
12
12
  import '@photon-ai/slack';
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  imessage
3
- } from "../chunk-UGBHJEX2.js";
4
- import "../chunk-TOJQ6DPE.js";
3
+ } from "../chunk-BGV4SFVJ.js";
4
+ import "../chunk-JBMQ5GEW.js";
5
5
  import {
6
6
  slack
7
- } from "../chunk-5HNHMI6L.js";
7
+ } from "../chunk-VOAKCXBF.js";
8
8
  import {
9
9
  terminal
10
- } from "../chunk-VTQWVJZ5.js";
11
- import "../chunk-ODO6KRGX.js";
10
+ } from "../chunk-TSJKUFNE.js";
11
+ import "../chunk-2B76JFHX.js";
12
12
  import {
13
13
  whatsappBusiness
14
- } from "../chunk-ZUQYLYGI.js";
14
+ } from "../chunk-YEQPATHB.js";
15
15
  import "../chunk-KO67KDBD.js";
16
16
  import "../chunk-YKWKZ2PZ.js";
17
- import "../chunk-YZ226L5Y.js";
18
- import "../chunk-JTS25BT3.js";
17
+ import "../chunk-J2ANGYYW.js";
18
+ import "../chunk-YFCDKZ6W.js";
19
19
  export {
20
20
  imessage,
21
21
  slack,
@@ -1,4 +1,4 @@
1
- import { S as SchemaMessage, P as Platform, a as PlatformDef } from '../../types-CtsphK2p.js';
1
+ import { S as SchemaMessage, P as Platform, a as PlatformDef } from '../../types-kk0L8kFG.js';
2
2
  import * as z from 'zod';
3
3
  import z__default from 'zod';
4
4
  import * as _photon_ai_slack from '@photon-ai/slack';
@@ -42,6 +42,6 @@ declare const slack: Platform<PlatformDef<"Slack", z.ZodUnion<readonly [z.ZodObj
42
42
  subtype: z.ZodOptional<z.ZodString>;
43
43
  threadTs: z.ZodOptional<z.ZodString>;
44
44
  ts: z.ZodOptional<z.ZodString>;
45
- }, zod_v4_core.$strip>, SlackMessage, undefined, Record<never, never>, Record<never, never>>> & Readonly<Record<never, never>>;
45
+ }, zod_v4_core.$strip>, SlackMessage, undefined, Record<never, never>, Record<never, never>, Record<never, never>>> & Readonly<Record<never, never>>;
46
46
 
47
47
  export { slack };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  slack
3
- } from "../../chunk-5HNHMI6L.js";
3
+ } from "../../chunk-VOAKCXBF.js";
4
4
  import "../../chunk-YKWKZ2PZ.js";
5
- import "../../chunk-JTS25BT3.js";
5
+ import "../../chunk-YFCDKZ6W.js";
6
6
  export {
7
7
  slack
8
8
  };
@@ -1,4 +1,4 @@
1
- import { P as Platform, a as PlatformDef, M as Message, U as User, b as Space } from '../../types-CtsphK2p.js';
1
+ import { P as Platform, a as PlatformDef, M as Message, U as User, b as Space } from '../../types-kk0L8kFG.js';
2
2
  import { ChildProcess } from 'node:child_process';
3
3
  import z__default from 'zod';
4
4
  import { Socket } from 'node:net';
@@ -107,15 +107,16 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
107
107
  } | undefined;
108
108
  id: string;
109
109
  content: {
110
+ type: "text";
111
+ text: string;
112
+ } | {
110
113
  type: "attachment";
114
+ id: string;
111
115
  name: string;
112
116
  mimeType: string;
113
117
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
114
118
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
115
119
  size?: number | undefined;
116
- } | {
117
- type: "text";
118
- text: string;
119
120
  } | {
120
121
  type: "custom";
121
122
  raw: unknown;
@@ -210,15 +211,16 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
210
211
  } | {
211
212
  type: "effect";
212
213
  content: {
214
+ type: "text";
215
+ text: string;
216
+ } | {
213
217
  type: "attachment";
218
+ id: string;
214
219
  name: string;
215
220
  mimeType: string;
216
221
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
217
222
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
218
223
  size?: number | undefined;
219
- } | {
220
- type: "text";
221
- text: string;
222
224
  };
223
225
  effect: string;
224
226
  } | {
@@ -237,17 +239,18 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
237
239
  kind: "clear";
238
240
  };
239
241
  } | {
240
- type: "reply";
242
+ type: "edit";
241
243
  content: {
244
+ type: "text";
245
+ text: string;
246
+ } | {
242
247
  type: "attachment";
248
+ id: string;
243
249
  name: string;
244
250
  mimeType: string;
245
251
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
246
252
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
247
253
  size?: number | undefined;
248
- } | {
249
- type: "text";
250
- text: string;
251
254
  } | {
252
255
  type: "custom";
253
256
  raw: unknown;
@@ -342,15 +345,16 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
342
345
  } | {
343
346
  type: "effect";
344
347
  content: {
348
+ type: "text";
349
+ text: string;
350
+ } | {
345
351
  type: "attachment";
352
+ id: string;
346
353
  name: string;
347
354
  mimeType: string;
348
355
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
349
356
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
350
357
  size?: number | undefined;
351
- } | {
352
- type: "text";
353
- text: string;
354
358
  };
355
359
  effect: string;
356
360
  } | {
@@ -371,17 +375,18 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
371
375
  };
372
376
  target: Message<string, User, Space<unknown>>;
373
377
  } | {
374
- type: "edit";
378
+ type: "reply";
375
379
  content: {
380
+ type: "text";
381
+ text: string;
382
+ } | {
376
383
  type: "attachment";
384
+ id: string;
377
385
  name: string;
378
386
  mimeType: string;
379
387
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
380
388
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
381
389
  size?: number | undefined;
382
- } | {
383
- type: "text";
384
- text: string;
385
390
  } | {
386
391
  type: "custom";
387
392
  raw: unknown;
@@ -476,15 +481,16 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
476
481
  } | {
477
482
  type: "effect";
478
483
  content: {
484
+ type: "text";
485
+ text: string;
486
+ } | {
479
487
  type: "attachment";
488
+ id: string;
480
489
  name: string;
481
490
  mimeType: string;
482
491
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
483
492
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
484
493
  size?: number | undefined;
485
- } | {
486
- type: "text";
487
- text: string;
488
494
  };
489
495
  effect: string;
490
496
  } | {
@@ -512,6 +518,6 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
512
518
  id: string;
513
519
  };
514
520
  timestamp: Date;
515
- }, undefined, Record<never, never>, Record<never, never>>> & Readonly<Record<never, never>>;
521
+ }, undefined, Record<never, never>, Record<never, never>, Record<never, never>>> & Readonly<Record<never, never>>;
516
522
 
517
523
  export { terminal };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  terminal
3
- } from "../../chunk-VTQWVJZ5.js";
4
- import "../../chunk-ODO6KRGX.js";
5
- import "../../chunk-YZ226L5Y.js";
6
- import "../../chunk-JTS25BT3.js";
3
+ } from "../../chunk-TSJKUFNE.js";
4
+ import "../../chunk-2B76JFHX.js";
5
+ import "../../chunk-J2ANGYYW.js";
6
+ import "../../chunk-YFCDKZ6W.js";
7
7
  export {
8
8
  terminal
9
9
  };
@@ -1,4 +1,4 @@
1
- import { S as SchemaMessage, P as Platform, a as PlatformDef } from '../../types-CtsphK2p.js';
1
+ import { S as SchemaMessage, P as Platform, a as PlatformDef } from '../../types-kk0L8kFG.js';
2
2
  import { WhatsAppClient } from '@photon-ai/whatsapp-business';
3
3
  import * as z from 'zod';
4
4
  import z__default from 'zod';
@@ -22,6 +22,6 @@ declare const whatsappBusiness: Platform<PlatformDef<"WhatsApp Business", z.ZodU
22
22
  id: string;
23
23
  }, {
24
24
  id: string;
25
- }, undefined, WhatsAppMessage, undefined, Record<never, never>, Record<never, never>>> & Readonly<Record<never, never>>;
25
+ }, undefined, WhatsAppMessage, undefined, Record<never, never>, Record<never, never>, Record<never, never>>> & Readonly<Record<never, never>>;
26
26
 
27
27
  export { whatsappBusiness };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  whatsappBusiness
3
- } from "../../chunk-ZUQYLYGI.js";
3
+ } from "../../chunk-YEQPATHB.js";
4
4
  import "../../chunk-KO67KDBD.js";
5
5
  import "../../chunk-YKWKZ2PZ.js";
6
- import "../../chunk-YZ226L5Y.js";
7
- import "../../chunk-JTS25BT3.js";
6
+ import "../../chunk-J2ANGYYW.js";
7
+ import "../../chunk-YFCDKZ6W.js";
8
8
  export {
9
9
  whatsappBusiness
10
10
  };
@@ -9,6 +9,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
9
9
  raw: z__default.ZodUnknown;
10
10
  }, z__default.core.$strip>, z__default.ZodObject<{
11
11
  type: z__default.ZodLiteral<"attachment">;
12
+ id: z__default.ZodString;
12
13
  name: z__default.ZodString;
13
14
  mimeType: z__default.ZodString;
14
15
  size: z__default.ZodOptional<z__default.ZodNumber>;
@@ -122,6 +123,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
122
123
  text: z__default.ZodString;
123
124
  }, z__default.core.$strip>, z__default.ZodObject<{
124
125
  type: z__default.ZodLiteral<"attachment">;
126
+ id: z__default.ZodString;
125
127
  name: z__default.ZodString;
126
128
  mimeType: z__default.ZodString;
127
129
  size: z__default.ZodOptional<z__default.ZodNumber>;
@@ -163,6 +165,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
163
165
  text: string;
164
166
  } | {
165
167
  type: "attachment";
168
+ id: string;
166
169
  name: string;
167
170
  mimeType: string;
168
171
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -266,6 +269,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
266
269
  text: string;
267
270
  } | {
268
271
  type: "attachment";
272
+ id: string;
269
273
  name: string;
270
274
  mimeType: string;
271
275
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -293,6 +297,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
293
297
  text: string;
294
298
  } | {
295
299
  type: "attachment";
300
+ id: string;
296
301
  name: string;
297
302
  mimeType: string;
298
303
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -396,6 +401,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
396
401
  text: string;
397
402
  } | {
398
403
  type: "attachment";
404
+ id: string;
399
405
  name: string;
400
406
  mimeType: string;
401
407
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -427,6 +433,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
427
433
  text: string;
428
434
  } | {
429
435
  type: "attachment";
436
+ id: string;
430
437
  name: string;
431
438
  mimeType: string;
432
439
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -530,6 +537,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
530
537
  text: string;
531
538
  } | {
532
539
  type: "attachment";
540
+ id: string;
533
541
  name: string;
534
542
  mimeType: string;
535
543
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -557,6 +565,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
557
565
  text: string;
558
566
  } | {
559
567
  type: "attachment";
568
+ id: string;
560
569
  name: string;
561
570
  mimeType: string;
562
571
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -660,6 +669,7 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
660
669
  text: string;
661
670
  } | {
662
671
  type: "attachment";
672
+ id: string;
663
673
  name: string;
664
674
  mimeType: string;
665
675
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
@@ -813,6 +823,60 @@ type SpaceActionFn = (space: Space, ...args: never[]) => Promise<void>;
813
823
  * `Exclude<…, keyof Message>`.
814
824
  */
815
825
  type MessageActionFn = (message: Message, ...args: never[]) => Promise<void>;
826
+ /**
827
+ * A platform-defined method projected onto the value returned by
828
+ * `provider(spectrum)` (e.g. `imessage(spectrum).getAttachment(guid)`). The
829
+ * first parameter is an injected runtime context (`{ client, config, store }`);
830
+ * `createPlatformInstance` supplies it so callers only pass the trailing args.
831
+ *
832
+ * Unlike `SpaceActionFn` / `MessageActionFn` (which always return
833
+ * `Promise<void>` because they dispatch through `send`), instance actions
834
+ * return arbitrary data — the public signature preserves the declared return
835
+ * type via `InstanceActionMethods<Def>`.
836
+ *
837
+ * Two tiers live in the same `actions?` slot:
838
+ *
839
+ * - **Platform-wise actions** — fixed framework-known names (currently just
840
+ * `getMessage`) whose signatures are defined by `PlatformWiseActions`. They
841
+ * power universal sugar (`space.getMessage(id)`) AND surface on the
842
+ * platform instance. If a provider omits one, the framework wires a
843
+ * default that throws `UnsupportedError`.
844
+ * - **Platform-specific actions** — free-form keys each platform declares
845
+ * for its own ergonomics (e.g. iMessage's `getAttachment`). Surface on
846
+ * the platform instance only.
847
+ *
848
+ * Names that collide with reserved instance keys (`user`, `space`, `messages`,
849
+ * plus any declared `events` key) are skipped at runtime with a warning and
850
+ * excluded at the type level.
851
+ */
852
+ type InstanceActionFn = (ctx: any, ...args: any[]) => Promise<unknown>;
853
+ /**
854
+ * Framework-known action names that every platform implicitly has.
855
+ *
856
+ * Each entry's signature lives here; the framework wires the corresponding
857
+ * method onto the `PlatformInstance` for every platform — providers override
858
+ * by declaring the key inside their `actions` slot, and platforms that omit
859
+ * the key get a default that throws `UnsupportedError`.
860
+ *
861
+ * Add a new platform-wise capability by extending this record (and the
862
+ * runtime list in `define.ts`); the corresponding instance method will be
863
+ * surfaced on every `PlatformInstance` automatically.
864
+ */
865
+ interface PlatformWiseActions<_ResolvedSpace extends {
866
+ id: string;
867
+ }, _MessageType, _Client, _Config> {
868
+ getMessage: (ctx: {
869
+ client: _Client;
870
+ config: _Config;
871
+ store: Store;
872
+ }, space: _ResolvedSpace & {
873
+ id: string;
874
+ __platform: string;
875
+ }, messageId: string) => Promise<_MessageType | undefined>;
876
+ }
877
+ type PlatformWiseActionKey = keyof PlatformWiseActions<{
878
+ id: string;
879
+ }, unknown, unknown, unknown>;
816
880
  type ResolvedSpace = Pick<Space, "id">;
817
881
  type SpaceRef = Pick<Space, "id" | "__platform">;
818
882
  type ResolvedUser = Pick<User, "id">;
@@ -886,27 +950,30 @@ interface CreateClientContext<_ConfigSchema extends z__default.ZodType<object>>
886
950
  */
887
951
  interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__default.ZodType<object> = z__default.ZodType<object>, _UserSchema extends z__default.ZodType<object> | undefined = undefined, _SpaceSchema extends z__default.ZodType<object> | undefined = undefined, _SpaceParamsSchema extends z__default.ZodType<object> | undefined = undefined, _Client = unknown, _ResolvedUser extends ResolvedUser = ResolvedUser, _ResolvedSpace extends ResolvedSpace = ResolvedSpace, _MessageSchema extends z__default.ZodType<object> | undefined = undefined, _MessageType extends ProviderMessage<_ResolvedUser, _ResolvedSpace, InferSchema<_MessageSchema>> = ProviderMessage<_ResolvedUser, _ResolvedSpace, InferSchema<_MessageSchema>>, _Events extends (Record<string, EventProducer<unknown, _Client, z__default.infer<_ConfigSchema>>> & {
888
952
  messages?: never;
889
- }) | undefined = undefined, _SpaceActions extends Record<string, SpaceActionFn> = Record<never, never>, _MessageActions extends Record<string, MessageActionFn> = Record<never, never>> {
953
+ }) | undefined = undefined, _SpaceActions extends Record<string, SpaceActionFn> = Record<never, never>, _MessageActions extends Record<string, MessageActionFn> = Record<never, never>, _Actions extends Record<string, InstanceActionFn> = Record<never, never>> {
890
954
  /**
891
- * Optional escape hatch: platform actions beyond `send`. Currently the
892
- * framework recognizes one slot:
955
+ * Provider-defined methods exposed on the platform instance.
893
956
  *
894
- * - **`getMessage?`** fetch a message by id from a space. Powers
895
- * `space.getMessage(id)`. When omitted, `space.getMessage()` warns and
896
- * returns `undefined`.
957
+ * Two tiers share this slot:
897
958
  *
898
- * 99% of integrations don't need this — `messages` + `send` is the
899
- * universal contract.
959
+ * 1. **Platform-wise actions** (`getMessage`) framework-recognized names
960
+ * declared in `PlatformWiseActions`. Override by declaring the key here
961
+ * with the matching signature. The framework injects `ctx = { client,
962
+ * config, store }` as the first arg and surfaces the method on the
963
+ * platform instance (`im.getMessage(space, id)`). If omitted, the
964
+ * framework wires a default that throws `UnsupportedError`. Powers
965
+ * universal sugar like `space.getMessage(id)`.
966
+ *
967
+ * 2. **Platform-specific actions** — free-form keys like `getAttachment`.
968
+ * Each gets `ctx = { client, config, store }` as the first arg; the
969
+ * public signature on `PlatformInstance<Def>` drops `ctx` and preserves
970
+ * the declared return type.
971
+ *
972
+ * Names that collide with reserved instance keys (`user`, `space`,
973
+ * `messages`, plus any declared `events` key) are skipped at runtime with
974
+ * a warning and excluded at the type level.
900
975
  */
901
- actions?: {
902
- getMessage?: (_: {
903
- space: _ResolvedSpace & SpaceRef;
904
- messageId: string;
905
- client: NoInferClient<_Client>;
906
- config: z__default.infer<_ConfigSchema>;
907
- store: Store;
908
- }) => Promise<_MessageType | undefined>;
909
- };
976
+ actions?: Partial<PlatformWiseActions<_ResolvedSpace, _MessageType, NoInferClient<_Client>, z__default.infer<_ConfigSchema>>> & _Actions;
910
977
  config: _ConfigSchema;
911
978
  /**
912
979
  * Optional escape hatch: platform-specific event streams beyond the core
@@ -1028,9 +1095,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
1028
1095
  };
1029
1096
  }
1030
1097
  interface AnyPlatformDef {
1031
- actions?: {
1032
- getMessage?: (_: any) => Promise<any>;
1033
- };
1098
+ actions?: Record<string, InstanceActionFn>;
1034
1099
  config: z__default.ZodType<object>;
1035
1100
  events?: {
1036
1101
  [key: string]: (ctx: any) => AsyncIterable<any>;
@@ -1122,6 +1187,15 @@ type MessageActionFns<Def extends AnyPlatformDef> = NonNullable<Def["message"]>
1122
1187
  type MessageActionMethods<Def extends AnyPlatformDef> = {
1123
1188
  [K in Exclude<keyof MessageActionFns<Def>, keyof Message>]: (...args: TailArgs<Parameters<MessageActionFns<Def>[K]>>) => Promise<void>;
1124
1189
  };
1190
+ type AnyInstanceActionFn = (...args: any[]) => Promise<unknown>;
1191
+ type InstanceActionFns<Def extends AnyPlatformDef> = Def["actions"] extends infer A | undefined ? A extends Record<string, AnyInstanceActionFn> ? A : Record<string, never> : Record<string, never>;
1192
+ type ReservedInstanceKeys<Def extends AnyPlatformDef> = "user" | "space" | "messages" | PlatformWiseActionKey | Extract<keyof CustomEventInstanceProperties<Def>, string>;
1193
+ type InstanceActionMethods<Def extends AnyPlatformDef> = {
1194
+ [K in Exclude<keyof InstanceActionFns<Def>, ReservedInstanceKeys<Def> | symbol | number>]: (...args: TailArgs<Parameters<InstanceActionFns<Def>[K]>>) => ReturnType<InstanceActionFns<Def>[K]>;
1195
+ };
1196
+ interface PlatformWiseInstanceMethods<Def extends AnyPlatformDef> {
1197
+ getMessage: (space: PlatformSpace<Def>, messageId: string) => Promise<PlatformMessage<Def> | undefined>;
1198
+ }
1125
1199
  type PlatformSpace<Def extends AnyPlatformDef> = Omit<SpaceShapeOf<Def>, keyof Space | keyof SpaceActionMethods<Def>> & Space & SpaceActionMethods<Def>;
1126
1200
  type PlatformMessage<Def extends AnyPlatformDef> = Omit<SchemaInfer<Def["message"]>, keyof Message | keyof MessageActionMethods<Def>> & Message<Def["name"], PlatformUser<Def>, PlatformSpace<Def>> & MessageActionMethods<Def>;
1127
1201
  type PlatformUser<Def extends AnyPlatformDef> = Omit<ResolvedUserOf<Def>, keyof User> & User;
@@ -1129,7 +1203,7 @@ type PlatformInstance<Def extends AnyPlatformDef> = {
1129
1203
  readonly messages: AsyncIterable<[PlatformSpace<Def>, PlatformMessage<Def>]>;
1130
1204
  space(...args: SpaceArgs<Def>): Promise<PlatformSpace<Def>>;
1131
1205
  user(userID: string): Promise<PlatformUser<Def>>;
1132
- } & CustomEventInstanceProperties<Def>;
1206
+ } & CustomEventInstanceProperties<Def> & PlatformWiseInstanceMethods<Def> & InstanceActionMethods<Def>;
1133
1207
  type CustomEventInstanceProperties<Def extends AnyPlatformDef> = Def["events"] extends Record<string, unknown> ? {
1134
1208
  [K in Exclude<keyof Def["events"], symbol | number> as K extends ReservedNames ? never : K]: AsyncIterable<InferEventPayload<NonNullable<Def["events"]>[K]>>;
1135
1209
  } : Record<never, never>;
@@ -1156,4 +1230,4 @@ interface Platform<Def extends AnyPlatformDef> {
1156
1230
  (message: Message): PlatformMessage<Def>;
1157
1231
  }
1158
1232
 
1159
- export { type AgentSender as A, type Broadcaster as B, type ContentBuilder as C, type EventProducer as E, type Message as M, type Platform as P, type SchemaMessage as S, type User as U, type PlatformDef as a, type Space as b, type ContentInput as c, type Content as d, type ProviderMessage as e, type SpaceActionFn as f, type MessageActionFn as g, type CreateClientContext as h, type Store as i, type PlatformProviderConfig as j, type SpectrumLike as k, type CustomEventStreams as l, type AnyPlatformDef as m, type ManagedStream as n, type PlatformInstance as o, type PlatformMessage as p, type PlatformRuntime as q, type PlatformSpace as r, type PlatformUser as s, broadcast as t, mergeStreams as u, stream as v };
1233
+ export { type AgentSender as A, type Broadcaster as B, type ContentBuilder as C, type EventProducer as E, type InstanceActionFn as I, type Message as M, type Platform as P, type SchemaMessage as S, type User as U, type PlatformDef as a, type Space as b, type ContentInput as c, type Store as d, type Content as e, type ProviderMessage as f, type SpaceActionFn as g, type MessageActionFn as h, type CreateClientContext as i, type PlatformProviderConfig as j, type SpectrumLike as k, type CustomEventStreams as l, type AnyPlatformDef as m, type ManagedStream as n, type PlatformInstance as o, type PlatformMessage as p, type PlatformRuntime as q, type PlatformSpace as r, type PlatformUser as s, broadcast as t, mergeStreams as u, stream as v };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "Bring agents to any interface — unified messaging SDK for TypeScript.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,13 +0,0 @@
1
- /**
2
- * Shared building blocks for photo-style content (chat background, group
3
- * avatar/icon, …) whose builders all share the same `set | clear` shape and
4
- * the same `"clear"` reserved-string sentinel.
5
- *
6
- * Keeping the action schema and `buildPhotoAction` factory here means both
7
- * `background()` and `avatar()` parse against the same structural definition
8
- * and any DX fix (mime inference, read caching, sentinel docs) lands once.
9
- */
10
- declare const CLEAR_SENTINEL: "clear";
11
- type PhotoInput = typeof CLEAR_SENTINEL | string | Buffer | URL;
12
-
13
- export type { PhotoInput as P };