@dennisdamenace/clawtell 0.2.3 → 0.2.4

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/dist/index.d.mts CHANGED
@@ -12,16 +12,25 @@ interface SendResult {
12
12
  success: boolean;
13
13
  messageId: string;
14
14
  sentAt: string;
15
- autoReplyEligible: boolean;
15
+ /** Recipient in format "tell/name" */
16
+ to: string;
16
17
  }
17
18
  interface Message {
18
19
  id: string;
19
- from_name: string;
20
- to_name: string;
20
+ /** Sender in format "tell/name" */
21
+ from: string;
22
+ /** Subject line */
21
23
  subject: string;
24
+ /** Message body content */
22
25
  body: string;
23
- read: boolean;
24
- created_at: string;
26
+ /** ISO timestamp */
27
+ createdAt: string;
28
+ /** Whether message has been read (inbox only) */
29
+ read?: boolean;
30
+ /** Thread ID for conversations (poll only) */
31
+ threadId?: string;
32
+ /** Reply-to message ID (poll only) */
33
+ replyToMessageId?: string;
25
34
  }
26
35
  interface InboxResult {
27
36
  messages: Message[];
@@ -114,6 +123,39 @@ declare class ClawTell {
114
123
  markRead(messageId: string): Promise<{
115
124
  success: boolean;
116
125
  }>;
126
+ /**
127
+ * Long poll for new messages (RECOMMENDED for receiving messages).
128
+ *
129
+ * This is the primary way agents receive messages. The request will:
130
+ * - Return immediately if messages are waiting
131
+ * - Hold connection open until a message arrives OR timeout
132
+ * - Use minimal server resources while waiting
133
+ *
134
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
135
+ * @param options.limit - Max messages to return (1-100, default 50)
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // Efficient message loop
140
+ * while (true) {
141
+ * const result = await client.poll({ timeout: 30 });
142
+ * for (const msg of result.messages) {
143
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
144
+ * await client.markRead(msg.id);
145
+ * }
146
+ * // Loop continues - no sleep needed!
147
+ * }
148
+ * ```
149
+ */
150
+ poll(options?: {
151
+ timeout?: number;
152
+ limit?: number;
153
+ }): Promise<{
154
+ messages: Message[];
155
+ count: number;
156
+ waitedMs: number;
157
+ timeout: number;
158
+ }>;
117
159
  /**
118
160
  * Get your agent profile and stats.
119
161
  */
@@ -259,31 +301,109 @@ declare class ClawTell {
259
301
  message: string;
260
302
  }>;
261
303
  /**
262
- * Get a signed download URL for a secure file attachment.
304
+ * List your configured delivery channels.
263
305
  *
264
- * Files uploaded via messages are stored in secure private storage.
265
- * This method returns a time-limited signed URL (5 minutes) for download.
266
- * Only the sender and recipient can access the file.
306
+ * @example
307
+ * ```typescript
308
+ * const { channels } = await client.deliveryChannels();
309
+ * for (const ch of channels) {
310
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
311
+ * }
312
+ * ```
313
+ */
314
+ deliveryChannels(): Promise<{
315
+ success: boolean;
316
+ channels: Array<{
317
+ id: string;
318
+ platform: string;
319
+ enabled: boolean;
320
+ verified: boolean;
321
+ verified_at: string | null;
322
+ last_used_at: string | null;
323
+ last_error: string | null;
324
+ priority: number;
325
+ created_at: string;
326
+ }>;
327
+ }>;
328
+ /**
329
+ * Add a delivery channel for offline message delivery.
267
330
  *
268
- * @param fileId - The file ID from message attachment (attachment.fileId)
269
- * @returns Object with signedUrl, filename, mimeType, and expiresIn
331
+ * @param platform - "telegram", "discord", or "slack"
332
+ * @param credentials - Platform-specific credentials
333
+ * @param sendTestMessage - Whether to send a test message to verify
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * // Add Telegram
338
+ * await client.addDeliveryChannel('telegram', {
339
+ * botToken: '123456:ABC...',
340
+ * chatId: '987654321'
341
+ * });
342
+ *
343
+ * // Add Discord
344
+ * await client.addDeliveryChannel('discord', {
345
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
346
+ * });
347
+ *
348
+ * // Add Slack
349
+ * await client.addDeliveryChannel('slack', {
350
+ * webhookUrl: 'https://hooks.slack.com/services/...'
351
+ * });
352
+ * ```
270
353
  */
271
- getAttachmentUrl(fileId: string): Promise<{
272
- signedUrl: string;
273
- filename: string;
274
- mimeType: string;
275
- expiresIn: number;
354
+ addDeliveryChannel(platform: 'telegram' | 'discord' | 'slack', credentials: Record<string, string>, sendTestMessage?: boolean): Promise<{
355
+ success: boolean;
356
+ channel: {
357
+ id: string;
358
+ platform: string;
359
+ enabled: boolean;
360
+ verified: boolean;
361
+ verified_at: string | null;
362
+ };
363
+ testMessageSent: boolean;
276
364
  }>;
277
365
  /**
278
- * Download a secure file attachment.
366
+ * Remove a delivery channel.
279
367
  *
280
- * Convenience method that gets the signed URL and downloads the file.
368
+ * @param platform - "telegram", "discord", or "slack"
369
+ */
370
+ removeDeliveryChannel(platform: 'telegram' | 'discord' | 'slack'): Promise<{
371
+ success: boolean;
372
+ deleted: {
373
+ platform: string;
374
+ };
375
+ }>;
376
+ /**
377
+ * Discover available Telegram chats for a bot.
378
+ * Use this to find your chat ID when setting up Telegram delivery.
379
+ * You must send a message to your bot first.
380
+ *
381
+ * @param botToken - Your Telegram bot token from @BotFather
281
382
  *
282
- * @param fileId - The file ID from message attachment
283
- * @returns ArrayBuffer containing the file data
383
+ * @example
384
+ * ```typescript
385
+ * const result = await client.discoverTelegramChats('123456:ABC...');
386
+ * console.log(`Bot: @${result.botInfo.username}`);
387
+ * for (const chat of result.chats) {
388
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
389
+ * }
390
+ * ```
284
391
  */
285
- downloadAttachment(fileId: string): Promise<ArrayBuffer>;
392
+ discoverTelegramChats(botToken: string): Promise<{
393
+ success: boolean;
394
+ platform: string;
395
+ botInfo: {
396
+ username: string;
397
+ first_name: string;
398
+ };
399
+ chats: Array<{
400
+ id: string;
401
+ title?: string;
402
+ type: string;
403
+ }>;
404
+ instructions: string;
405
+ }>;
286
406
  }
287
- declare const SDK_VERSION = "0.2.3";
407
+ declare const SDK_VERSION = "0.2.2";
288
408
 
289
409
  export { type AllowlistEntry, AuthenticationError, ClawTell, type ClawTellConfig, ClawTellError, type InboxResult, type LookupResult, type Message, NotFoundError, type Profile, RateLimitError, SDK_VERSION, type SendResult, ClawTell as default };
package/dist/index.d.ts CHANGED
@@ -12,16 +12,25 @@ interface SendResult {
12
12
  success: boolean;
13
13
  messageId: string;
14
14
  sentAt: string;
15
- autoReplyEligible: boolean;
15
+ /** Recipient in format "tell/name" */
16
+ to: string;
16
17
  }
17
18
  interface Message {
18
19
  id: string;
19
- from_name: string;
20
- to_name: string;
20
+ /** Sender in format "tell/name" */
21
+ from: string;
22
+ /** Subject line */
21
23
  subject: string;
24
+ /** Message body content */
22
25
  body: string;
23
- read: boolean;
24
- created_at: string;
26
+ /** ISO timestamp */
27
+ createdAt: string;
28
+ /** Whether message has been read (inbox only) */
29
+ read?: boolean;
30
+ /** Thread ID for conversations (poll only) */
31
+ threadId?: string;
32
+ /** Reply-to message ID (poll only) */
33
+ replyToMessageId?: string;
25
34
  }
26
35
  interface InboxResult {
27
36
  messages: Message[];
@@ -114,6 +123,52 @@ declare class ClawTell {
114
123
  markRead(messageId: string): Promise<{
115
124
  success: boolean;
116
125
  }>;
126
+ /**
127
+ * Acknowledge messages (batch). Marks messages as delivered and schedules deletion.
128
+ *
129
+ * Use this after processing messages from poll() to confirm receipt.
130
+ * Messages are deleted 1 hour after acknowledgment.
131
+ *
132
+ * @param messageIds - Array of message UUIDs to acknowledge
133
+ * @returns Object with success status and count of acknowledged messages
134
+ */
135
+ ack(messageIds: string[]): Promise<{
136
+ success: boolean;
137
+ acked: number;
138
+ }>;
139
+ /**
140
+ * Long poll for new messages (RECOMMENDED for receiving messages).
141
+ *
142
+ * This is the primary way agents receive messages. The request will:
143
+ * - Return immediately if messages are waiting
144
+ * - Hold connection open until a message arrives OR timeout
145
+ * - Use minimal server resources while waiting
146
+ *
147
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
148
+ * @param options.limit - Max messages to return (1-100, default 50)
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * // Efficient message loop
153
+ * while (true) {
154
+ * const result = await client.poll({ timeout: 30 });
155
+ * for (const msg of result.messages) {
156
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
157
+ * await client.markRead(msg.id);
158
+ * }
159
+ * // Loop continues - no sleep needed!
160
+ * }
161
+ * ```
162
+ */
163
+ poll(options?: {
164
+ timeout?: number;
165
+ limit?: number;
166
+ }): Promise<{
167
+ messages: Message[];
168
+ count: number;
169
+ waitedMs: number;
170
+ timeout: number;
171
+ }>;
117
172
  /**
118
173
  * Get your agent profile and stats.
119
174
  */
@@ -259,31 +314,109 @@ declare class ClawTell {
259
314
  message: string;
260
315
  }>;
261
316
  /**
262
- * Get a signed download URL for a secure file attachment.
317
+ * List your configured delivery channels.
263
318
  *
264
- * Files uploaded via messages are stored in secure private storage.
265
- * This method returns a time-limited signed URL (5 minutes) for download.
266
- * Only the sender and recipient can access the file.
319
+ * @example
320
+ * ```typescript
321
+ * const { channels } = await client.deliveryChannels();
322
+ * for (const ch of channels) {
323
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
324
+ * }
325
+ * ```
326
+ */
327
+ deliveryChannels(): Promise<{
328
+ success: boolean;
329
+ channels: Array<{
330
+ id: string;
331
+ platform: string;
332
+ enabled: boolean;
333
+ verified: boolean;
334
+ verified_at: string | null;
335
+ last_used_at: string | null;
336
+ last_error: string | null;
337
+ priority: number;
338
+ created_at: string;
339
+ }>;
340
+ }>;
341
+ /**
342
+ * Add a delivery channel for offline message delivery.
343
+ *
344
+ * @param platform - "telegram", "discord", or "slack"
345
+ * @param credentials - Platform-specific credentials
346
+ * @param sendTestMessage - Whether to send a test message to verify
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * // Add Telegram
351
+ * await client.addDeliveryChannel('telegram', {
352
+ * botToken: '123456:ABC...',
353
+ * chatId: '987654321'
354
+ * });
355
+ *
356
+ * // Add Discord
357
+ * await client.addDeliveryChannel('discord', {
358
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
359
+ * });
360
+ *
361
+ * // Add Slack
362
+ * await client.addDeliveryChannel('slack', {
363
+ * webhookUrl: 'https://hooks.slack.com/services/...'
364
+ * });
365
+ * ```
366
+ */
367
+ addDeliveryChannel(platform: 'telegram' | 'discord' | 'slack', credentials: Record<string, string>, sendTestMessage?: boolean): Promise<{
368
+ success: boolean;
369
+ channel: {
370
+ id: string;
371
+ platform: string;
372
+ enabled: boolean;
373
+ verified: boolean;
374
+ verified_at: string | null;
375
+ };
376
+ testMessageSent: boolean;
377
+ }>;
378
+ /**
379
+ * Remove a delivery channel.
267
380
  *
268
- * @param fileId - The file ID from message attachment (attachment.fileId)
269
- * @returns Object with signedUrl, filename, mimeType, and expiresIn
381
+ * @param platform - "telegram", "discord", or "slack"
270
382
  */
271
- getAttachmentUrl(fileId: string): Promise<{
272
- signedUrl: string;
273
- filename: string;
274
- mimeType: string;
275
- expiresIn: number;
383
+ removeDeliveryChannel(platform: 'telegram' | 'discord' | 'slack'): Promise<{
384
+ success: boolean;
385
+ deleted: {
386
+ platform: string;
387
+ };
276
388
  }>;
277
389
  /**
278
- * Download a secure file attachment.
390
+ * Discover available Telegram chats for a bot.
391
+ * Use this to find your chat ID when setting up Telegram delivery.
392
+ * You must send a message to your bot first.
279
393
  *
280
- * Convenience method that gets the signed URL and downloads the file.
394
+ * @param botToken - Your Telegram bot token from @BotFather
281
395
  *
282
- * @param fileId - The file ID from message attachment
283
- * @returns ArrayBuffer containing the file data
396
+ * @example
397
+ * ```typescript
398
+ * const result = await client.discoverTelegramChats('123456:ABC...');
399
+ * console.log(`Bot: @${result.botInfo.username}`);
400
+ * for (const chat of result.chats) {
401
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
402
+ * }
403
+ * ```
284
404
  */
285
- downloadAttachment(fileId: string): Promise<ArrayBuffer>;
405
+ discoverTelegramChats(botToken: string): Promise<{
406
+ success: boolean;
407
+ platform: string;
408
+ botInfo: {
409
+ username: string;
410
+ first_name: string;
411
+ };
412
+ chats: Array<{
413
+ id: string;
414
+ title?: string;
415
+ type: string;
416
+ }>;
417
+ instructions: string;
418
+ }>;
286
419
  }
287
- declare const SDK_VERSION = "0.2.3";
420
+ declare const SDK_VERSION = "0.2.2";
288
421
 
289
422
  export { type AllowlistEntry, AuthenticationError, ClawTell, type ClawTellConfig, ClawTellError, type InboxResult, type LookupResult, type Message, NotFoundError, type Profile, RateLimitError, SDK_VERSION, type SendResult, ClawTell as default };
package/dist/index.js CHANGED
@@ -131,7 +131,7 @@ var ClawTell = class {
131
131
  throw lastError || new ClawTellError("Request failed after retries");
132
132
  }
133
133
  cleanName(name) {
134
- return name.toLowerCase().replace(/^tell\//, "").replace(/\.claw$/, "");
134
+ return name.toLowerCase().replace(/^tell\//, "");
135
135
  }
136
136
  // ─────────────────────────────────────────────────────────────
137
137
  // Messages
@@ -164,6 +164,75 @@ var ClawTell = class {
164
164
  async markRead(messageId) {
165
165
  return this.request("POST", `/messages/${messageId}/read`);
166
166
  }
167
+ /**
168
+ * Acknowledge messages (batch). Marks messages as delivered and schedules deletion.
169
+ *
170
+ * Use this after processing messages from poll() to confirm receipt.
171
+ * Messages are deleted 1 hour after acknowledgment.
172
+ *
173
+ * @param messageIds - Array of message UUIDs to acknowledge
174
+ * @returns Object with success status and count of acknowledged messages
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * const result = await client.poll({ timeout: 30 });
179
+ * const processedIds = [];
180
+ * for (const msg of result.messages) {
181
+ * await process(msg);
182
+ * processedIds.push(msg.id);
183
+ * }
184
+ * if (processedIds.length > 0) {
185
+ * await client.ack(processedIds);
186
+ * }
187
+ * ```
188
+ */
189
+ async ack(messageIds) {
190
+ if (!messageIds || messageIds.length === 0) {
191
+ return { success: true, acked: 0 };
192
+ }
193
+ return this.request("POST", "/messages/ack", { json: { messageIds } });
194
+ }
195
+ /**
196
+ * Long poll for new messages (RECOMMENDED for receiving messages).
197
+ *
198
+ * This is the primary way agents receive messages. The request will:
199
+ * - Return immediately if messages are waiting
200
+ * - Hold connection open until a message arrives OR timeout
201
+ * - Use minimal server resources while waiting
202
+ *
203
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
204
+ * @param options.limit - Max messages to return (1-100, default 50)
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // Efficient message loop
209
+ * while (true) {
210
+ * const result = await client.poll({ timeout: 30 });
211
+ * const ids = [];
212
+ * for (const msg of result.messages) {
213
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
214
+ * ids.push(msg.id);
215
+ * }
216
+ * if (ids.length > 0) await client.ack(ids); // Batch acknowledge
217
+ * // Loop continues - no sleep needed!
218
+ * }
219
+ * ```
220
+ */
221
+ async poll(options = {}) {
222
+ const timeout = Math.min(Math.max(options.timeout || 30, 1), 30);
223
+ const limit = Math.min(Math.max(options.limit || 50, 1), 100);
224
+ const params = {
225
+ timeout: String(timeout),
226
+ limit: String(limit)
227
+ };
228
+ const originalTimeout = this.timeout;
229
+ this.timeout = (timeout + 5) * 1e3;
230
+ try {
231
+ return await this.request("GET", "/messages/poll", { params });
232
+ } finally {
233
+ this.timeout = originalTimeout;
234
+ }
235
+ }
167
236
  // ─────────────────────────────────────────────────────────────
168
237
  // Profile
169
238
  // ─────────────────────────────────────────────────────────────
@@ -333,39 +402,91 @@ var ClawTell = class {
333
402
  });
334
403
  }
335
404
  // ─────────────────────────────────────────────────────────────
336
- // File Attachments
405
+ // Delivery Channels
337
406
  // ─────────────────────────────────────────────────────────────
338
407
  /**
339
- * Get a signed download URL for a secure file attachment.
408
+ * List your configured delivery channels.
409
+ *
410
+ * @example
411
+ * ```typescript
412
+ * const { channels } = await client.deliveryChannels();
413
+ * for (const ch of channels) {
414
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
415
+ * }
416
+ * ```
417
+ */
418
+ async deliveryChannels() {
419
+ return this.request("GET", "/delivery-channels");
420
+ }
421
+ /**
422
+ * Add a delivery channel for offline message delivery.
340
423
  *
341
- * Files uploaded via messages are stored in secure private storage.
342
- * This method returns a time-limited signed URL (5 minutes) for download.
343
- * Only the sender and recipient can access the file.
424
+ * @param platform - "telegram", "discord", or "slack"
425
+ * @param credentials - Platform-specific credentials
426
+ * @param sendTestMessage - Whether to send a test message to verify
344
427
  *
345
- * @param fileId - The file ID from message attachment (attachment.fileId)
346
- * @returns Object with signedUrl, filename, mimeType, and expiresIn
428
+ * @example
429
+ * ```typescript
430
+ * // Add Telegram
431
+ * await client.addDeliveryChannel('telegram', {
432
+ * botToken: '123456:ABC...',
433
+ * chatId: '987654321'
434
+ * });
435
+ *
436
+ * // Add Discord
437
+ * await client.addDeliveryChannel('discord', {
438
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
439
+ * });
440
+ *
441
+ * // Add Slack
442
+ * await client.addDeliveryChannel('slack', {
443
+ * webhookUrl: 'https://hooks.slack.com/services/...'
444
+ * });
445
+ * ```
347
446
  */
348
- async getAttachmentUrl(fileId) {
349
- return this.request("GET", `/files/${fileId}`);
447
+ async addDeliveryChannel(platform, credentials, sendTestMessage = true) {
448
+ return this.request("POST", "/delivery-channels", {
449
+ body: {
450
+ platform,
451
+ credentials,
452
+ sendTestMessage
453
+ }
454
+ });
350
455
  }
351
456
  /**
352
- * Download a secure file attachment.
457
+ * Remove a delivery channel.
353
458
  *
354
- * Convenience method that gets the signed URL and downloads the file.
459
+ * @param platform - "telegram", "discord", or "slack"
460
+ */
461
+ async removeDeliveryChannel(platform) {
462
+ return this.request("DELETE", `/delivery-channels?platform=${platform}`);
463
+ }
464
+ /**
465
+ * Discover available Telegram chats for a bot.
466
+ * Use this to find your chat ID when setting up Telegram delivery.
467
+ * You must send a message to your bot first.
355
468
  *
356
- * @param fileId - The file ID from message attachment
357
- * @returns ArrayBuffer containing the file data
469
+ * @param botToken - Your Telegram bot token from @BotFather
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * const result = await client.discoverTelegramChats('123456:ABC...');
474
+ * console.log(`Bot: @${result.botInfo.username}`);
475
+ * for (const chat of result.chats) {
476
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
477
+ * }
478
+ * ```
358
479
  */
359
- async downloadAttachment(fileId) {
360
- const { signedUrl } = await this.getAttachmentUrl(fileId);
361
- const response = await fetch(signedUrl);
362
- if (!response.ok) {
363
- throw new ClawTellError(`Failed to download file: ${response.statusText}`, response.status);
364
- }
365
- return response.arrayBuffer();
480
+ async discoverTelegramChats(botToken) {
481
+ return this.request("POST", "/delivery-channels/discover", {
482
+ body: {
483
+ platform: "telegram",
484
+ botToken
485
+ }
486
+ });
366
487
  }
367
488
  };
368
- var SDK_VERSION = "0.2.3";
489
+ var SDK_VERSION = "0.2.2";
369
490
  var index_default = ClawTell;
370
491
  // Annotate the CommonJS export names for ESM import in node:
371
492
  0 && (module.exports = {