@meet-ai/cli 0.0.29 → 0.0.31

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 +110 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14634,6 +14634,12 @@ function createClient(baseUrl, apiKey) {
14634
14634
  const data = JSON.parse(text);
14635
14635
  if (data.type === "pong")
14636
14636
  return;
14637
+ if (data.type === "terminal_subscribe" || data.type === "terminal_unsubscribe") {
14638
+ options?.onMessage?.(data);
14639
+ return;
14640
+ }
14641
+ if (data.type === "terminal_data")
14642
+ return;
14637
14643
  deliver(data);
14638
14644
  };
14639
14645
  ws.onclose = (event) => {
@@ -15450,6 +15456,29 @@ class TmuxClient {
15450
15456
  };
15451
15457
  });
15452
15458
  }
15459
+ listAllPanes() {
15460
+ const args = [
15461
+ "-L",
15462
+ this.server,
15463
+ "list-panes",
15464
+ "-a",
15465
+ "-F",
15466
+ "#{pane_id}\t#{session_name}\t#{pane_title}\t#{pane_current_command}"
15467
+ ];
15468
+ return new Promise((resolve2) => {
15469
+ execFileCb("tmux", args, { encoding: "utf8", timeout: 5000 }, (error48, stdout) => {
15470
+ if (error48) {
15471
+ resolve2([]);
15472
+ return;
15473
+ }
15474
+ resolve2(stdout.trim().split(`
15475
+ `).filter((line) => line.trim()).map((line) => {
15476
+ const [paneId, sessionName, title, command] = line.split("\t");
15477
+ return { paneId: paneId ?? "", sessionName: sessionName ?? "", title: title ?? "", command: command ?? "" };
15478
+ }));
15479
+ });
15480
+ });
15481
+ }
15453
15482
  listPanes(sessionName) {
15454
15483
  validateSessionName(sessionName);
15455
15484
  const result = this.exec([
@@ -15474,12 +15503,14 @@ class TmuxClient {
15474
15503
  });
15475
15504
  }
15476
15505
  capturePane(target, lines) {
15477
- const dotIdx = target.indexOf(".");
15478
- const sessionPart = dotIdx === -1 ? target : target.slice(0, dotIdx);
15479
- const panePart = dotIdx === -1 ? null : target.slice(dotIdx + 1);
15480
- validateSessionName(sessionPart);
15481
- if (panePart !== null && !/^\d+$/.test(panePart)) {
15482
- throw new Error(`Invalid pane index: ${panePart}`);
15506
+ if (/^%\d+$/.test(target)) {} else {
15507
+ const dotIdx = target.indexOf(".");
15508
+ const sessionPart = dotIdx === -1 ? target : target.slice(0, dotIdx);
15509
+ const panePart = dotIdx === -1 ? null : target.slice(dotIdx + 1);
15510
+ validateSessionName(sessionPart);
15511
+ if (panePart !== null && !/^\d+$/.test(panePart)) {
15512
+ throw new Error(`Invalid pane index: ${panePart}`);
15513
+ }
15483
15514
  }
15484
15515
  const args = [
15485
15516
  "-L",
@@ -15488,10 +15519,11 @@ class TmuxClient {
15488
15519
  "-t",
15489
15520
  target,
15490
15521
  "-p",
15491
- "-e",
15492
- "-S",
15493
- `-${lines}`
15522
+ "-e"
15494
15523
  ];
15524
+ if (lines > 0) {
15525
+ args.push("-S", `-${lines}`);
15526
+ }
15495
15527
  return new Promise((resolve2) => {
15496
15528
  execFileCb("tmux", args, { encoding: "utf8", timeout: 5000 }, (error48, stdout) => {
15497
15529
  if (error48) {
@@ -15507,6 +15539,15 @@ class TmuxClient {
15507
15539
  });
15508
15540
  });
15509
15541
  }
15542
+ resizePane(paneId, cols, rows) {
15543
+ const result = this.exec(["-L", this.server, "resize-pane", "-t", paneId, "-x", String(cols)]);
15544
+ if (!result.ok)
15545
+ return result;
15546
+ if (rows) {
15547
+ return this.exec(["-L", this.server, "resize-pane", "-t", paneId, "-y", String(rows)]);
15548
+ }
15549
+ return result;
15550
+ }
15510
15551
  attachSession(name) {
15511
15552
  validateSessionName(name);
15512
15553
  try {
@@ -15568,21 +15609,70 @@ function listen(client, input) {
15568
15609
  const tmuxClient = new TmuxClient({ server: "meet-ai", scrollback: 50000 });
15569
15610
  let terminalInterval = null;
15570
15611
  const onMessage = (msg) => {
15612
+ if (msg.type === "terminal_resize") {
15613
+ const cols = msg.cols;
15614
+ if (typeof cols === "number" && cols > 0) {
15615
+ tmuxClient.listAllPanes().then((allPanes) => {
15616
+ const roomPrefix = roomId.slice(0, 8);
15617
+ const roomPanes = allPanes.filter((p) => p.sessionName.includes(roomPrefix));
15618
+ for (const p of roomPanes) {
15619
+ tmuxClient.resizePane(p.paneId, cols);
15620
+ }
15621
+ });
15622
+ }
15623
+ return;
15624
+ }
15571
15625
  if (msg.type === "terminal_subscribe") {
15572
- const paneId = msg.paneId;
15573
- if (!paneId)
15574
- return;
15626
+ const roomPrefix = roomId.slice(0, 8);
15627
+ let membersByPaneId = {};
15628
+ if (teamDir) {
15629
+ try {
15630
+ const configPath = `${teamDir}/config.json`;
15631
+ const fs = __require("node:fs");
15632
+ const config2 = JSON.parse(fs.readFileSync(configPath, "utf8"));
15633
+ const members = config2.members || [];
15634
+ for (const m of members) {
15635
+ if (m.tmuxPaneId) {
15636
+ membersByPaneId[m.tmuxPaneId] = m.name;
15637
+ }
15638
+ }
15639
+ } catch {}
15640
+ }
15575
15641
  if (terminalInterval) {
15576
15642
  clearInterval(terminalInterval);
15577
15643
  terminalInterval = null;
15578
15644
  }
15645
+ let lastSentPayload = "";
15646
+ const TERMINAL_POLL_MS = 500;
15579
15647
  terminalInterval = setInterval(async () => {
15580
15648
  try {
15581
- const lines = await tmuxClient.capturePane(paneId, 500);
15582
- await client.sendTerminalData(roomId, lines.join(`
15583
- `));
15649
+ const allTmuxPanes = await tmuxClient.listAllPanes();
15650
+ const roomPanes = allTmuxPanes.filter((p) => p.sessionName.includes(roomPrefix));
15651
+ if (roomPanes.length === 0)
15652
+ return;
15653
+ const panes = roomPanes.map((tp) => ({
15654
+ name: membersByPaneId[tp.paneId] || tp.title || tp.paneId,
15655
+ paneId: tp.paneId
15656
+ }));
15657
+ panes.sort((a, b) => {
15658
+ if (a.name === "team-lead")
15659
+ return -1;
15660
+ if (b.name === "team-lead")
15661
+ return 1;
15662
+ return a.name.localeCompare(b.name);
15663
+ });
15664
+ const results = await Promise.all(panes.map(async (p) => {
15665
+ const lines = await tmuxClient.capturePane(p.paneId, 0);
15666
+ return { name: p.name, paneId: p.paneId, data: lines.join(`\r
15667
+ `) };
15668
+ }));
15669
+ const payload = JSON.stringify({ panes: results });
15670
+ if (payload === lastSentPayload)
15671
+ return;
15672
+ lastSentPayload = payload;
15673
+ await client.sendTerminalData(roomId, payload);
15584
15674
  } catch {}
15585
- }, 200);
15675
+ }, TERMINAL_POLL_MS);
15586
15676
  return;
15587
15677
  }
15588
15678
  if (msg.type === "terminal_unsubscribe") {
@@ -15592,6 +15682,9 @@ function listen(client, input) {
15592
15682
  }
15593
15683
  return;
15594
15684
  }
15685
+ if (msg.type === "terminal_data") {
15686
+ return;
15687
+ }
15595
15688
  if (msg.id && msg.room_id && msg.attachment_count > 0) {
15596
15689
  downloadMessageAttachments(client, msg.room_id, msg.id).then((paths) => {
15597
15690
  const output = paths.length ? { ...msg, attachments: paths } : msg;
@@ -56355,7 +56448,7 @@ init_output();
56355
56448
  var main = defineCommand({
56356
56449
  meta: {
56357
56450
  name: "meet-ai",
56358
- version: "0.0.29",
56451
+ version: "0.0.30",
56359
56452
  description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
56360
56453
  },
56361
56454
  args: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meet-ai/cli",
3
- "version": "0.0.29",
3
+ "version": "0.0.31",
4
4
  "description": "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket",
5
5
  "keywords": [
6
6
  "chat",