spectrum-ts 1.13.0 → 1.14.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.
@@ -10,7 +10,7 @@ import {
10
10
  asReaction,
11
11
  asText,
12
12
  definePlatform
13
- } from "./chunk-YDHES53X.js";
13
+ } from "./chunk-JTS25BT3.js";
14
14
 
15
15
  // src/providers/slack/index.ts
16
16
  import { createClient as createClient2, staticTokens } from "@photon-ai/slack";
@@ -22,6 +22,28 @@ var bufferToStream = (buf) => new ReadableStream({
22
22
  controller.close();
23
23
  }
24
24
  });
25
+ var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
26
+ var fetchUrlBytes = async (url, options) => {
27
+ const controller = new AbortController();
28
+ const timer = setTimeout(
29
+ () => controller.abort(),
30
+ options?.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS
31
+ );
32
+ try {
33
+ const res = await fetch(url, {
34
+ signal: controller.signal,
35
+ headers: options?.headers
36
+ });
37
+ if (!res.ok) {
38
+ throw new Error(`URL fetch ${url.toString()} returned ${res.status}`);
39
+ }
40
+ const data = Buffer.from(await res.arrayBuffer());
41
+ const mimeType = res.headers.get("content-type") ?? void 0;
42
+ return { data, mimeType };
43
+ } finally {
44
+ clearTimeout(timer);
45
+ }
46
+ };
25
47
 
26
48
  // src/content/attachment.ts
27
49
  var DEFAULT_ATTACHMENT_NAME = "attachment";
@@ -33,7 +55,18 @@ var attachmentSchema = z2.object({
33
55
  read: readSchema,
34
56
  stream: streamSchema
35
57
  });
