@meet-ai/cli 0.0.10 → 0.0.11

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.
Files changed (2) hide show
  1. package/dist/index.js +176 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -348,9 +348,115 @@ function checkIdleAgents(inboxDir, members, excludeAgent, notified, now = Date.n
348
348
  return newlyIdle;
349
349
  }
350
350
 
351
+ // src/config.ts
352
+ import { readFileSync as readFileSync2, existsSync } from "node:fs";
353
+ import { join, resolve } from "node:path";
354
+ import { homedir } from "node:os";
355
+ function loadSettingsFromPath(path) {
356
+ try {
357
+ if (!existsSync(path)) {
358
+ return null;
359
+ }
360
+ const content = readFileSync2(path, "utf-8");
361
+ return JSON.parse(content);
362
+ } catch {
363
+ return null;
364
+ }
365
+ }
366
+ function getMeetAiConfig() {
367
+ if (process.env.MEET_AI_URL) {
368
+ return {
369
+ url: process.env.MEET_AI_URL,
370
+ key: process.env.MEET_AI_KEY
371
+ };
372
+ }
373
+ const projectSettingsPath = resolve("./.claude/settings.json");
374
+ const projectSettings = loadSettingsFromPath(projectSettingsPath);
375
+ if (projectSettings?.env?.MEET_AI_URL) {
376
+ return {
377
+ url: projectSettings.env.MEET_AI_URL,
378
+ key: projectSettings.env.MEET_AI_KEY
379
+ };
380
+ }
381
+ const userSettingsPath = join(homedir(), ".claude/settings.json");
382
+ const userSettings = loadSettingsFromPath(userSettingsPath);
383
+ if (userSettings?.env?.MEET_AI_URL) {
384
+ return {
385
+ url: userSettings.env.MEET_AI_URL,
386
+ key: userSettings.env.MEET_AI_KEY
387
+ };
388
+ }
389
+ return {
390
+ url: "https://meet-ai.cc",
391
+ key: undefined
392
+ };
393
+ }
394
+
395
+ // src/spawner.ts
396
+ import { spawn, execSync } from "node:child_process";
397
+ import { existsSync as existsSync2 } from "node:fs";
398
+ import { join as join2 } from "node:path";
399
+ import { homedir as homedir2, platform } from "node:os";
400
+ function findClaudeCli() {
401
+ try {
402
+ const command = platform() === "win32" ? "where claude" : "which claude";
403
+ const result = execSync(command, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
404
+ const claudePath = result.split(`
405
+ `)[0].trim();
406
+ if (claudePath && existsSync2(claudePath)) {
407
+ return claudePath;
408
+ }
409
+ } catch {}
410
+ const envPath = process.env.MEET_AI_CLAUDE_PATH;
411
+ if (envPath && existsSync2(envPath)) {
412
+ return envPath;
413
+ }
414
+ const home = homedir2();
415
+ const commonPaths = [
416
+ join2(home, ".bun", "bin", "claude"),
417
+ "/opt/homebrew/bin/claude",
418
+ "/usr/local/bin/claude",
419
+ join2(home, ".local", "bin", "claude")
420
+ ];
421
+ for (const path of commonPaths) {
422
+ if (existsSync2(path)) {
423
+ return path;
424
+ }
425
+ }
426
+ throw new Error(`
427
+ Claude Code is not installed
428
+
429
+ Please install Claude Code:
430
+ npm install -g @anthropic-ai/claude-code
431
+
432
+ Or set MEET_AI_CLAUDE_PATH to the Claude Code CLI path.
433
+ `.trim());
434
+ }
435
+ async function spawnInteractive() {
436
+ const claudePath = findClaudeCli();
437
+ return new Promise((resolve2, reject) => {
438
+ const child = spawn(claudePath, [], {
439
+ stdio: "inherit",
440
+ env: {
441
+ ...process.env,
442
+ DISABLE_AUTOUPDATER: "1"
443
+ }
444
+ });
445
+ child.on("exit", (code) => {
446
+ if (code === 0 || code === null) {
447
+ resolve2();
448
+ } else {
449
+ reject(new Error(`Claude exited with code ${code}`));
450
+ }
451
+ });
452
+ child.on("error", reject);
453
+ });
454
+ }
455
+
351
456
  // src/index.ts
352
- var API_URL = process.env.MEET_AI_URL || "https://meet-ai.cc";
353
- var API_KEY = process.env.MEET_AI_KEY;
457
+ var config = getMeetAiConfig();
458
+ var API_URL = config.url;
459
+ var API_KEY = config.key;
354
460
  var client = createClient(API_URL, API_KEY);
355
461
  var [command, ...args] = process.argv.slice(2);
356
462
  async function downloadMessageAttachments(roomId, messageId) {
@@ -582,22 +688,57 @@ switch (command) {
582
688
  }
583
689
  case "send-team-info": {
584
690
  if (args.includes("--help")) {
585
- console.log("Usage: meet-ai send-team-info <roomId> '<json-payload>'");
691
+ console.log(`Usage: meet-ai send-team-info <roomId> '<json>' [--team-name <name>]
692
+
693
+ Accepts two JSON formats:
694
+
695
+ 1. Full format (passed through as-is):
696
+ '{"team_name":"my-team","members":[{"name":"agent1","role":"dev","status":"active","color":"#fff","model":"opus","joinedAt":1234567890}]}'
697
+
698
+ 2. Members-only array (requires --team-name):
699
+ '[{"name":"agent1","role":"dev","status":"active","color":"#fff"}]' --team-name my-team
700
+
701
+ Missing fields get defaults: model="claude-opus-4-6", joinedAt=<now>`);
586
702
  process.exit(0);
587
703
  }
588
- rejectFlagLikeArgs(args, "meet-ai send-team-info <roomId> '<json-payload>'");
589
- const [tiRoomId, tiPayload] = args;
704
+ const { positional: tiPos, flags: tiFlags } = parseFlags(args);
705
+ rejectFlagLikeArgs(tiPos, "meet-ai send-team-info <roomId> '<json>' [--team-name <name>]");
706
+ const [tiRoomId, tiPayload] = tiPos;
590
707
  if (!tiRoomId || !tiPayload) {
591
- console.error("Usage: meet-ai send-team-info <roomId> '<json-payload>'");
708
+ console.error("Usage: meet-ai send-team-info <roomId> '<json>' [--team-name <name>]");
592
709
  process.exit(1);
593
710
  }
711
+ let tiParsed;
594
712
  try {
595
- JSON.parse(tiPayload);
713
+ tiParsed = JSON.parse(tiPayload);
596
714
  } catch {
597
715
  console.error("Error: payload must be valid JSON");
598
716
  process.exit(1);
599
717
  }
600
- await client.sendTeamInfo(tiRoomId, tiPayload);
718
+ let tiBody;
719
+ if (Array.isArray(tiParsed)) {
720
+ const teamName = tiFlags["team-name"];
721
+ if (!teamName) {
722
+ console.error("Error: when passing a members array, --team-name is required");
723
+ console.error("Usage: meet-ai send-team-info <roomId> '[...]' --team-name <name>");
724
+ process.exit(1);
725
+ }
726
+ const now = Date.now();
727
+ tiBody = {
728
+ team_name: teamName,
729
+ members: tiParsed.map((m) => ({
730
+ model: "claude-opus-4-6",
731
+ joinedAt: now,
732
+ ...m
733
+ }))
734
+ };
735
+ } else if (tiParsed && typeof tiParsed === "object" && "team_name" in tiParsed && "members" in tiParsed) {
736
+ tiBody = tiParsed;
737
+ } else {
738
+ console.error("Error: JSON must be either a members array or an object with { team_name, members }");
739
+ process.exit(1);
740
+ }
741
+ await client.sendTeamInfo(tiRoomId, JSON.stringify(tiBody));
601
742
  console.log("Team info sent");
602
743
  break;
603
744
  }
@@ -666,32 +807,46 @@ switch (command) {
666
807
  break;
667
808
  }
668
809
  default: {
810
+ if (!command) {
811
+ console.log(`Starting Claude Code... (Press Ctrl+C to exit)
812
+ `);
813
+ await spawnInteractive();
814
+ break;
815
+ }
669
816
  console.log(`meet-ai CLI
670
817
 
671
- Environment variables:
672
- MEET_AI_URL Server URL (default: https://meet-ai.cc)
673
- MEET_AI_KEY API key for authentication
818
+ Usage:
819
+ meet-ai Start Claude Code interactively (default)
820
+ meet-ai <command> [options] Run a specific command
821
+
822
+ Configuration (in order of priority):
823
+ 1. Environment variables:
824
+ MEET_AI_URL Server URL (default: https://meet-ai.cc)
825
+ MEET_AI_KEY API key for authentication
826
+ 2. Project settings: ./.claude/settings.json
827
+ 3. User settings: ~/.claude/settings.json
674
828
 
675
829
  Commands:
676
- create-room <name> Create a new chat room
677
- delete-room <roomId> Delete a room and all its messages
678
- send-message <roomId> <sender> <content> Send a message to a room
830
+ create-room <name> Create a new chat room
831
+ delete-room <roomId> Delete a room and all its messages
832
+ send-message <roomId> <sender> <content> Send a message to a room
679
833
  --color <color> Set sender name color (e.g. #ff0000, red)
680
- send-log <roomId> <sender> <content> Send a log entry to a room
834
+ send-log <roomId> <sender> <content> Send a log entry to a room
681
835
  --color <color> Set sender name color (e.g. #ff0000, red)
682
836
  --message-id <id> Associate log with a parent message
683
- poll <roomId> [options] Fetch messages from a room
837
+ poll <roomId> [options] Fetch messages from a room
684
838
  --after <id> Only messages after this ID
685
839
  --exclude <sender> Exclude messages from sender
686
840
  --sender-type <type> Filter by sender_type (human|agent)
687
- listen <roomId> [options] Stream messages via WebSocket
841
+ listen <roomId> [options] Stream messages via WebSocket
688
842
  --exclude <sender> Exclude messages from sender
689
843
  --sender-type <type> Filter by sender_type (human|agent)
690
844
  --team <name> Write to Claude Code team inbox
691
845
  --inbox <agent> Target agent inbox (requires --team)
692
- download-attachment <attachmentId> Download an attachment to /tmp
693
- send-team-info <roomId> '<json>' Send team info to a room
694
- send-tasks <roomId> '<json>' Send tasks info to a room
695
- generate-key Generate a new API key`);
846
+ download-attachment <attachmentId> Download an attachment to /tmp
847
+ send-team-info <roomId> '<json>' [options] Send team info to a room
848
+ --team-name <name> Team name (required when passing members array)
849
+ send-tasks <roomId> '<json>' Send tasks info to a room
850
+ generate-key Generate a new API key`);
696
851
  }
697
852
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meet-ai/cli",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket",
5
5
  "keywords": [
6
6
  "chat",