@meet-ai/cli 0.0.31 → 0.0.33
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 +180 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16040,10 +16040,57 @@ var init_command10 = __esm(() => {
|
|
|
16040
16040
|
});
|
|
16041
16041
|
|
|
16042
16042
|
// src/lib/hooks/find-room.ts
|
|
16043
|
-
import { readdirSync, readFileSync as readFileSync3 } from "node:fs";
|
|
16043
|
+
import { readdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2, createReadStream } from "node:fs";
|
|
16044
16044
|
import { join as join2 } from "node:path";
|
|
16045
|
-
|
|
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 findRoom(sessionId, teamsDir, transcriptPath) {
|
|
16046
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
|
+
if (data.room_id)
|
|
16090
|
+
return { roomId: data.room_id, teamName: data.team_name || teamName };
|
|
16091
|
+
} catch {}
|
|
16092
|
+
}
|
|
16093
|
+
}
|
|
16047
16094
|
let entries;
|
|
16048
16095
|
try {
|
|
16049
16096
|
entries = readdirSync(dir);
|
|
@@ -16055,8 +16102,11 @@ function findRoomId(sessionId, teamsDir) {
|
|
|
16055
16102
|
try {
|
|
16056
16103
|
const raw = readFileSync3(filePath, "utf-8");
|
|
16057
16104
|
const data = JSON.parse(raw);
|
|
16058
|
-
|
|
16059
|
-
|
|
16105
|
+
const knownIds = data.session_ids ?? [data.session_id];
|
|
16106
|
+
if (knownIds.includes(sessionId) || data.session_id === sessionId) {
|
|
16107
|
+
if (data.room_id)
|
|
16108
|
+
return { roomId: data.room_id, teamName: data.team_name || entry };
|
|
16109
|
+
return null;
|
|
16060
16110
|
}
|
|
16061
16111
|
} catch {
|
|
16062
16112
|
continue;
|
|
@@ -16064,6 +16114,10 @@ function findRoomId(sessionId, teamsDir) {
|
|
|
16064
16114
|
}
|
|
16065
16115
|
return null;
|
|
16066
16116
|
}
|
|
16117
|
+
async function findRoomId(sessionId, teamsDir, transcriptPath) {
|
|
16118
|
+
const result = await findRoom(sessionId, teamsDir, transcriptPath);
|
|
16119
|
+
return result?.roomId ?? null;
|
|
16120
|
+
}
|
|
16067
16121
|
var init_find_room = () => {};
|
|
16068
16122
|
|
|
16069
16123
|
// src/lib/hooks/summarize.ts
|
|
@@ -16107,6 +16161,39 @@ function summarize(toolName, toolInput) {
|
|
|
16107
16161
|
var truncate = (s, n) => s.slice(0, n);
|
|
16108
16162
|
var init_summarize = () => {};
|
|
16109
16163
|
|
|
16164
|
+
// src/lib/hooks/format-diff.ts
|
|
16165
|
+
function shortPath(filePath) {
|
|
16166
|
+
const parts = filePath.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
16167
|
+
return parts.slice(-3).join("/");
|
|
16168
|
+
}
|
|
16169
|
+
function formatDiff(filePath, hunks) {
|
|
16170
|
+
const display = shortPath(filePath);
|
|
16171
|
+
const diffLines = hunks.map((hunk) => {
|
|
16172
|
+
const header = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;
|
|
16173
|
+
return `${header}
|
|
16174
|
+
${hunk.lines.join(`
|
|
16175
|
+
`)}`;
|
|
16176
|
+
}).join(`
|
|
16177
|
+
`);
|
|
16178
|
+
return `[diff:${display}]
|
|
16179
|
+
--- a/${display}
|
|
16180
|
+
+++ b/${display}
|
|
16181
|
+
${diffLines}`;
|
|
16182
|
+
}
|
|
16183
|
+
function formatWriteDiff(filePath, content) {
|
|
16184
|
+
const display = shortPath(filePath);
|
|
16185
|
+
const lines = content.split(`
|
|
16186
|
+
`);
|
|
16187
|
+
const header = `@@ -0,0 +1,${lines.length} @@`;
|
|
16188
|
+
const addedLines = lines.map((line) => `+${line}`).join(`
|
|
16189
|
+
`);
|
|
16190
|
+
return `[diff:${display}]
|
|
16191
|
+
--- /dev/null
|
|
16192
|
+
+++ b/${display}
|
|
16193
|
+
${header}
|
|
16194
|
+
${addedLines}`;
|
|
16195
|
+
}
|
|
16196
|
+
|
|
16110
16197
|
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/utils/url.js
|
|
16111
16198
|
var init_url = () => {};
|
|
16112
16199
|
|
|
@@ -16432,6 +16519,14 @@ async function sendParentMessage(client, roomId) {
|
|
|
16432
16519
|
return null;
|
|
16433
16520
|
}
|
|
16434
16521
|
}
|
|
16522
|
+
async function sendTeamMemberUpsert(client, roomId, teamName, member) {
|
|
16523
|
+
try {
|
|
16524
|
+
await client.api.rooms[":id"]["team-info"].members.$patch({
|
|
16525
|
+
param: { id: roomId },
|
|
16526
|
+
json: { team_name: teamName, member }
|
|
16527
|
+
});
|
|
16528
|
+
} catch {}
|
|
16529
|
+
}
|
|
16435
16530
|
async function sendLogEntry(client, roomId, summary, messageId) {
|
|
16436
16531
|
try {
|
|
16437
16532
|
await client.api.rooms[":id"].logs.$post({
|
|
@@ -16458,7 +16553,7 @@ var init_hooks = __esm(() => {
|
|
|
16458
16553
|
});
|
|
16459
16554
|
|
|
16460
16555
|
// src/commands/hook/log-tool-use/usecase.ts
|
|
16461
|
-
import { readFileSync as readFileSync4, writeFileSync as
|
|
16556
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, statSync as statSync2, rmSync } from "node:fs";
|
|
16462
16557
|
function getOrCreateParentId(sessionId) {
|
|
16463
16558
|
const path = `/tmp/meet-ai-hook-${sessionId}.msgid`;
|
|
16464
16559
|
try {
|
|
@@ -16474,7 +16569,7 @@ function getOrCreateParentId(sessionId) {
|
|
|
16474
16569
|
}
|
|
16475
16570
|
function saveParentId(sessionId, msgId) {
|
|
16476
16571
|
try {
|
|
16477
|
-
|
|
16572
|
+
writeFileSync3(`/tmp/meet-ai-hook-${sessionId}.msgid`, msgId);
|
|
16478
16573
|
} catch {}
|
|
16479
16574
|
}
|
|
16480
16575
|
async function processHookInput(rawInput, teamsDir) {
|
|
@@ -16484,24 +16579,89 @@ async function processHookInput(rawInput, teamsDir) {
|
|
|
16484
16579
|
} catch {
|
|
16485
16580
|
return "skip";
|
|
16486
16581
|
}
|
|
16487
|
-
const {
|
|
16582
|
+
const {
|
|
16583
|
+
session_id: sessionId,
|
|
16584
|
+
transcript_path: transcriptPath,
|
|
16585
|
+
tool_name: toolName,
|
|
16586
|
+
tool_input: toolInput = {},
|
|
16587
|
+
tool_response: toolResponse
|
|
16588
|
+
} = input;
|
|
16488
16589
|
if (!sessionId || !toolName)
|
|
16489
16590
|
return "skip";
|
|
16490
|
-
if (toolName === "SendMessage")
|
|
16491
|
-
return "skip";
|
|
16492
16591
|
if (toolName === "Bash") {
|
|
16493
16592
|
const cmd = typeof toolInput.command === "string" ? toolInput.command : "";
|
|
16494
16593
|
if (cmd.startsWith("cd ") || cmd.startsWith("meet-ai "))
|
|
16495
16594
|
return "skip";
|
|
16496
16595
|
}
|
|
16497
|
-
const
|
|
16498
|
-
if (!
|
|
16596
|
+
const room = await findRoom(sessionId, teamsDir, transcriptPath);
|
|
16597
|
+
if (!room)
|
|
16499
16598
|
return "skip";
|
|
16599
|
+
const { roomId, teamName } = room;
|
|
16500
16600
|
const url2 = process.env.MEET_AI_URL;
|
|
16501
16601
|
const key = process.env.MEET_AI_KEY;
|
|
16502
16602
|
if (!url2 || !key)
|
|
16503
16603
|
return "skip";
|
|
16504
16604
|
const client = createHookClient(url2, key);
|
|
16605
|
+
if (toolName === "Agent" && toolResponse) {
|
|
16606
|
+
const status = toolResponse.status;
|
|
16607
|
+
if (status === "teammate_spawned") {
|
|
16608
|
+
await sendTeamMemberUpsert(client, roomId, toolResponse.team_name, {
|
|
16609
|
+
teammate_id: toolResponse.teammate_id,
|
|
16610
|
+
name: toolResponse.name,
|
|
16611
|
+
color: toolResponse.color,
|
|
16612
|
+
role: toolResponse.agent_type || "teammate",
|
|
16613
|
+
model: toolResponse.model || "unknown",
|
|
16614
|
+
status: "active",
|
|
16615
|
+
joinedAt: Date.now()
|
|
16616
|
+
});
|
|
16617
|
+
}
|
|
16618
|
+
}
|
|
16619
|
+
if (toolName === "SendMessage") {
|
|
16620
|
+
const inputType = toolInput.type;
|
|
16621
|
+
const approve = toolInput.approve;
|
|
16622
|
+
if (inputType === "shutdown_response" && approve === true) {
|
|
16623
|
+
const requestId = toolInput.request_id;
|
|
16624
|
+
const agentName = requestId?.split("@")[1];
|
|
16625
|
+
if (agentName) {
|
|
16626
|
+
const teammateId = teamName ? `${agentName}@${teamName}` : agentName;
|
|
16627
|
+
await sendTeamMemberUpsert(client, roomId, teamName, {
|
|
16628
|
+
teammate_id: teammateId,
|
|
16629
|
+
name: agentName,
|
|
16630
|
+
color: "#555",
|
|
16631
|
+
role: "teammate",
|
|
16632
|
+
model: "unknown",
|
|
16633
|
+
status: "inactive",
|
|
16634
|
+
joinedAt: 0
|
|
16635
|
+
});
|
|
16636
|
+
}
|
|
16637
|
+
}
|
|
16638
|
+
return "skip";
|
|
16639
|
+
}
|
|
16640
|
+
if (toolName === "Edit" && toolResponse?.structuredPatch) {
|
|
16641
|
+
const hunks = toolResponse.structuredPatch;
|
|
16642
|
+
const filePath = typeof toolInput.file_path === "string" ? toolInput.file_path : "?";
|
|
16643
|
+
const diffContent = formatDiff(filePath, hunks);
|
|
16644
|
+
let parentId2 = getOrCreateParentId(sessionId);
|
|
16645
|
+
if (!parentId2) {
|
|
16646
|
+
parentId2 = await sendParentMessage(client, roomId);
|
|
16647
|
+
if (parentId2)
|
|
16648
|
+
saveParentId(sessionId, parentId2);
|
|
16649
|
+
}
|
|
16650
|
+
await sendLogEntry(client, roomId, diffContent, parentId2 ?? undefined);
|
|
16651
|
+
return "sent";
|
|
16652
|
+
}
|
|
16653
|
+
if (toolName === "Write" && typeof toolInput.content === "string") {
|
|
16654
|
+
const filePath = typeof toolInput.file_path === "string" ? toolInput.file_path : "?";
|
|
16655
|
+
const diffContent = formatWriteDiff(filePath, toolInput.content);
|
|
16656
|
+
let parentId2 = getOrCreateParentId(sessionId);
|
|
16657
|
+
if (!parentId2) {
|
|
16658
|
+
parentId2 = await sendParentMessage(client, roomId);
|
|
16659
|
+
if (parentId2)
|
|
16660
|
+
saveParentId(sessionId, parentId2);
|
|
16661
|
+
}
|
|
16662
|
+
await sendLogEntry(client, roomId, diffContent, parentId2 ?? undefined);
|
|
16663
|
+
return "sent";
|
|
16664
|
+
}
|
|
16505
16665
|
const summary = summarize(toolName, toolInput);
|
|
16506
16666
|
let parentId = getOrCreateParentId(sessionId);
|
|
16507
16667
|
if (!parentId) {
|
|
@@ -16645,14 +16805,14 @@ async function processPlanReview(rawInput, teamsDir) {
|
|
|
16645
16805
|
`);
|
|
16646
16806
|
return;
|
|
16647
16807
|
}
|
|
16648
|
-
const { session_id: sessionId } = input;
|
|
16808
|
+
const { session_id: sessionId, transcript_path: transcriptPath } = input;
|
|
16649
16809
|
if (!sessionId) {
|
|
16650
16810
|
process.stderr.write(`[plan-review] missing session_id
|
|
16651
16811
|
`);
|
|
16652
16812
|
return;
|
|
16653
16813
|
}
|
|
16654
16814
|
const planContent = input.tool_input?.plan || "_Agent requested to exit plan mode without a plan._";
|
|
16655
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
16815
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
16656
16816
|
if (!roomId) {
|
|
16657
16817
|
process.stderr.write(`[plan-review] no room found for session
|
|
16658
16818
|
`);
|
|
@@ -16833,7 +16993,7 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
|
|
|
16833
16993
|
`);
|
|
16834
16994
|
return;
|
|
16835
16995
|
}
|
|
16836
|
-
const { session_id: sessionId, hook_event_name: hookEventName, tool_input: toolInput } = input;
|
|
16996
|
+
const { session_id: sessionId, transcript_path: transcriptPath, hook_event_name: hookEventName, tool_input: toolInput } = input;
|
|
16837
16997
|
if (!sessionId || !toolInput?.questions?.length) {
|
|
16838
16998
|
process.stderr.write(`[question-review] missing session_id or questions
|
|
16839
16999
|
`);
|
|
@@ -16841,7 +17001,7 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
|
|
|
16841
17001
|
}
|
|
16842
17002
|
process.stderr.write(`[question-review] triggered by ${hookEventName} event
|
|
16843
17003
|
`);
|
|
16844
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
17004
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
16845
17005
|
if (!roomId) {
|
|
16846
17006
|
process.stderr.write(`[question-review] no room found for session
|
|
16847
17007
|
`);
|
|
@@ -17030,7 +17190,7 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
|
|
|
17030
17190
|
`);
|
|
17031
17191
|
return;
|
|
17032
17192
|
}
|
|
17033
|
-
const { session_id: sessionId, hook_event_name: hookEventName, tool_name: toolName, tool_input: toolInput } = input;
|
|
17193
|
+
const { session_id: sessionId, transcript_path: transcriptPath, hook_event_name: hookEventName, tool_name: toolName, tool_input: toolInput } = input;
|
|
17034
17194
|
if (!sessionId || !toolName) {
|
|
17035
17195
|
process.stderr.write(`[permission-review] missing session_id or tool_name
|
|
17036
17196
|
`);
|
|
@@ -17044,7 +17204,7 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
|
|
|
17044
17204
|
}
|
|
17045
17205
|
process.stderr.write(`[permission-review] triggered by ${hookEventName} for tool ${toolName}
|
|
17046
17206
|
`);
|
|
17047
|
-
const roomId = findRoomId(sessionId, teamsDir);
|
|
17207
|
+
const roomId = await findRoomId(sessionId, teamsDir, transcriptPath);
|
|
17048
17208
|
if (!roomId) {
|
|
17049
17209
|
process.stderr.write(`[permission-review] no room found for session
|
|
17050
17210
|
`);
|
|
@@ -54959,7 +55119,7 @@ var init_build2 = __esm(async () => {
|
|
|
54959
55119
|
});
|
|
54960
55120
|
|
|
54961
55121
|
// src/lib/process-manager.ts
|
|
54962
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as
|
|
55122
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync, lstatSync } from "node:fs";
|
|
54963
55123
|
import { homedir as homedir4 } from "node:os";
|
|
54964
55124
|
import { join as join4 } from "node:path";
|
|
54965
55125
|
function readRegistry() {
|
|
@@ -54981,7 +55141,7 @@ function writeRegistry(entries) {
|
|
|
54981
55141
|
return;
|
|
54982
55142
|
}
|
|
54983
55143
|
const tmpPath = join4(REGISTRY_DIR, `sessions.${process.pid}.${Date.now()}.tmp`);
|
|
54984
|
-
|
|
55144
|
+
writeFileSync4(tmpPath, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
54985
55145
|
renameSync(tmpPath, REGISTRY_PATH);
|
|
54986
55146
|
}
|
|
54987
55147
|
function addToRegistry(entry) {
|
|
@@ -56448,7 +56608,7 @@ init_output();
|
|
|
56448
56608
|
var main = defineCommand({
|
|
56449
56609
|
meta: {
|
|
56450
56610
|
name: "meet-ai",
|
|
56451
|
-
version: "0.0.
|
|
56611
|
+
version: "0.0.33",
|
|
56452
56612
|
description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
|
|
56453
56613
|
},
|
|
56454
56614
|
args: {
|