@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.
- package/dist/index.js +110 -17
- 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
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
|
|
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
|
|
15573
|
-
|
|
15574
|
-
|
|
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
|
|
15582
|
-
|
|
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
|
-
},
|
|
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.
|
|
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: {
|