36
- var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
58
+ var resolveAttachmentName = (input, name) => {
59
+ if (name) {
60
+ return name;
61
+ }
62
+ if (input instanceof URL) {
63
+ return basename(input.pathname) || DEFAULT_ATTACHMENT_NAME;
64
+ }
65
+ if (typeof input === "string") {
66
+ return basename(input);
67
+ }
68
+ return DEFAULT_ATTACHMENT_NAME;
69
+ };
37
70
  var resolveAttachmentMimeType = (name, mimeType) => {
38
71
  if (mimeType) {
39
72
  return mimeType;
@@ -70,6 +103,13 @@ function attachment(input, options) {
70
103
  build: async () => {
71
104
  const name = resolveAttachmentName(input, options?.name);
72
105
  const mimeType = resolveAttachmentMimeType(name, options?.mimeType);
106
+ if (input instanceof URL) {
107
+ return asAttachment({
108
+ name,
109
+ mimeType,
110
+ read: async () => (await fetchUrlBytes(input)).data
111
+ });
112
+ }
73
113
  if (typeof input === "string") {
74
114
  const stats = await stat(input);
75
115
  return asAttachment({
@@ -114,7 +154,12 @@ var resolveMimeType = (input, mimeType, contentLabel) => {
114
154
  if (mimeType) {
115
155
  return mimeType;
116
156
  }
117
- if (typeof input === "string") {
157
+ if (input instanceof URL) {
158
+ const resolved = lookupMimeType2(basename2(input.pathname));
159
+ if (resolved) {
160
+ return resolved;
161
+ }
162
+ } else if (typeof input === "string") {
118
163
  const resolved = lookupMimeType2(basename2(input));
119
164
  if (resolved) {
120
165
  return resolved;
@@ -140,7 +185,9 @@ var buildPhotoAction = (input, options, contentLabel) => {
140
185
  }
141
186
  const mimeType = resolveMimeType(input, options?.mimeType, contentLabel);
142
187
  let read;
143
- if (typeof input === "string") {
188
+ if (input instanceof URL) {
189
+ read = cachedRead(async () => (await fetchUrlBytes(input)).data);
190
+ } else if (typeof input === "string") {
144
191
  read = cachedRead(() => readFile2(input));
145
192
  } else {
146
193
  const snapshot = Buffer.from(input);
@@ -785,7 +832,7 @@ function buildSpace(params) {
785
832
  await space.send(rename(displayName));
786
833
  },
787
834
  avatar: (async (input, options) => {
788
- if (typeof input === "string") {
835
+ if (typeof input === "string" || input instanceof URL) {
789
836
  await space.send(avatar(input, options));
790
837
  return;
791
838
  }
@@ -1121,6 +1168,7 @@ export {
1121
1168
  readSchema,
1122
1169
  streamSchema,
1123
1170
  bufferToStream,
1171
+ fetchUrlBytes,
1124
1172
  attachmentSchema,
1125
1173
  asAttachment,
1126
1174
  attachment,
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  bufferToStream,
3
+ fetchUrlBytes,
3
4
  readSchema,
4
5
  streamSchema
5
- } from "./chunk-YDHES53X.js";
6
+ } from "./chunk-JTS25BT3.js";
6
7
 
7
8
  // src/content/voice.ts
8
9
  import { createReadStream } from "fs";
@@ -26,11 +27,23 @@ var resolveVoiceName = (input, name) => {
26
27
  if (name) {
27
28
  return name;
28
29
  }
30
+ if (input instanceof URL) {
31
+ return basename(input.pathname) || void 0;
32
+ }
29
33
  if (typeof input === "string") {
30
34
  return basename(input);
31
35
  }
32
36
  return;
33
37
  };
38
+ var resolveVoiceMimeHint = (input, name) => {
39
+ if (input instanceof URL) {
40
+ return basename(input.pathname) || void 0;
41
+ }
42
+ if (typeof input === "string") {
43
+ return basename(input);
44
+ }
45
+ return name;
46
+ };
34
47
  var resolveVoiceMimeType = (name, mimeType) => {
35
48
  if (mimeType) {
36
49
  if (!AUDIO_MIME_PATTERN.test(mimeType)) {
@@ -79,8 +92,16 @@ function voice(input, options) {
79
92
  return {
80
93
  build: async () => {
81
94
  const name = resolveVoiceName(input, options?.name);
82
- const mimeHint = typeof input === "string" ? basename(input) : name;
95
+ const mimeHint = resolveVoiceMimeHint(input, name);
83
96
  const mimeType = resolveVoiceMimeType(mimeHint, options?.mimeType);
97
+ if (input instanceof URL) {
98
+ return asVoice({
99
+ name,
100
+ mimeType,
101
+ duration: options?.duration,
102
+ read: async () => (await fetchUrlBytes(input)).data
103
+ });
104
+ }
84
105
  if (typeof input === "string") {
85
106
  const stats = await stat(input);
86
107
  if (!stats.isFile()) {
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  bufferToStream,
3
+ fetchUrlBytes,
3
4
  readSchema,
4
5
  resolveContents,
5
6
  streamSchema
6
- } from "./chunk-YDHES53X.js";
7
+ } from "./chunk-JTS25BT3.js";
7
8
 
8
9
  // src/content/group.ts
9
10
  import z from "zod";
@@ -82,24 +83,10 @@ var fetchLinkMetadata = async (url) => {
82
83
  return {};
83
84
  }
84
85
  };
85
- var fetchImage = async (url) => {
86
- const controller = new AbortController();
87
- const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);
88
- try {
89
- const res = await fetch(url, {
90
- signal: controller.signal,
91
- headers: { "User-Agent": USER_AGENT }
92
- });
93
- if (!res.ok) {
94
- throw new Error(`image fetch ${url} returned ${res.status}`);
95
- }
96
- const data = Buffer.from(await res.arrayBuffer());
97
- const mimeType = res.headers.get("content-type") ?? void 0;
98
- return { data, mimeType };
99
- } finally {
100
- clearTimeout(timer);
101
- }
102
- };
86
+ var fetchImage = (url) => fetchUrlBytes(new URL(url), {
87
+ timeoutMs: DEFAULT_TIMEOUT_MS,
88
+ headers: { "User-Agent": USER_AGENT }
89
+ });
103
90
 
104
91
  // src/content/richlink.ts
105
92
  var richlinkCoverSchema = z2.object({
@@ -2,7 +2,7 @@ import {
2
2
  asGroup,
3
3
  asRichlink,
4
4
  groupSchema
5
- } from "./chunk-UFJZIZDO.js";
5
+ } from "./chunk-TOJQ6DPE.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-L3VXHUVY.js";
19
+ } from "./chunk-YZ226L5Y.js";
20
20
  import {
21
21
  UnsupportedError,
22
22
  asAttachment,
@@ -29,7 +29,7 @@ import {
29
29
  reactionSchema,
30
30
  text,
31
31
  textSchema
32
- } from "./chunk-YDHES53X.js";
32
+ } from "./chunk-JTS25BT3.js";
33
33
 
34
34
  // src/providers/imessage/index.ts
35
35
  import { createClient as createClient2, MessageEffect as MessageEffect2 } from "@photon-ai/advanced-imessage";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  asVoice
3
- } from "./chunk-4TXLNBGE.js";
3
+ } from "./chunk-ODO6KRGX.js";
4
4
  import {
5
5
  asContact,
6
6
  fromVCard,
7
7
  toVCard
8
- } from "./chunk-L3VXHUVY.js";
8
+ } from "./chunk-YZ226L5Y.js";
9
9
  import {
10
10
  UnsupportedError,
11
11
  asAttachment,
12
12
  asCustom,
13
13
  definePlatform,
14
14
  reactionSchema
15
- } from "./chunk-YDHES53X.js";
15
+ } from "./chunk-JTS25BT3.js";
16
16
 
17
17
  // src/providers/terminal/index.ts
18
18
  import { spawn } from "child_process";
@@ -665,7 +665,7 @@ async function spectrumToProtocol(content) {
665
665
  }
666
666
  throw UnsupportedError.content(
667
667
  content.type,
668
- "terminal"
668
+ "Terminal"
669
669
  );
670
670
  }
671
671
  function protocolToSpectrum(p) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readSchema
3
- } from "./chunk-YDHES53X.js";
3
+ } from "./chunk-JTS25BT3.js";
4
4
 
5
5
  // src/utils/vcard.ts
6
6
  import vCard from "vcf";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-YKWKZ2PZ.js";
9
9
  import {
10
10
  asContact
11
- } from "./chunk-L3VXHUVY.js";
11
+ } from "./chunk-YZ226L5Y.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-YDHES53X.js";
19
+ } from "./chunk-JTS25BT3.js";
20
20
 
21
21
  // src/providers/whatsapp-business/index.ts
22
22
  import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
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-BzW4gInA.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-BzW4gInA.js';
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';
3
3
  import z__default from 'zod';
4
- import { P as PhotoInput } from './photo-content-BQF42prd.js';
4
+ import { P as PhotoInput } from './photo-content-BJKnqgN-.js';
5
5
  import vCard from 'vcf';
6
6
  import 'hotscript';
7
7
 
8
- declare function attachment(input: string | Buffer, options?: {
8
+ type AttachmentInput = string | Buffer | URL;
9
+ declare function attachment(input: AttachmentInput, options?: {
9
10
  mimeType?: string;
10
11
  name?: string;
11
12
  }): ContentBuilder;
@@ -39,6 +40,10 @@ type AvatarInput = PhotoInput;
39
40
  * - `avatar("clear")` — remove the current chat avatar.
40
41
  * - `avatar("./icon.png")` — set avatar from a filesystem path. MIME type is
41
42
  * inferred from the extension; override with `options.mimeType`.
43
+ * - `avatar(new URL("https://…/icon.png"))` — fetch the avatar lazily over
44
+ * the network. Bytes stay in memory (safe in read-only environments). MIME
45
+ * type is inferred from the URL pathname extension; override with
46
+ * `options.mimeType` when the URL has no usable extension.
42
47
  * - `avatar(buffer, { mimeType })` — set avatar from in-memory bytes.
43
48
  * `options.mimeType` is required (enforced at the type level).
44
49
  *
@@ -46,7 +51,7 @@ type AvatarInput = PhotoInput;
46
51
  * literally named `clear` with no extension, pass `"./clear"` or load it as a
47
52
  * Buffer.
48
53
  */
49
- declare function avatar(input: string, options?: {
54
+ declare function avatar(input: string | URL, options?: {
50
55
  mimeType?: string;
51
56
  }): ContentBuilder;
52
57
  declare function avatar(input: Buffer, options: {
@@ -874,7 +879,8 @@ declare const voiceSchema: z__default.ZodObject<{
874
879
  stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
875
880
  }, z__default.core.$strip>;
876
881
  type Voice = z__default.infer<typeof voiceSchema>;
877
- declare function voice(input: string | Buffer, options?: {
882
+ type VoiceInput = string | Buffer | URL;
883
+ declare function voice(input: VoiceInput, options?: {
878
884
  mimeType?: string;
879
885
  name?: string;
880
886
  duration?: number;
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  group,
3
3
  richlink
4
- } from "./chunk-UFJZIZDO.js";
4
+ } from "./chunk-TOJQ6DPE.js";
5
5
  import {
6
6
  voice
7
- } from "./chunk-4TXLNBGE.js";
7
+ } from "./chunk-ODO6KRGX.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-L3VXHUVY.js";
23
+ } from "./chunk-YZ226L5Y.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-YDHES53X.js";
41
+ } from "./chunk-JTS25BT3.js";
42
42
 
43
43
  // src/emoji/generated.ts
44
44
  var GeneratedEmoji = {
@@ -2311,7 +2311,9 @@ async function Spectrum(options) {
2311
2311
  ];
2312
2312
  process.off("SIGINT", handleSignal);
2313
2313
  process.off("SIGTERM", handleSignal);
2314
+ const streamCloseStart = performance.now();
2314
2315
  await Promise.allSettled(streamShutdowns);
2316
+ const streamCloseMs = Math.round(performance.now() - streamCloseStart);
2315
2317
  const clientShutdowns = [];
2316
2318
  for (const state of platformStates.values()) {
2317
2319
  const destroy = state.definition.lifecycle.destroyClient;
@@ -2331,11 +2333,17 @@ async function Spectrum(options) {
2331
2333
  )
2332
2334
  );
2333
2335
  }
2336
+ const clientCloseStart = performance.now();
2334
2337
  await Promise.allSettled(clientShutdowns);
2338
+ const clientCloseMs = Math.round(performance.now() - clientCloseStart);
2335
2339
  customEventStreams.clear();
2336
2340
  messageBroadcasters.clear();
2337
2341
  platformStates.clear();
2338
- lifecycleLog.info("Spectrum stopped", { providers: providerNames });
2342
+ lifecycleLog.info("Spectrum stopped", {
2343
+ providers: providerNames,
2344
+ streamCloseMs,
2345
+ clientCloseMs
2346
+ });
2339
2347
  if (otelHandle) {
2340
2348
  await otelHandle.shutdown();
2341
2349
  }
@@ -8,6 +8,6 @@
8
8
  * and any DX fix (mime inference, read caching, sentinel docs) lands once.
9
9
  */
10
10
  declare const CLEAR_SENTINEL: "clear";
11
- type PhotoInput = typeof CLEAR_SENTINEL | string | Buffer;
11
+ type PhotoInput = typeof CLEAR_SENTINEL | string | Buffer | URL;
12
12
 
13
13
  export type { PhotoInput as P };
@@ -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-BzW4gInA.js';
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';
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-BQF42prd.js';
5
+ import { P as PhotoInput } from '../../photo-content-BJKnqgN-.js';
6
6
  import { MessageEffect, AdvancedIMessage } from '@photon-ai/advanced-imessage';
7
7
  import { IMessageSDK } from '@photon-ai/imessage-kit';
8
8
  import 'hotscript';
@@ -14,6 +14,10 @@ type BackgroundInput = PhotoInput;
14
14
  * - `background("clear")` — remove the current chat background.
15
15
  * - `background("./photo.jpg")` — set background from a filesystem path.
16
16
  * MIME type is inferred from the extension; override with `options.mimeType`.
17
+ * - `background(new URL("https://…/photo.jpg"))` — fetch the background
18
+ * lazily over the network. Bytes stay in memory (safe in read-only
19
+ * environments). MIME type is inferred from the URL pathname extension;
20
+ * override with `options.mimeType` when the URL has no usable extension.
17
21
  * - `background(buffer, { mimeType })` — set background from in-memory bytes.
18
22
  * `options.mimeType` is required.
19
23
  *
@@ -30,7 +34,7 @@ type BackgroundInput = PhotoInput;
30
34
  * The framework treats it as a fire-and-forget control signal at runtime.
31
35
  */
32
36
  declare function background(input: "clear"): ContentBuilder;
33
- declare function background(input: string | Buffer, options?: {
37
+ declare function background(input: string | Buffer | URL, options?: {
34
38
  mimeType?: string;
35
39
  }): ContentBuilder;
36
40
 
@@ -3,12 +3,12 @@ import {
3
3
  effect,
4
4
  imessage,
5
5
  read
6
- } from "../../chunk-FPYXHZZA.js";
7
- import "../../chunk-UFJZIZDO.js";
6
+ } from "../../chunk-UGBHJEX2.js";
7
+ import "../../chunk-TOJQ6DPE.js";
8
8
  import "../../chunk-KO67KDBD.js";
9
9
  import "../../chunk-YKWKZ2PZ.js";
10
- import "../../chunk-L3VXHUVY.js";
11
- import "../../chunk-YDHES53X.js";
10
+ import "../../chunk-YZ226L5Y.js";
11
+ import "../../chunk-JTS25BT3.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-BzW4gInA.js';
5
+ import '../types-CtsphK2p.js';
6
6
  import 'hotscript';
7
7
  import 'zod';
8
8
  import 'zod/v4/core';
9
- import '../photo-content-BQF42prd.js';
9
+ import '../photo-content-BJKnqgN-.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-FPYXHZZA.js";
4
- import "../chunk-UFJZIZDO.js";
3
+ } from "../chunk-UGBHJEX2.js";
4
+ import "../chunk-TOJQ6DPE.js";
5
5
  import {
6
6
  slack
7
- } from "../chunk-E7AXYNOZ.js";
7
+ } from "../chunk-5HNHMI6L.js";
8
8
  import {
9
9
  terminal
10
- } from "../chunk-ZGWANTLX.js";
11
- import "../chunk-4TXLNBGE.js";
10
+ } from "../chunk-VTQWVJZ5.js";
11
+ import "../chunk-ODO6KRGX.js";
12
12
  import {
13
13
  whatsappBusiness
14
- } from "../chunk-VQOW7X7U.js";
14
+ } from "../chunk-ZUQYLYGI.js";
15
15
  import "../chunk-KO67KDBD.js";
16
16
  import "../chunk-YKWKZ2PZ.js";
17
- import "../chunk-L3VXHUVY.js";
18
- import "../chunk-YDHES53X.js";
17
+ import "../chunk-YZ226L5Y.js";
18
+ import "../chunk-JTS25BT3.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-BzW4gInA.js';
1
+ import { S as SchemaMessage, P as Platform, a as PlatformDef } from '../../types-CtsphK2p.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';
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  slack
3
- } from "../../chunk-E7AXYNOZ.js";
3
+ } from "../../chunk-5HNHMI6L.js";
4
4
  import "../../chunk-YKWKZ2PZ.js";
5
- import "../../chunk-YDHES53X.js";
5
+ import "../../chunk-JTS25BT3.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-BzW4gInA.js';
1
+ import { P as Platform, a as PlatformDef, M as Message, U as User, b as Space } from '../../types-CtsphK2p.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,15 @@ 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
- } | {
113
110
  type: "attachment";
114
111
  name: string;
115
112
  mimeType: string;
116
113
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
117
114
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
118
115
  size?: number | undefined;
116
+ } | {
117
+ type: "text";
118
+ text: string;
119
119
  } | {
120
120
  type: "custom";
121
121
  raw: unknown;
@@ -210,15 +210,15 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
210
210
  } | {
211
211
  type: "effect";
212
212
  content: {
213
- type: "text";
214
- text: string;
215
- } | {
216
213
  type: "attachment";
217
214
  name: string;
218
215
  mimeType: string;
219
216
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
220
217
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
221
218
  size?: number | undefined;
219
+ } | {
220
+ type: "text";
221
+ text: string;
222
222
  };
223
223
  effect: string;
224
224
  } | {
@@ -237,17 +237,17 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
237
237
  kind: "clear";
238
238
  };
239
239
  } | {
240
- type: "edit";
240
+ type: "reply";
241
241
  content: {
242
- type: "text";
243
- text: string;
244
- } | {
245
242
  type: "attachment";
246
243
  name: string;
247
244
  mimeType: string;
248
245
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
249
246
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
250
247
  size?: number | undefined;
248
+ } | {
249
+ type: "text";
250
+ text: string;
251
251
  } | {
252
252
  type: "custom";
253
253
  raw: unknown;
@@ -342,15 +342,15 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
342
342
  } | {
343
343
  type: "effect";
344
344
  content: {
345
- type: "text";
346
- text: string;
347
- } | {
348
345
  type: "attachment";
349
346
  name: string;
350
347
  mimeType: string;
351
348
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
352
349
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
353
350
  size?: number | undefined;
351
+ } | {
352
+ type: "text";
353
+ text: string;
354
354
  };
355
355
  effect: string;
356
356
  } | {
@@ -371,17 +371,17 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
371
371
  };
372
372
  target: Message<string, User, Space<unknown>>;
373
373
  } | {
374
- type: "reply";
374
+ type: "edit";
375
375
  content: {
376
- type: "text";
377
- text: string;
378
- } | {
379
376
  type: "attachment";
380
377
  name: string;
381
378
  mimeType: string;
382
379
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
383
380
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
384
381
  size?: number | undefined;
382
+ } | {
383
+ type: "text";
384
+ text: string;
385
385
  } | {
386
386
  type: "custom";
387
387
  raw: unknown;
@@ -476,15 +476,15 @@ declare const terminal: Platform<PlatformDef<"Terminal", z__default.ZodObject<{
476
476
  } | {
477
477
  type: "effect";
478
478
  content: {
479
- type: "text";
480
- text: string;
481
- } | {
482
479
  type: "attachment";
483
480
  name: string;
484
481
  mimeType: string;
485
482
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
486
483
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
487
484
  size?: number | undefined;
485
+ } | {
486
+ type: "text";
487
+ text: string;
488
488
  };
489
489
  effect: string;
490
490
  } | {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  terminal
3
- } from "../../chunk-ZGWANTLX.js";
4
- import "../../chunk-4TXLNBGE.js";
5
- import "../../chunk-L3VXHUVY.js";
6
- import "../../chunk-YDHES53X.js";
3
+ } from "../../chunk-VTQWVJZ5.js";
4
+ import "../../chunk-ODO6KRGX.js";
5
+ import "../../chunk-YZ226L5Y.js";
6
+ import "../../chunk-JTS25BT3.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-BzW4gInA.js';
1
+ import { S as SchemaMessage, P as Platform, a as PlatformDef } from '../../types-CtsphK2p.js';
2
2
  import { WhatsAppClient } from '@photon-ai/whatsapp-business';
3
3
  import * as z from 'zod';
4
4
  import z__default from 'zod';
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  whatsappBusiness
3
- } from "../../chunk-VQOW7X7U.js";
3
+ } from "../../chunk-ZUQYLYGI.js";
4
4
  import "../../chunk-KO67KDBD.js";
5
5
  import "../../chunk-YKWKZ2PZ.js";
6
- import "../../chunk-L3VXHUVY.js";
7
- import "../../chunk-YDHES53X.js";
6
+ import "../../chunk-YZ226L5Y.js";
7
+ import "../../chunk-JTS25BT3.js";
8
8
  export {
9
9
  whatsappBusiness
10
10
  };
@@ -700,13 +700,16 @@ interface Space<_Def = unknown> {
700
700
  * - `space.avatar("clear")` — remove the current avatar.
701
701
  * - `space.avatar("./icon.png")` — set from a filesystem path; MIME type
702
702
  * is inferred from the extension.
703
+ * - `space.avatar(new URL("https://…/icon.png"))` — fetch the avatar
704
+ * lazily over the network. Bytes stay in memory (safe in read-only
705
+ * environments); MIME type is inferred from the URL pathname extension.
703
706
  * - `space.avatar(buffer, { mimeType })` — set from in-memory bytes;
704
707
  * `mimeType` is required (enforced at the type level).
705
708
  *
706
709
  * Universal API; per-platform constraints (e.g. iMessage: remote + group
707
710
  * only) surface as `UnsupportedError` from the provider's send action.
708
711
  */
709
- avatar(input: string, options?: {
712
+ avatar(input: string | URL, options?: {
710
713
  mimeType?: string;
711
714
  }): Promise<void>;
712
715
  avatar(input: Buffer, options: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "description": "Bring agents to any interface — unified messaging SDK for TypeScript.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "./manifest.json": "./dist/manifest.json"
35
35
  },
36
36
  "dependencies": {
37
- "@photon-ai/advanced-imessage": "^0.9.0",
37
+ "@photon-ai/advanced-imessage": "^0.10.0",
38
38
  "@photon-ai/imessage-kit": "^3.0.0",
39
39
  "@photon-ai/otel": "^0.1.1",
40
40
  "@photon-ai/slack": "^0.2.0",