@meet-ai/cli 0.0.30 → 0.0.32
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 +163 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15519,10 +15519,11 @@ class TmuxClient {
|
|
|
15519
15519
|
"-t",
|
|
15520
15520
|
target,
|
|
15521
15521
|
"-p",
|
|
15522
|
-
"-e"
|
|
15523
|
-
"-S",
|
|
15524
|
-
`-${lines}`
|
|
15522
|
+
"-e"
|
|
15525
15523
|
];
|
|
15524
|
+
if (lines > 0) {
|
|
15525
|
+
args.push("-S", `-${lines}`);
|
|
15526
|
+
}
|
|
15526
15527
|
return new Promise((resolve2) => {
|
|
15527
15528
|
execFileCb("tmux", args, { encoding: "utf8", timeout: 5000 }, (error48, stdout) => {
|
|
15528
15529
|
if (error48) {
|
|
@@ -15538,6 +15539,15 @@ class TmuxClient {
|
|
|
15538
15539
|
});
|
|
15539
15540
|
});
|
|
15540
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
|
+
}
|
|
15541
15551
|
attachSession(name) {
|
|
15542
15552
|
validateSessionName(name);
|
|
15543
15553
|
try {
|
|
@@ -15599,6 +15609,19 @@ function listen(client, input) {
|
|
|
15599
15609
|
const tmuxClient = new TmuxClient({ server: "meet-ai", scrollback: 50000 });
|
|
15600
15610
|
let terminalInterval = null;
|
|
15601
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
|
+
}
|
|
15602
15625
|
if (msg.type === "terminal_subscribe") {
|
|
15603
15626
|
const roomPrefix = roomId.slice(0, 8);
|
|
15604
15627
|
let membersByPaneId = {};
|
|
@@ -15619,6 +15642,7 @@ function listen(client, input) {
|
|
|
15619
15642
|
clearInterval(terminalInterval);
|
|
15620
15643
|
terminalInterval = null;
|
|
15621
15644
|
}
|
|
15645
|
+
let lastSentPayload = "";
|
|
15622
15646
|
const TERMINAL_POLL_MS = 500;
|
|
15623
15647
|
terminalInterval = setInterval(async () => {
|
|
15624
15648
|
try {
|
|
@@ -15638,11 +15662,15 @@ function listen(client, input) {
|
|
|
15638
15662
|
return a.name.localeCompare(b.name);
|
|
15639
15663
|
});
|
|
15640
15664
|
const results = await Promise.all(panes.map(async (p) => {
|
|
15641
|
-
const lines = await tmuxClient.capturePane(p.paneId,
|
|
15665
|
+
const lines = await tmuxClient.capturePane(p.paneId, 0);
|
|
15642
15666
|
return { name: p.name, paneId: p.paneId, data: lines.join(`\r
|
|
15643
15667
|
`) };
|
|
15644
15668
|
}));
|
|
15645
|
-
|
|
15669
|
+
const payload = JSON.stringify({ panes: results });
|
|
15670
|
+
if (payload === lastSentPayload)
|
|
15671
|
+
return;
|
|
15672
|
+
lastSentPayload = payload;
|
|
15673
|
+
await client.sendTerminalData(roomId, payload);
|
|
15646
15674
|
} catch {}
|
|
15647
15675
|
}, TERMINAL_POLL_MS);
|
|
15648
15676
|
return;
|
|
@@ -15654,6 +15682,9 @@ function listen(client, input) {
|
|
|
15654
15682
|
}
|
|
15655
15683
|
return;
|
|
15656
15684
|
}
|
|
15685
|
+
if (msg.type === "terminal_data") {
|
|
15686
|
+
return;
|
|
15687
|
+
}
|
|
15657
15688
|
if (msg.id && msg.room_id && msg.attachment_count > 0) {
|
|
15658
15689
|
downloadMessageAttachments(client, msg.room_id, msg.id).then((paths) => {
|
|
15659
15690
|
const output = paths.length ? { ...msg, attachments: paths } : msg;
|
|
@@ -16009,10 +16040,56 @@ var init_command10 = __esm(() => {
|
|
|
16009
16040
|
});
|
|
16010
16041
|
|
|
16011
16042
|
// src/lib/hooks/find-room.ts
|
|
16012
|
-
import { readdirSync, readFileSync as readFileSync3 } from "node:fs";
|
|
16043
|
+
import { readdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2, createReadStream } from "node:fs";
|
|
16013
16044
|
import { join as join2 } from "node:path";
|
|
16014
|
-
|
|
16045
|
+
import { createInterface } from "node:readline";
|
|
16046
|
+
async function extractTeamName(transcriptPath) {
|
|
16047
|
+
try {
|
|
16048
|
+
const rl = createInterface({
|
|
16049
|
+
input: createReadStream(transcriptPath, "utf-8"),
|
|
16050
|
+
crlfDelay: Infinity
|
|
16051
|
+
});
|
|
16052
|
+
for await (const line of rl) {
|
|
16053
|
+
try {
|
|
16054
|
+
const obj = JSON.parse(line);
|
|
16055
|
+
if (obj.teamName) {
|
|
16056
|
+
rl.close();
|
|
16057
|
+
return obj.teamName;
|
|
16058
|
+
}
|
|
16059
|
+
} catch {
|
|
16060
|
+
continue;
|
|
16061
|
+
}
|
|
16062
|
+
}
|
|
16063
|
+
} catch {}
|
|
16064
|
+
return null;
|
|
16065
|
+
}
|
|
16066
|
+
function registerSession(filePath, data, sessionId) {
|
|
16067
|
+
const ids = data.session_ids ?? [data.session_id];
|
|
16068
|
+
if (!ids.includes(sessionId)) {
|
|
16069
|
+
ids.push(sessionId);
|
|
16070
|
+
}
|
|
16071
|
+
if (!ids.includes(data.session_id)) {
|
|
16072
|
+
ids.unshift(data.session_id);
|
|
16073
|
+
}
|
|
16074
|
+
data.session_ids = ids;
|
|
16075
|
+
try {
|
|
16076
|
+
writeFileSync2(filePath, JSON.stringify(data));
|
|
16077
|
+
} catch {}
|
|
16078
|
+
}
|
|
16079
|
+
async function findRoomId(sessionId, teamsDir, transcriptPath) {
|
|
16015
16080
|
const dir = teamsDir ?? `${process.env.HOME}/.claude/teams`;
|
|
16081
|
+
if (transcriptPath) {
|
|
16082
|
+
const teamName = await extractTeamName(transcriptPath);
|
|
16083
|
+
if (teamName) {
|
|
16084
|
+
const filePath = join2(dir, teamName, "meet-ai.json");
|
|
16085
|
+
try {
|
|
16086
|
+
const raw = readFileSync3(filePath, "utf-8");
|
|
16087
|
+
const data = JSON.parse(raw);
|
|
16088
|
+
registerSession(filePath, data, sessionId);
|
|
16089
|
+
return data.room_id || null;
|
|
16090
|
+
} catch {}
|
|
16091
|
+
}
|
|
16092
|
+
}
|
|
16016
16093
|
let entries;
|
|
16017
16094
|
try {
|
|
16018
16095
|
entries = readdirSync(dir);
|
|
@@ -16024,7 +16101,8 @@ function findRoomId(sessionId, teamsDir) {
|
|
|
16024
16101
|
try {
|
|
16025
16102
|
const raw = readFileSync3(filePath, "utf-8");
|
|
16026
16103
|
const data = JSON.parse(raw);
|
|
16027
|
-
|
|
16104
|
+
const knownIds = data.session_ids ?? [data.session_id];
|
|
16105
|
+
if (knownIds.includes(sessionId) || data.session_id === sessionId) {
|
|
16028
16106
|
return data.room_id || null;
|
|
16029
16107
|
}
|
|
16030
16108
|
} catch {
|
|
@@ -16076,6 +16154,39 @@ function summarize(toolName, toolInput) {
|
|
|
16076
16154
|
var truncate = (s, n) => s.slice(0, n);
|
|
16077
16155
|
var init_summarize = () => {};
|
|
16078
16156
|
|
|
16157
|
+
// src/lib/hooks/format-diff.ts
|
|
16158
|
+
function shortPath(filePath) {
|
|
16159
|
+
const parts = filePath.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
16160
|
+
return parts.slice(-3).join("/");
|
|
16161
|
+
}
|
|
16162
|
+
function formatDiff(filePath, hunks) {
|
|
16163
|
+
const display = shortPath(filePath);
|
|
16164
|
+
const diffLines = hunks.map((hunk) => {
|
|
16165
|
+
const header = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;
|
|
16166
|
+
return `${header}
|
|
16167
|
+
${hunk.lines.join(`
|
|
16168
|
+
`)}`;
|
|
16169
|
+
}).join(`
|
|
16170
|
+
`);
|
|
16171
|
+
return `[diff:${display}]
|
|
16172
|
+
--- a/${display}
|
|
16173
|
+
+++ b/${display}
|
|
16174
|
+
${diffLines}`;
|
|
16175
|
+
}
|
|
16176
|
+
function formatWriteDiff(filePath, content) {
|
|
16177
|
+
const display = shortPath(filePath);
|
|
16178
|
+
const lines = content.split(`
|
|
16179
|
+
`);
|
|
16180
|
+
const header = `@@ -0,0 +1,${lines.length} @@`;
|
|
16181
|
+
const addedLines = lines.map((line) => `+${line}`).join(`
|
|
16182
|
+
`);
|
|
16183
|
+
return `[diff:${display}]
|
|
16184
|
+
--- /dev/null
|
|
16185
|
+
+++ b/${display}
|
|
16186
|
+
${header}
|
|
16187
|
+
${addedLines}`;
|
|
16188
|
+
}
|
|
16189
|
+
|
|
16079
16190
|
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/utils/url.js
|
|
16080
16191
|
var init_url = () => {};
|
|
16081
16192
|
|
|
@@ -16427,7 +16538,7 @@ var init_hooks = __esm(() => {
|
|
|
16427
16538
|
});
|
|
16428
16539
|
|
|
16429
16540
|
// src/commands/hook/log-tool-use/usecase.ts
|
|
16430
|
-
import { readFileSync as readFileSync4, writeFileSync as
|
|
16541
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, statSync as statSync2, rmSync } from "node:fs";
|
|
16431
16542
|
function getOrCreateParentId(sessionId) {
|
|
16432
16543
|
const path = `/tmp/meet-ai-hook-${sessionId}.msgid`;
|
|
16433
16544
|
try {
|
|
@@ -16443,7 +16554,7 @@ function getOrCreateParentId(sessionId) {
|
|
|
16443
16554
|
}
|
|
16444
16555
|
function saveParentId(sessionId, msgId) {
|
|
16445
16556
|
try {
|
|
16446
|
-
|
|
16557
|
+
writeFileSync3(`/tmp/meet-ai-hook-${sessionId}.msgid`, msgId);
|
|
16447
16558
|
} catch {}
|
|
16448
16559
|
}
|
|
16449
16560
|
async function processHookInput(rawInput, teamsDir) {
|
|
@@ -16453,7 +16564,13 @@ async function processHookInput(rawInput, teamsDir) {
|
|
|
16453
16564
|
} catch {
|
|
16454
16565
|
return "skip";
|
|
16455
16566
|
}
|
|
16456
|
-
const {
|
|
16567
|
+
const {
|
|
16568
|
+
session_id: sessionId,
|
|
16569
|
+
transcript_path: transcriptPath,
|
|
16570
|
+
tool_name: toolName,
|
|
16571
|
+
tool_input: toolInput = {},
|
|
16572
|
+
tool_response: toolResponse
|
|
16573
|
+
} = input;
|
|
16457
16574
|
if (!sessionId || !toolName)
|
|
16458
16575
|
return "skip";
|
|
16459
16576
|
if (toolName === "SendMessage")
|
|
@@ -16463,7 +16580,7 @@ async function processHookInput(rawInput, teamsDir) {
|
|
|
16463
16580
|
if (cmd.startsWith("cd ") || cmd.startsWith("meet-ai "))
|
|
16464
16581
|
return "skip";
|
|
16465
16582
|
}
|
|
16466
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
16583
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
16467
16584
|
if (!roomId)
|
|
16468
16585
|
return "skip";
|
|
16469
16586
|
const url2 = process.env.MEET_AI_URL;
|
|
@@ -16471,6 +16588,31 @@ async function processHookInput(rawInput, teamsDir) {
|
|
|
16471
16588
|
if (!url2 || !key)
|
|
16472
16589
|
return "skip";
|
|
16473
16590
|
const client = createHookClient(url2, key);
|
|
16591
|
+
if (toolName === "Edit" && toolResponse?.structuredPatch) {
|
|
16592
|
+
const hunks = toolResponse.structuredPatch;
|
|
16593
|
+
const filePath = typeof toolInput.file_path === "string" ? toolInput.file_path : "?";
|
|
16594
|
+
const diffContent = formatDiff(filePath, hunks);
|
|
16595
|
+
let parentId2 = getOrCreateParentId(sessionId);
|
|
16596
|
+
if (!parentId2) {
|
|
16597
|
+
parentId2 = await sendParentMessage(client, roomId);
|
|
16598
|
+
if (parentId2)
|
|
16599
|
+
saveParentId(sessionId, parentId2);
|
|
16600
|
+
}
|
|
16601
|
+
await sendLogEntry(client, roomId, diffContent, parentId2 ?? undefined);
|
|
16602
|
+
return "sent";
|
|
16603
|
+
}
|
|
16604
|
+
if (toolName === "Write" && typeof toolInput.content === "string") {
|
|
16605
|
+
const filePath = typeof toolInput.file_path === "string" ? toolInput.file_path : "?";
|
|
16606
|
+
const diffContent = formatWriteDiff(filePath, toolInput.content);
|
|
16607
|
+
let parentId2 = getOrCreateParentId(sessionId);
|
|
16608
|
+
if (!parentId2) {
|
|
16609
|
+
parentId2 = await sendParentMessage(client, roomId);
|
|
16610
|
+
if (parentId2)
|
|
16611
|
+
saveParentId(sessionId, parentId2);
|
|
16612
|
+
}
|
|
16613
|
+
await sendLogEntry(client, roomId, diffContent, parentId2 ?? undefined);
|
|
16614
|
+
return "sent";
|
|
16615
|
+
}
|
|
16474
16616
|
const summary = summarize(toolName, toolInput);
|
|
16475
16617
|
let parentId = getOrCreateParentId(sessionId);
|
|
16476
16618
|
if (!parentId) {
|
|
@@ -16614,14 +16756,14 @@ async function processPlanReview(rawInput, teamsDir) {
|
|
|
16614
16756
|
`);
|
|
16615
16757
|
return;
|
|
16616
16758
|
}
|
|
16617
|
-
const { session_id: sessionId } = input;
|
|
16759
|
+
const { session_id: sessionId, transcript_path: transcriptPath } = input;
|
|
16618
16760
|
if (!sessionId) {
|
|
16619
16761
|
process.stderr.write(`[plan-review] missing session_id
|
|
16620
16762
|
`);
|
|
16621
16763
|
return;
|
|
16622
16764
|
}
|
|
16623
16765
|
const planContent = input.tool_input?.plan || "_Agent requested to exit plan mode without a plan._";
|
|
16624
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
16766
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
16625
16767
|
if (!roomId) {
|
|
16626
16768
|
process.stderr.write(`[plan-review] no room found for session
|
|
16627
16769
|
`);
|
|
@@ -16802,7 +16944,7 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
|
|
|
16802
16944
|
`);
|
|
16803
16945
|
return;
|
|
16804
16946
|
}
|
|
16805
|
-
const { session_id: sessionId, hook_event_name: hookEventName, tool_input: toolInput } = input;
|
|
16947
|
+
const { session_id: sessionId, transcript_path: transcriptPath, hook_event_name: hookEventName, tool_input: toolInput } = input;
|
|
16806
16948
|
if (!sessionId || !toolInput?.questions?.length) {
|
|
16807
16949
|
process.stderr.write(`[question-review] missing session_id or questions
|
|
16808
16950
|
`);
|
|
@@ -16810,7 +16952,7 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
|
|
|
16810
16952
|
}
|
|
16811
16953
|
process.stderr.write(`[question-review] triggered by ${hookEventName} event
|
|
16812
16954
|
`);
|
|
16813
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
16955
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
16814
16956
|
if (!roomId) {
|
|
16815
16957
|
process.stderr.write(`[question-review] no room found for session
|
|
16816
16958
|
`);
|
|
@@ -16999,7 +17141,7 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
|
|
|
16999
17141
|
`);
|
|
17000
17142
|
return;
|
|
17001
17143
|
}
|
|
17002
|
-
const { session_id: sessionId, hook_event_name: hookEventName, tool_name: toolName, tool_input: toolInput } = input;
|
|
17144
|
+
const { session_id: sessionId, transcript_path: transcriptPath, hook_event_name: hookEventName, tool_name: toolName, tool_input: toolInput } = input;
|
|
17003
17145
|
if (!sessionId || !toolName) {
|
|
17004
17146
|
process.stderr.write(`[permission-review] missing session_id or tool_name
|
|
17005
17147
|
`);
|
|
@@ -17013,7 +17155,7 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
|
|
|
17013
17155
|
}
|
|
17014
17156
|
process.stderr.write(`[permission-review] triggered by ${hookEventName} for tool ${toolName}
|
|
17015
17157
|
`);
|
|
17016
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
17158
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
17017
17159
|
if (!roomId) {
|
|
17018
17160
|
process.stderr.write(`[permission-review] no room found for session
|
|
17019
17161
|
`);
|
|
@@ -54928,7 +55070,7 @@ var init_build2 = __esm(async () => {
|
|
|
54928
55070
|
});
|
|
54929
55071
|
|
|
54930
55072
|
// src/lib/process-manager.ts
|
|
54931
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as
|
|
55073
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync, lstatSync } from "node:fs";
|
|
54932
55074
|
import { homedir as homedir4 } from "node:os";
|
|
54933
55075
|
import { join as join4 } from "node:path";
|
|
54934
55076
|
function readRegistry() {
|
|
@@ -54950,7 +55092,7 @@ function writeRegistry(entries) {
|
|
|
54950
55092
|
return;
|
|
54951
55093
|
}
|
|
54952
55094
|
const tmpPath = join4(REGISTRY_DIR, `sessions.${process.pid}.${Date.now()}.tmp`);
|
|
54953
|
-
|
|
55095
|
+
writeFileSync4(tmpPath, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
54954
55096
|
renameSync(tmpPath, REGISTRY_PATH);
|
|
54955
55097
|
}
|
|
54956
55098
|
function addToRegistry(entry) {
|
|
@@ -56417,7 +56559,7 @@ init_output();
|
|
|
56417
56559
|
var main = defineCommand({
|
|
56418
56560
|
meta: {
|
|
56419
56561
|
name: "meet-ai",
|
|
56420
|
-
version: "0.0.
|
|
56562
|
+
version: "0.0.32",
|
|
56421
56563
|
description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
|
|
56422
56564
|
},
|
|
56423
56565
|
args: {
|