@meet-ai/cli 0.0.8 → 0.0.10
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.js +251 -24
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
2
4
|
|
|
3
5
|
// src/client.ts
|
|
4
6
|
function wsLog(data) {
|
|
@@ -17,26 +19,43 @@ async function withRetry(fn, options) {
|
|
|
17
19
|
const maxRetries = options?.maxRetries ?? 3;
|
|
18
20
|
const baseDelay = options?.baseDelay ?? 1000;
|
|
19
21
|
const shouldRetry = options?.shouldRetry ?? isRetryable;
|
|
20
|
-
let lastError;
|
|
22
|
+
let lastError = new Error("withRetry: no attempts made");
|
|
21
23
|
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
22
24
|
try {
|
|
23
25
|
return await fn();
|
|
24
|
-
} catch (
|
|
25
|
-
lastError =
|
|
26
|
-
if (attempt >= maxRetries || !shouldRetry(
|
|
27
|
-
throw
|
|
26
|
+
} catch (error) {
|
|
27
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
28
|
+
if (attempt >= maxRetries || !shouldRetry(error))
|
|
29
|
+
throw lastError;
|
|
28
30
|
const delay = baseDelay * 2 ** attempt;
|
|
29
31
|
console.error(JSON.stringify({
|
|
30
32
|
event: "retry",
|
|
31
33
|
attempt: attempt + 1,
|
|
32
34
|
delay_ms: delay,
|
|
33
|
-
error:
|
|
35
|
+
error: lastError.message
|
|
34
36
|
}));
|
|
35
|
-
await new Promise((
|
|
37
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
throw lastError;
|
|
39
41
|
}
|
|
42
|
+
var ATTACHMENTS_DIR = "/tmp/meet-ai-attachments";
|
|
43
|
+
var MAX_AGE_MS = 5 * 60 * 1000;
|
|
44
|
+
function cleanupOldAttachments() {
|
|
45
|
+
try {
|
|
46
|
+
const { readdirSync, statSync, unlinkSync } = __require("node:fs");
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
for (const entry of readdirSync(ATTACHMENTS_DIR)) {
|
|
49
|
+
try {
|
|
50
|
+
const filePath = `${ATTACHMENTS_DIR}/${entry}`;
|
|
51
|
+
const mtime = statSync(filePath).mtimeMs;
|
|
52
|
+
if (now - mtime > MAX_AGE_MS) {
|
|
53
|
+
unlinkSync(filePath);
|
|
54
|
+
}
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
40
59
|
function createClient(baseUrl, apiKey) {
|
|
41
60
|
function headers(extra) {
|
|
42
61
|
const h = { "Content-Type": "application/json", ...extra };
|
|
@@ -213,6 +232,45 @@ function createClient(baseUrl, apiKey) {
|
|
|
213
232
|
return res.text();
|
|
214
233
|
});
|
|
215
234
|
},
|
|
235
|
+
async sendTasks(roomId, payload) {
|
|
236
|
+
return withRetry(async () => {
|
|
237
|
+
const res = await fetch(`${baseUrl}/api/rooms/${roomId}/tasks`, {
|
|
238
|
+
method: "POST",
|
|
239
|
+
headers: headers(),
|
|
240
|
+
body: payload
|
|
241
|
+
});
|
|
242
|
+
if (!res.ok) {
|
|
243
|
+
const err = await res.json().catch(() => ({}));
|
|
244
|
+
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
245
|
+
}
|
|
246
|
+
return res.text();
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
async getMessageAttachments(roomId, messageId) {
|
|
250
|
+
const res = await fetch(`${baseUrl}/api/rooms/${roomId}/messages/${messageId}/attachments`, { headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined });
|
|
251
|
+
if (!res.ok) {
|
|
252
|
+
const err = await res.json().catch(() => ({}));
|
|
253
|
+
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
254
|
+
}
|
|
255
|
+
return res.json();
|
|
256
|
+
},
|
|
257
|
+
async downloadAttachment(attachmentId, filename) {
|
|
258
|
+
cleanupOldAttachments();
|
|
259
|
+
const res = await fetch(`${baseUrl}/api/attachments/${attachmentId}`, {
|
|
260
|
+
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined
|
|
261
|
+
});
|
|
262
|
+
if (!res.ok) {
|
|
263
|
+
const err = await res.json().catch(() => ({}));
|
|
264
|
+
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
265
|
+
}
|
|
266
|
+
const { mkdirSync, writeFileSync } = await import("node:fs");
|
|
267
|
+
const dir = "/tmp/meet-ai-attachments";
|
|
268
|
+
mkdirSync(dir, { recursive: true });
|
|
269
|
+
const localPath = `${dir}/${attachmentId}-${filename}`;
|
|
270
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
271
|
+
writeFileSync(localPath, buffer);
|
|
272
|
+
return localPath;
|
|
273
|
+
},
|
|
216
274
|
async generateKey() {
|
|
217
275
|
const res = await fetch(`${baseUrl}/api/keys`, {
|
|
218
276
|
method: "POST",
|
|
@@ -223,13 +281,23 @@ function createClient(baseUrl, apiKey) {
|
|
|
223
281
|
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
224
282
|
}
|
|
225
283
|
return res.json();
|
|
284
|
+
},
|
|
285
|
+
async deleteRoom(roomId) {
|
|
286
|
+
const res = await fetch(`${baseUrl}/api/rooms/${roomId}`, {
|
|
287
|
+
method: "DELETE",
|
|
288
|
+
headers: headers()
|
|
289
|
+
});
|
|
290
|
+
if (!res.ok) {
|
|
291
|
+
const err = await res.json().catch(() => ({}));
|
|
292
|
+
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
293
|
+
}
|
|
226
294
|
}
|
|
227
295
|
};
|
|
228
296
|
}
|
|
229
297
|
|
|
230
298
|
// src/inbox-router.ts
|
|
231
|
-
import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
|
|
232
|
-
import { dirname } from "path";
|
|
299
|
+
import { readFileSync, writeFileSync, mkdirSync, statSync } from "node:fs";
|
|
300
|
+
import { dirname } from "node:path";
|
|
233
301
|
var IDLE_CHECK_INTERVAL_MS = 60000;
|
|
234
302
|
var IDLE_THRESHOLD_MS = 5 * 60 * 1000;
|
|
235
303
|
function appendToInbox(path, entry) {
|
|
@@ -285,6 +353,25 @@ var API_URL = process.env.MEET_AI_URL || "https://meet-ai.cc";
|
|
|
285
353
|
var API_KEY = process.env.MEET_AI_KEY;
|
|
286
354
|
var client = createClient(API_URL, API_KEY);
|
|
287
355
|
var [command, ...args] = process.argv.slice(2);
|
|
356
|
+
async function downloadMessageAttachments(roomId, messageId) {
|
|
357
|
+
try {
|
|
358
|
+
const attachments = await client.getMessageAttachments(roomId, messageId);
|
|
359
|
+
if (!attachments.length)
|
|
360
|
+
return [];
|
|
361
|
+
const paths = [];
|
|
362
|
+
for (const att of attachments) {
|
|
363
|
+
try {
|
|
364
|
+
const localPath = await client.downloadAttachment(att.id, att.filename);
|
|
365
|
+
paths.push(localPath);
|
|
366
|
+
} catch (error) {
|
|
367
|
+
console.error(JSON.stringify({ event: "attachment_download_error", attachmentId: att.id, error: error instanceof Error ? error.message : String(error) }));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return paths;
|
|
371
|
+
} catch {
|
|
372
|
+
return [];
|
|
373
|
+
}
|
|
374
|
+
}
|
|
288
375
|
function parseFlags(args2) {
|
|
289
376
|
const positional = [];
|
|
290
377
|
const flags = {};
|
|
@@ -298,24 +385,65 @@ function parseFlags(args2) {
|
|
|
298
385
|
}
|
|
299
386
|
return { positional, flags };
|
|
300
387
|
}
|
|
388
|
+
function rejectFlagLikeArgs(positional, usage) {
|
|
389
|
+
for (const arg of positional) {
|
|
390
|
+
if (arg.startsWith("--")) {
|
|
391
|
+
console.error(`Unknown flag: ${arg}`);
|
|
392
|
+
console.error(`Usage: ${usage}`);
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
301
397
|
switch (command) {
|
|
302
398
|
case "create-room": {
|
|
303
|
-
|
|
399
|
+
if (args.includes("--help")) {
|
|
400
|
+
console.log("Usage: meet-ai create-room <room-name>");
|
|
401
|
+
process.exit(0);
|
|
402
|
+
}
|
|
403
|
+
const { positional, flags } = parseFlags(args);
|
|
404
|
+
const unknownFlags = Object.keys(flags);
|
|
405
|
+
if (unknownFlags.length > 0) {
|
|
406
|
+
console.error(`Unknown flag: --${unknownFlags[0]}`);
|
|
407
|
+
console.error("Usage: meet-ai create-room <room-name>");
|
|
408
|
+
process.exit(1);
|
|
409
|
+
}
|
|
410
|
+
rejectFlagLikeArgs(positional, "meet-ai create-room <room-name>");
|
|
411
|
+
const name = positional[0];
|
|
304
412
|
if (!name) {
|
|
305
|
-
console.error("Usage:
|
|
413
|
+
console.error("Usage: meet-ai create-room <room-name>");
|
|
306
414
|
process.exit(1);
|
|
307
415
|
}
|
|
308
416
|
const room = await client.createRoom(name);
|
|
309
417
|
console.log(`Room created: ${room.id} (${room.name})`);
|
|
310
418
|
break;
|
|
311
419
|
}
|
|
420
|
+
case "delete-room": {
|
|
421
|
+
if (args.includes("--help")) {
|
|
422
|
+
console.log("Usage: meet-ai delete-room <roomId>");
|
|
423
|
+
process.exit(0);
|
|
424
|
+
}
|
|
425
|
+
rejectFlagLikeArgs(args, "meet-ai delete-room <roomId>");
|
|
426
|
+
const roomId = args[0];
|
|
427
|
+
if (!roomId) {
|
|
428
|
+
console.error("Usage: meet-ai delete-room <roomId>");
|
|
429
|
+
process.exit(1);
|
|
430
|
+
}
|
|
431
|
+
await client.deleteRoom(roomId);
|
|
432
|
+
console.log(`Room deleted: ${roomId}`);
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
312
435
|
case "send-message": {
|
|
436
|
+
if (args.includes("--help")) {
|
|
437
|
+
console.log("Usage: meet-ai send-message <roomId> <sender> <content> [--color <color>]");
|
|
438
|
+
process.exit(0);
|
|
439
|
+
}
|
|
313
440
|
const { positional: smPos, flags: smFlags } = parseFlags(args);
|
|
441
|
+
rejectFlagLikeArgs(smPos, "meet-ai send-message <roomId> <sender> <content> [--color <color>]");
|
|
314
442
|
const [roomId, sender, ...rest] = smPos;
|
|
315
443
|
const content = rest.join(" ").replace(/\\n/g, `
|
|
316
444
|
`);
|
|
317
445
|
if (!roomId || !sender || !content) {
|
|
318
|
-
console.error("Usage:
|
|
446
|
+
console.error("Usage: meet-ai send-message <roomId> <sender> <content> [--color <color>]");
|
|
319
447
|
process.exit(1);
|
|
320
448
|
}
|
|
321
449
|
const msg = await client.sendMessage(roomId, sender, content, smFlags.color);
|
|
@@ -323,10 +451,15 @@ switch (command) {
|
|
|
323
451
|
break;
|
|
324
452
|
}
|
|
325
453
|
case "poll": {
|
|
454
|
+
if (args.includes("--help")) {
|
|
455
|
+
console.log("Usage: meet-ai poll <roomId> [--after <messageId>] [--exclude <sender>] [--sender-type <type>]");
|
|
456
|
+
process.exit(0);
|
|
457
|
+
}
|
|
326
458
|
const { positional, flags } = parseFlags(args);
|
|
459
|
+
rejectFlagLikeArgs(positional, "meet-ai poll <roomId> [--after <messageId>] [--exclude <sender>] [--sender-type <type>]");
|
|
327
460
|
const roomId = positional[0];
|
|
328
461
|
if (!roomId) {
|
|
329
|
-
console.error("Usage:
|
|
462
|
+
console.error("Usage: meet-ai poll <roomId> [--after <messageId>] [--exclude <sender>] [--sender-type <type>]");
|
|
330
463
|
process.exit(1);
|
|
331
464
|
}
|
|
332
465
|
const messages = await client.getMessages(roomId, {
|
|
@@ -334,19 +467,26 @@ switch (command) {
|
|
|
334
467
|
exclude: flags.exclude,
|
|
335
468
|
senderType: flags["sender-type"]
|
|
336
469
|
});
|
|
337
|
-
|
|
470
|
+
const enriched = await Promise.all(messages.map(async (msg) => {
|
|
471
|
+
const paths = await downloadMessageAttachments(roomId, msg.id);
|
|
472
|
+
return paths.length ? { ...msg, attachments: paths } : msg;
|
|
473
|
+
}));
|
|
474
|
+
console.log(JSON.stringify(enriched));
|
|
338
475
|
break;
|
|
339
476
|
}
|
|
340
477
|
case "listen": {
|
|
341
|
-
let routeToInbox = function(msg) {
|
|
478
|
+
let routeToInbox = function(msg, attachmentPaths) {
|
|
342
479
|
if (!inboxDir)
|
|
343
480
|
return;
|
|
344
481
|
const entry = {
|
|
345
|
-
from:
|
|
482
|
+
from: `meet-ai:${msg.sender}`,
|
|
346
483
|
text: msg.content,
|
|
347
484
|
timestamp: new Date().toISOString(),
|
|
348
485
|
read: false
|
|
349
486
|
};
|
|
487
|
+
if (attachmentPaths?.length) {
|
|
488
|
+
entry.attachments = attachmentPaths;
|
|
489
|
+
}
|
|
350
490
|
const members = teamDir ? getTeamMembers(teamDir) : new Set;
|
|
351
491
|
const targets = resolveInboxTargets(msg.content, members);
|
|
352
492
|
if (targets) {
|
|
@@ -364,10 +504,15 @@ switch (command) {
|
|
|
364
504
|
}
|
|
365
505
|
process.exit(0);
|
|
366
506
|
};
|
|
507
|
+
if (args.includes("--help")) {
|
|
508
|
+
console.log("Usage: meet-ai listen <roomId> [--exclude <sender>] [--sender-type <type>] [--team <name> --inbox <agent>]");
|
|
509
|
+
process.exit(0);
|
|
510
|
+
}
|
|
367
511
|
const { positional, flags } = parseFlags(args);
|
|
512
|
+
rejectFlagLikeArgs(positional, "meet-ai listen <roomId> [--exclude <sender>] [--sender-type <type>] [--team <name> --inbox <agent>]");
|
|
368
513
|
const roomId = positional[0];
|
|
369
514
|
if (!roomId) {
|
|
370
|
-
console.error("Usage:
|
|
515
|
+
console.error("Usage: meet-ai listen <roomId> [--exclude <sender>] [--sender-type <type>] [--team <name> --inbox <agent>]");
|
|
371
516
|
process.exit(1);
|
|
372
517
|
}
|
|
373
518
|
const team = flags.team;
|
|
@@ -375,10 +520,20 @@ switch (command) {
|
|
|
375
520
|
const inboxDir = team ? `${process.env.HOME}/.claude/teams/${team}/inboxes` : null;
|
|
376
521
|
const defaultInboxPath = inboxDir && inbox ? `${inboxDir}/${inbox}.json` : null;
|
|
377
522
|
const teamDir = team ? `${process.env.HOME}/.claude/teams/${team}` : null;
|
|
378
|
-
const onMessage =
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
523
|
+
const onMessage = (msg) => {
|
|
524
|
+
if (msg.id && msg.room_id && msg.attachment_count > 0) {
|
|
525
|
+
downloadMessageAttachments(msg.room_id, msg.id).then((paths) => {
|
|
526
|
+
const output = paths.length ? { ...msg, attachments: paths } : msg;
|
|
527
|
+
console.log(JSON.stringify(output));
|
|
528
|
+
if (inboxDir)
|
|
529
|
+
routeToInbox(msg, paths);
|
|
530
|
+
});
|
|
531
|
+
} else {
|
|
532
|
+
console.log(JSON.stringify(msg));
|
|
533
|
+
if (inboxDir)
|
|
534
|
+
routeToInbox(msg);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
382
537
|
const ws = client.listen(roomId, { exclude: flags.exclude, senderType: flags["sender-type"], onMessage });
|
|
383
538
|
let idleCheckTimeout = null;
|
|
384
539
|
const idleNotified = new Set;
|
|
@@ -408,12 +563,17 @@ switch (command) {
|
|
|
408
563
|
break;
|
|
409
564
|
}
|
|
410
565
|
case "send-log": {
|
|
566
|
+
if (args.includes("--help")) {
|
|
567
|
+
console.log("Usage: meet-ai send-log <roomId> <sender> <content> [--color <color>] [--message-id <id>]");
|
|
568
|
+
process.exit(0);
|
|
569
|
+
}
|
|
411
570
|
const { positional: slPos, flags: slFlags } = parseFlags(args);
|
|
571
|
+
rejectFlagLikeArgs(slPos, "meet-ai send-log <roomId> <sender> <content> [--color <color>] [--message-id <id>]");
|
|
412
572
|
const [slRoomId, slSender, ...slRest] = slPos;
|
|
413
573
|
const slContent = slRest.join(" ").replace(/\\n/g, `
|
|
414
574
|
`);
|
|
415
575
|
if (!slRoomId || !slSender || !slContent) {
|
|
416
|
-
console.error("Usage:
|
|
576
|
+
console.error("Usage: meet-ai send-log <roomId> <sender> <content> [--color <color>] [--message-id <id>]");
|
|
417
577
|
process.exit(1);
|
|
418
578
|
}
|
|
419
579
|
const log = await client.sendLog(slRoomId, slSender, slContent, slFlags.color, slFlags["message-id"]);
|
|
@@ -421,9 +581,14 @@ switch (command) {
|
|
|
421
581
|
break;
|
|
422
582
|
}
|
|
423
583
|
case "send-team-info": {
|
|
584
|
+
if (args.includes("--help")) {
|
|
585
|
+
console.log("Usage: meet-ai send-team-info <roomId> '<json-payload>'");
|
|
586
|
+
process.exit(0);
|
|
587
|
+
}
|
|
588
|
+
rejectFlagLikeArgs(args, "meet-ai send-team-info <roomId> '<json-payload>'");
|
|
424
589
|
const [tiRoomId, tiPayload] = args;
|
|
425
590
|
if (!tiRoomId || !tiPayload) {
|
|
426
|
-
console.error("Usage:
|
|
591
|
+
console.error("Usage: meet-ai send-team-info <roomId> '<json-payload>'");
|
|
427
592
|
process.exit(1);
|
|
428
593
|
}
|
|
429
594
|
try {
|
|
@@ -436,13 +601,71 @@ switch (command) {
|
|
|
436
601
|
console.log("Team info sent");
|
|
437
602
|
break;
|
|
438
603
|
}
|
|
604
|
+
case "send-tasks": {
|
|
605
|
+
if (args.includes("--help")) {
|
|
606
|
+
console.log("Usage: meet-ai send-tasks <roomId> '<json-payload>'");
|
|
607
|
+
process.exit(0);
|
|
608
|
+
}
|
|
609
|
+
rejectFlagLikeArgs(args, "meet-ai send-tasks <roomId> '<json-payload>'");
|
|
610
|
+
const [stRoomId, stPayload] = args;
|
|
611
|
+
if (!stRoomId || !stPayload) {
|
|
612
|
+
console.error("Usage: meet-ai send-tasks <roomId> '<json-payload>'");
|
|
613
|
+
process.exit(1);
|
|
614
|
+
}
|
|
615
|
+
try {
|
|
616
|
+
JSON.parse(stPayload);
|
|
617
|
+
} catch {
|
|
618
|
+
console.error("Error: payload must be valid JSON");
|
|
619
|
+
process.exit(1);
|
|
620
|
+
}
|
|
621
|
+
await client.sendTasks(stRoomId, stPayload);
|
|
622
|
+
console.log("Tasks info sent");
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
case "download-attachment": {
|
|
626
|
+
if (args.includes("--help")) {
|
|
627
|
+
console.log("Usage: meet-ai download-attachment <attachmentId>");
|
|
628
|
+
process.exit(0);
|
|
629
|
+
}
|
|
630
|
+
rejectFlagLikeArgs(args, "meet-ai download-attachment <attachmentId>");
|
|
631
|
+
const attachmentId = args[0];
|
|
632
|
+
if (!attachmentId) {
|
|
633
|
+
console.error("Usage: meet-ai download-attachment <attachmentId>");
|
|
634
|
+
process.exit(1);
|
|
635
|
+
}
|
|
636
|
+
try {
|
|
637
|
+
cleanupOldAttachments();
|
|
638
|
+
const res = await fetch(`${API_URL}/api/attachments/${attachmentId}`, {
|
|
639
|
+
headers: API_KEY ? { Authorization: `Bearer ${API_KEY}` } : undefined
|
|
640
|
+
});
|
|
641
|
+
if (!res.ok) {
|
|
642
|
+
const err = await res.json().catch(() => ({}));
|
|
643
|
+
console.error(err.error ?? `HTTP ${res.status}`);
|
|
644
|
+
process.exit(1);
|
|
645
|
+
}
|
|
646
|
+
const disposition = res.headers.get("Content-Disposition") || "";
|
|
647
|
+
const filenameMatch = disposition.match(/filename="(.+?)"/);
|
|
648
|
+
const filename = filenameMatch?.[1] || attachmentId;
|
|
649
|
+
const { mkdirSync: mkdirSync2, writeFileSync: writeFileSync2 } = await import("node:fs");
|
|
650
|
+
const dir = "/tmp/meet-ai-attachments";
|
|
651
|
+
mkdirSync2(dir, { recursive: true });
|
|
652
|
+
const localPath = `${dir}/${attachmentId}-${filename}`;
|
|
653
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
654
|
+
writeFileSync2(localPath, buffer);
|
|
655
|
+
console.log(localPath);
|
|
656
|
+
} catch (error) {
|
|
657
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
658
|
+
process.exit(1);
|
|
659
|
+
}
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
439
662
|
case "generate-key": {
|
|
440
663
|
const result = await client.generateKey();
|
|
441
664
|
console.log(`API Key: ${result.key}`);
|
|
442
665
|
console.log(`Prefix: ${result.prefix}`);
|
|
443
666
|
break;
|
|
444
667
|
}
|
|
445
|
-
default:
|
|
668
|
+
default: {
|
|
446
669
|
console.log(`meet-ai CLI
|
|
447
670
|
|
|
448
671
|
Environment variables:
|
|
@@ -451,6 +674,7 @@ Environment variables:
|
|
|
451
674
|
|
|
452
675
|
Commands:
|
|
453
676
|
create-room <name> Create a new chat room
|
|
677
|
+
delete-room <roomId> Delete a room and all its messages
|
|
454
678
|
send-message <roomId> <sender> <content> Send a message to a room
|
|
455
679
|
--color <color> Set sender name color (e.g. #ff0000, red)
|
|
456
680
|
send-log <roomId> <sender> <content> Send a log entry to a room
|
|
@@ -465,6 +689,9 @@ Commands:
|
|
|
465
689
|
--sender-type <type> Filter by sender_type (human|agent)
|
|
466
690
|
--team <name> Write to Claude Code team inbox
|
|
467
691
|
--inbox <agent> Target agent inbox (requires --team)
|
|
692
|
+
download-attachment <attachmentId> Download an attachment to /tmp
|
|
468
693
|
send-team-info <roomId> '<json>' Send team info to a room
|
|
694
|
+
send-tasks <roomId> '<json>' Send tasks info to a room
|
|
469
695
|
generate-key Generate a new API key`);
|
|
696
|
+
}
|
|
470
697
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meet-ai/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chat",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"typecheck": "tsc --noEmit"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@types/node": "
|
|
38
|
-
"typescript": "
|
|
37
|
+
"@types/node": "catalog:",
|
|
38
|
+
"typescript": "catalog:"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=22"
|