@meet-ai/cli 0.0.34 → 0.0.36
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 +1940 -782
- package/package.json +2 -1
- package/README.md +0 -114
package/dist/index.js
CHANGED
|
@@ -1590,10 +1590,10 @@ function fixedBase64(bodyLength, padding) {
|
|
|
1590
1590
|
function fixedBase64url(length) {
|
|
1591
1591
|
return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
|
|
1592
1592
|
}
|
|
1593
|
-
var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uuid = (
|
|
1594
|
-
if (!
|
|
1593
|
+
var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uuid = (version2) => {
|
|
1594
|
+
if (!version2)
|
|
1595
1595
|
return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
|
|
1596
|
-
return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${
|
|
1596
|
+
return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
|
|
1597
1597
|
}, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (delimiter) => {
|
|
1598
1598
|
const escapedDelim = escapeRegex(delimiter ?? ":");
|
|
1599
1599
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
@@ -2249,9 +2249,9 @@ class Doc {
|
|
|
2249
2249
|
}
|
|
2250
2250
|
|
|
2251
2251
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/versions.js
|
|
2252
|
-
var
|
|
2252
|
+
var version2;
|
|
2253
2253
|
var init_versions = __esm(() => {
|
|
2254
|
-
|
|
2254
|
+
version2 = {
|
|
2255
2255
|
major: 4,
|
|
2256
2256
|
minor: 3,
|
|
2257
2257
|
patch: 6
|
|
@@ -2627,7 +2627,7 @@ var init_schemas = __esm(() => {
|
|
|
2627
2627
|
inst ?? (inst = {});
|
|
2628
2628
|
inst._zod.def = def;
|
|
2629
2629
|
inst._zod.bag = inst._zod.bag || {};
|
|
2630
|
-
inst._zod.version =
|
|
2630
|
+
inst._zod.version = version2;
|
|
2631
2631
|
const checks = [...inst._zod.def.checks ?? []];
|
|
2632
2632
|
if (inst._zod.traits.has("$ZodCheck")) {
|
|
2633
2633
|
checks.unshift(inst);
|
|
@@ -11912,7 +11912,7 @@ var init_json_schema = () => {};
|
|
|
11912
11912
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/index.js
|
|
11913
11913
|
var exports_core2 = {};
|
|
11914
11914
|
__export(exports_core2, {
|
|
11915
|
-
version: () =>
|
|
11915
|
+
version: () => version2,
|
|
11916
11916
|
util: () => exports_util,
|
|
11917
11917
|
treeifyError: () => treeifyError,
|
|
11918
11918
|
toJSONSchema: () => toJSONSchema,
|
|
@@ -14012,10 +14012,10 @@ function fromJSONSchema(schema, params) {
|
|
|
14012
14012
|
if (typeof schema === "boolean") {
|
|
14013
14013
|
return schema ? z.any() : z.never();
|
|
14014
14014
|
}
|
|
14015
|
-
const
|
|
14015
|
+
const version3 = detectVersion(schema, params?.defaultTarget);
|
|
14016
14016
|
const defs = schema.$defs || schema.definitions || {};
|
|
14017
14017
|
const ctx = {
|
|
14018
|
-
version:
|
|
14018
|
+
version: version3,
|
|
14019
14019
|
defs,
|
|
14020
14020
|
refs: new Map,
|
|
14021
14021
|
processing: new Set,
|
|
@@ -14390,6 +14390,100 @@ var init_zod = __esm(() => {
|
|
|
14390
14390
|
init_external();
|
|
14391
14391
|
});
|
|
14392
14392
|
|
|
14393
|
+
// src/lib/codex.ts
|
|
14394
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
14395
|
+
import { homedir } from "node:os";
|
|
14396
|
+
import { dirname, join, resolve } from "node:path";
|
|
14397
|
+
function getCodexHome(options) {
|
|
14398
|
+
if (options?.codexHome)
|
|
14399
|
+
return options.codexHome;
|
|
14400
|
+
if (options?.env?.CODEX_HOME)
|
|
14401
|
+
return options.env.CODEX_HOME;
|
|
14402
|
+
if (process.env.CODEX_HOME)
|
|
14403
|
+
return process.env.CODEX_HOME;
|
|
14404
|
+
if (process.env.MEET_AI_CODEX_STATE_DIR)
|
|
14405
|
+
return process.env.MEET_AI_CODEX_STATE_DIR;
|
|
14406
|
+
return join(homedir(), ".codex");
|
|
14407
|
+
}
|
|
14408
|
+
function getCodexConfigPaths(options) {
|
|
14409
|
+
const home = getCodexHome(options);
|
|
14410
|
+
return [
|
|
14411
|
+
resolve(".codex/config.json"),
|
|
14412
|
+
resolve(".codex/config.toml"),
|
|
14413
|
+
join(home, "config.json"),
|
|
14414
|
+
join(home, "config.toml")
|
|
14415
|
+
];
|
|
14416
|
+
}
|
|
14417
|
+
function parseCodexTomlEnv(path) {
|
|
14418
|
+
if (!existsSync(path))
|
|
14419
|
+
return null;
|
|
14420
|
+
const env = {};
|
|
14421
|
+
let inEnvSection = false;
|
|
14422
|
+
for (const line of readFileSync(path, "utf-8").split(/\r?\n/)) {
|
|
14423
|
+
const trimmed = line.trim();
|
|
14424
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
14425
|
+
continue;
|
|
14426
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
14427
|
+
inEnvSection = trimmed === "[env]";
|
|
14428
|
+
continue;
|
|
14429
|
+
}
|
|
14430
|
+
if (!inEnvSection)
|
|
14431
|
+
continue;
|
|
14432
|
+
const match = trimmed.match(/^([A-Z0-9_]+)\s*=\s*"([^"]*)"$/);
|
|
14433
|
+
if (!match)
|
|
14434
|
+
continue;
|
|
14435
|
+
env[match[1]] = match[2];
|
|
14436
|
+
}
|
|
14437
|
+
return Object.keys(env).length > 0 ? env : null;
|
|
14438
|
+
}
|
|
14439
|
+
function readCodexConfigEnv(options) {
|
|
14440
|
+
for (const path of getCodexConfigPaths(options)) {
|
|
14441
|
+
if (!existsSync(path))
|
|
14442
|
+
continue;
|
|
14443
|
+
if (path.endsWith(".json")) {
|
|
14444
|
+
try {
|
|
14445
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
14446
|
+
if (parsed.env && Object.keys(parsed.env).length > 0) {
|
|
14447
|
+
return parsed.env;
|
|
14448
|
+
}
|
|
14449
|
+
} catch {
|
|
14450
|
+
continue;
|
|
14451
|
+
}
|
|
14452
|
+
continue;
|
|
14453
|
+
}
|
|
14454
|
+
const env = parseCodexTomlEnv(path);
|
|
14455
|
+
if (env)
|
|
14456
|
+
return env;
|
|
14457
|
+
}
|
|
14458
|
+
return null;
|
|
14459
|
+
}
|
|
14460
|
+
function getInboxPath(sessionId, options) {
|
|
14461
|
+
return join(getCodexHome(options), "meet-ai", "inbox", `${sessionId}.json`);
|
|
14462
|
+
}
|
|
14463
|
+
function appendCodexInboxEntry(sessionId, entry, options) {
|
|
14464
|
+
const path = getInboxPath(sessionId, options);
|
|
14465
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
14466
|
+
let entries = [];
|
|
14467
|
+
try {
|
|
14468
|
+
entries = JSON.parse(readFileSync(path, "utf-8"));
|
|
14469
|
+
} catch {
|
|
14470
|
+
entries = [];
|
|
14471
|
+
}
|
|
14472
|
+
entries.push(entry);
|
|
14473
|
+
writeFileSync(path, `${JSON.stringify(entries, null, 2)}
|
|
14474
|
+
`);
|
|
14475
|
+
return path;
|
|
14476
|
+
}
|
|
14477
|
+
var init_codex = () => {};
|
|
14478
|
+
|
|
14479
|
+
// src/runtime.ts
|
|
14480
|
+
function getMeetAiRuntime(env = process.env) {
|
|
14481
|
+
const raw = env.MEET_AI_RUNTIME?.trim().toLowerCase();
|
|
14482
|
+
if (raw === "codex")
|
|
14483
|
+
return "codex";
|
|
14484
|
+
return "claude";
|
|
14485
|
+
}
|
|
14486
|
+
|
|
14393
14487
|
// src/config.ts
|
|
14394
14488
|
var exports_config = {};
|
|
14395
14489
|
__export(exports_config, {
|
|
@@ -14397,15 +14491,15 @@ __export(exports_config, {
|
|
|
14397
14491
|
getMeetAiConfig: () => getMeetAiConfig,
|
|
14398
14492
|
configSchema: () => configSchema
|
|
14399
14493
|
});
|
|
14400
|
-
import { readFileSync, existsSync } from "node:fs";
|
|
14401
|
-
import { join, resolve } from "node:path";
|
|
14402
|
-
import { homedir } from "node:os";
|
|
14494
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
|
|
14495
|
+
import { join as join2, resolve as resolve2 } from "node:path";
|
|
14496
|
+
import { homedir as homedir2 } from "node:os";
|
|
14403
14497
|
function loadSettingsFromPath(path) {
|
|
14404
14498
|
try {
|
|
14405
|
-
if (!
|
|
14499
|
+
if (!existsSync2(path)) {
|
|
14406
14500
|
return null;
|
|
14407
14501
|
}
|
|
14408
|
-
const content =
|
|
14502
|
+
const content = readFileSync2(path, "utf-8");
|
|
14409
14503
|
return JSON.parse(content);
|
|
14410
14504
|
} catch {
|
|
14411
14505
|
return null;
|
|
@@ -14418,7 +14512,16 @@ function resolveRawConfig(opts) {
|
|
|
14418
14512
|
key: process.env.MEET_AI_KEY
|
|
14419
14513
|
};
|
|
14420
14514
|
}
|
|
14421
|
-
|
|
14515
|
+
if (getMeetAiRuntime() === "codex") {
|
|
14516
|
+
const codexEnv = readCodexConfigEnv({ codexHome: opts?.codexHome });
|
|
14517
|
+
if (codexEnv?.MEET_AI_URL) {
|
|
14518
|
+
return {
|
|
14519
|
+
url: codexEnv.MEET_AI_URL,
|
|
14520
|
+
key: codexEnv.MEET_AI_KEY
|
|
14521
|
+
};
|
|
14522
|
+
}
|
|
14523
|
+
}
|
|
14524
|
+
const projectSettingsPath = opts?.projectSettingsPath ?? resolve2("./.claude/settings.json");
|
|
14422
14525
|
const projectSettings = loadSettingsFromPath(projectSettingsPath);
|
|
14423
14526
|
if (projectSettings?.env?.MEET_AI_URL) {
|
|
14424
14527
|
return {
|
|
@@ -14426,7 +14529,7 @@ function resolveRawConfig(opts) {
|
|
|
14426
14529
|
key: projectSettings.env.MEET_AI_KEY
|
|
14427
14530
|
};
|
|
14428
14531
|
}
|
|
14429
|
-
const userSettingsPath =
|
|
14532
|
+
const userSettingsPath = join2(opts?.homeDir ?? homedir2(), ".claude/settings.json");
|
|
14430
14533
|
const userSettings = loadSettingsFromPath(userSettingsPath);
|
|
14431
14534
|
if (userSettings?.env?.MEET_AI_URL) {
|
|
14432
14535
|
return {
|
|
@@ -14450,18 +14553,14 @@ function getMeetAiConfig(opts) {
|
|
|
14450
14553
|
var configSchema;
|
|
14451
14554
|
var init_config = __esm(() => {
|
|
14452
14555
|
init_zod();
|
|
14556
|
+
init_codex();
|
|
14453
14557
|
configSchema = exports_external.object({
|
|
14454
14558
|
url: exports_external.string().url("MEET_AI_URL must be a valid URL"),
|
|
14455
14559
|
key: exports_external.string().optional()
|
|
14456
14560
|
});
|
|
14457
14561
|
});
|
|
14458
14562
|
|
|
14459
|
-
// src/
|
|
14460
|
-
function wsLog(data) {
|
|
14461
|
-
const json2 = JSON.stringify({ ...data, ts: new Date().toISOString() });
|
|
14462
|
-
const isSuccess = data.event === "connected" || data.event === "reconnected" || data.event === "catchup";
|
|
14463
|
-
console.error(isSuccess ? `\x1B[32m${json2}\x1B[0m` : json2);
|
|
14464
|
-
}
|
|
14563
|
+
// src/domain/adapters/HttpTransport.ts
|
|
14465
14564
|
function isRetryable(error48) {
|
|
14466
14565
|
if (error48 instanceof TypeError)
|
|
14467
14566
|
return true;
|
|
@@ -14488,396 +14587,773 @@ async function withRetry(fn, options) {
|
|
|
14488
14587
|
delay_ms: delay,
|
|
14489
14588
|
error: lastError.message
|
|
14490
14589
|
}));
|
|
14491
|
-
await new Promise((
|
|
14590
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
14492
14591
|
}
|
|
14493
14592
|
}
|
|
14494
14593
|
throw lastError;
|
|
14495
14594
|
}
|
|
14496
|
-
function
|
|
14595
|
+
async function parseErrorMessage(res) {
|
|
14497
14596
|
try {
|
|
14498
|
-
const
|
|
14499
|
-
const
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
if (now - mtime > MAX_AGE_MS) {
|
|
14505
|
-
unlinkSync(filePath);
|
|
14506
|
-
}
|
|
14507
|
-
} catch {}
|
|
14508
|
-
}
|
|
14597
|
+
const err2 = await res.json();
|
|
14598
|
+
const msg = err2.error;
|
|
14599
|
+
if (typeof msg === "string")
|
|
14600
|
+
return msg;
|
|
14601
|
+
if (msg)
|
|
14602
|
+
return JSON.stringify(msg);
|
|
14509
14603
|
} catch {}
|
|
14604
|
+
return `HTTP ${res.status}`;
|
|
14510
14605
|
}
|
|
14511
|
-
|
|
14512
|
-
|
|
14606
|
+
|
|
14607
|
+
class HttpTransport {
|
|
14608
|
+
baseUrl;
|
|
14609
|
+
apiKey;
|
|
14610
|
+
constructor(baseUrl, apiKey) {
|
|
14611
|
+
this.baseUrl = baseUrl;
|
|
14612
|
+
this.apiKey = apiKey;
|
|
14613
|
+
}
|
|
14614
|
+
headers(extra) {
|
|
14513
14615
|
const h = { "Content-Type": "application/json", ...extra };
|
|
14514
|
-
if (apiKey) {
|
|
14515
|
-
h["Authorization"] = `Bearer ${apiKey}`;
|
|
14616
|
+
if (this.apiKey) {
|
|
14617
|
+
h["Authorization"] = `Bearer ${this.apiKey}`;
|
|
14516
14618
|
}
|
|
14517
14619
|
return h;
|
|
14518
14620
|
}
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14621
|
+
authHeaders() {
|
|
14622
|
+
return this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : undefined;
|
|
14623
|
+
}
|
|
14624
|
+
buildUrl(path, query) {
|
|
14625
|
+
const params = new URLSearchParams;
|
|
14626
|
+
if (query) {
|
|
14627
|
+
for (const [key, value] of Object.entries(query)) {
|
|
14628
|
+
if (value)
|
|
14629
|
+
params.set(key, value);
|
|
14630
|
+
}
|
|
14631
|
+
}
|
|
14632
|
+
const qs = params.toString();
|
|
14633
|
+
return `${this.baseUrl}${path}${qs ? `?${qs}` : ""}`;
|
|
14634
|
+
}
|
|
14635
|
+
async postJson(path, body, opts) {
|
|
14636
|
+
const doRequest = async () => {
|
|
14637
|
+
const res = await fetch(this.buildUrl(path, opts?.query), {
|
|
14522
14638
|
method: "POST",
|
|
14523
|
-
headers: headers(),
|
|
14524
|
-
body: JSON.stringify(
|
|
14639
|
+
headers: this.headers(),
|
|
14640
|
+
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
14525
14641
|
});
|
|
14526
|
-
if (!res.ok)
|
|
14527
|
-
|
|
14528
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14529
|
-
}
|
|
14642
|
+
if (!res.ok)
|
|
14643
|
+
throw new Error(await parseErrorMessage(res));
|
|
14530
14644
|
return res.json();
|
|
14531
|
-
}
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14541
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14542
|
-
}
|
|
14543
|
-
return res.json();
|
|
14645
|
+
};
|
|
14646
|
+
return opts?.retry ? withRetry(doRequest, opts.retry) : doRequest();
|
|
14647
|
+
}
|
|
14648
|
+
async postText(path, body, opts) {
|
|
14649
|
+
const doRequest = async () => {
|
|
14650
|
+
const res = await fetch(this.buildUrl(path, opts?.query), {
|
|
14651
|
+
method: "POST",
|
|
14652
|
+
headers: this.headers(),
|
|
14653
|
+
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
14544
14654
|
});
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
const url2 = `${baseUrl}/api/rooms/${roomId}/messages${qs ? `?${qs}` : ""}`;
|
|
14556
|
-
const res = await fetch(url2, {
|
|
14557
|
-
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined
|
|
14655
|
+
if (!res.ok)
|
|
14656
|
+
throw new Error(await parseErrorMessage(res));
|
|
14657
|
+
return res.text();
|
|
14658
|
+
};
|
|
14659
|
+
return opts?.retry ? withRetry(doRequest, opts.retry) : doRequest();
|
|
14660
|
+
}
|
|
14661
|
+
async getJson(path, opts) {
|
|
14662
|
+
const doRequest = async () => {
|
|
14663
|
+
const res = await fetch(this.buildUrl(path, opts?.query), {
|
|
14664
|
+
headers: this.authHeaders()
|
|
14558
14665
|
});
|
|
14559
|
-
if (!res.ok)
|
|
14560
|
-
|
|
14561
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14562
|
-
}
|
|
14666
|
+
if (!res.ok)
|
|
14667
|
+
throw new Error(await parseErrorMessage(res));
|
|
14563
14668
|
return res.json();
|
|
14564
|
-
}
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
14589
|
-
|
|
14669
|
+
};
|
|
14670
|
+
return opts?.retry ? withRetry(doRequest, opts.retry) : doRequest();
|
|
14671
|
+
}
|
|
14672
|
+
async getRaw(path) {
|
|
14673
|
+
const res = await fetch(this.buildUrl(path), {
|
|
14674
|
+
headers: this.authHeaders()
|
|
14675
|
+
});
|
|
14676
|
+
if (!res.ok)
|
|
14677
|
+
throw new Error(await parseErrorMessage(res));
|
|
14678
|
+
return res;
|
|
14679
|
+
}
|
|
14680
|
+
async del(path) {
|
|
14681
|
+
const res = await fetch(this.buildUrl(path), {
|
|
14682
|
+
method: "DELETE",
|
|
14683
|
+
headers: this.headers()
|
|
14684
|
+
});
|
|
14685
|
+
if (!res.ok)
|
|
14686
|
+
throw new Error(await parseErrorMessage(res));
|
|
14687
|
+
}
|
|
14688
|
+
}
|
|
14689
|
+
|
|
14690
|
+
// src/coding-agents.ts
|
|
14691
|
+
function isCodingAgentId(value) {
|
|
14692
|
+
return CODING_AGENT_DEFINITIONS.some((agent) => agent.id === value);
|
|
14693
|
+
}
|
|
14694
|
+
var CODING_AGENT_DEFINITIONS;
|
|
14695
|
+
var init_coding_agents = __esm(() => {
|
|
14696
|
+
CODING_AGENT_DEFINITIONS = [
|
|
14697
|
+
{ id: "claude", label: "Claude Code" },
|
|
14698
|
+
{ id: "codex", label: "Codex" }
|
|
14699
|
+
];
|
|
14700
|
+
});
|
|
14701
|
+
|
|
14702
|
+
// src/domain/adapters/ConnectionAdapter.ts
|
|
14703
|
+
function wsLog(data) {
|
|
14704
|
+
const json2 = JSON.stringify({ ...data, ts: new Date().toISOString() });
|
|
14705
|
+
const isSuccess = data.event === "connected" || data.event === "reconnected" || data.event === "catchup";
|
|
14706
|
+
console.error(isSuccess ? `\x1B[32m${json2}\x1B[0m` : json2);
|
|
14707
|
+
}
|
|
14708
|
+
|
|
14709
|
+
class ConnectionAdapter {
|
|
14710
|
+
transport;
|
|
14711
|
+
baseUrl;
|
|
14712
|
+
apiKey;
|
|
14713
|
+
constructor(transport, baseUrl, apiKey) {
|
|
14714
|
+
this.transport = transport;
|
|
14715
|
+
this.baseUrl = baseUrl;
|
|
14716
|
+
this.apiKey = apiKey;
|
|
14717
|
+
}
|
|
14718
|
+
listen(roomId, options) {
|
|
14719
|
+
const wsUrl = this.baseUrl.replace(/^http/, "ws");
|
|
14720
|
+
const wsHeaders = this.apiKey ? { headers: { Authorization: `Bearer ${this.apiKey}` } } : undefined;
|
|
14721
|
+
let pingInterval = null;
|
|
14722
|
+
let reconnectAttempt = 0;
|
|
14723
|
+
const seen = new Set;
|
|
14724
|
+
let lastSeenId = null;
|
|
14725
|
+
const transport = this.transport;
|
|
14726
|
+
function deliver(msg) {
|
|
14727
|
+
if (seen.has(msg.id))
|
|
14728
|
+
return;
|
|
14729
|
+
seen.add(msg.id);
|
|
14730
|
+
if (seen.size > 200) {
|
|
14731
|
+
const first = seen.values().next().value;
|
|
14732
|
+
seen.delete(first);
|
|
14590
14733
|
}
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14734
|
+
lastSeenId = msg.id;
|
|
14735
|
+
if (options?.exclude && msg.sender === options.exclude)
|
|
14736
|
+
return;
|
|
14737
|
+
if (options?.senderType && msg.sender_type !== options.senderType)
|
|
14738
|
+
return;
|
|
14739
|
+
if (options?.onMessage) {
|
|
14740
|
+
options.onMessage(msg);
|
|
14741
|
+
} else {
|
|
14742
|
+
console.log(JSON.stringify(msg));
|
|
14595
14743
|
}
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14603
|
-
|
|
14604
|
-
|
|
14605
|
-
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
|
|
14610
|
-
ws.onopen = async () => {
|
|
14611
|
-
clearTimeout(connectTimeout);
|
|
14612
|
-
const wasReconnect = reconnectAttempt > 0;
|
|
14613
|
-
reconnectAttempt = 0;
|
|
14614
|
-
wsLog({ event: wasReconnect ? "reconnected" : "connected" });
|
|
14615
|
-
if (pingInterval)
|
|
14616
|
-
clearInterval(pingInterval);
|
|
14617
|
-
pingInterval = setInterval(() => {
|
|
14618
|
-
if (ws.readyState === WebSocket.OPEN) {
|
|
14619
|
-
ws.send(JSON.stringify({ type: "ping" }));
|
|
14620
|
-
}
|
|
14621
|
-
}, 30000);
|
|
14622
|
-
if (lastSeenId) {
|
|
14623
|
-
try {
|
|
14624
|
-
const missed = await fetchMessages(roomId, { after: lastSeenId });
|
|
14625
|
-
if (missed.length)
|
|
14626
|
-
wsLog({ event: "catchup", count: missed.length });
|
|
14627
|
-
for (const msg of missed)
|
|
14628
|
-
deliver(msg);
|
|
14629
|
-
} catch {}
|
|
14630
|
-
}
|
|
14631
|
-
};
|
|
14632
|
-
ws.onmessage = (event) => {
|
|
14633
|
-
const text = typeof event.data === "string" ? event.data : new TextDecoder().decode(event.data);
|
|
14634
|
-
const data = JSON.parse(text);
|
|
14635
|
-
if (data.type === "pong")
|
|
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;
|
|
14643
|
-
deliver(data);
|
|
14644
|
-
};
|
|
14645
|
-
ws.onclose = (event) => {
|
|
14646
|
-
clearTimeout(connectTimeout);
|
|
14647
|
-
if (pingInterval)
|
|
14648
|
-
clearInterval(pingInterval);
|
|
14649
|
-
const code = event.code;
|
|
14650
|
-
if (code === 1000) {
|
|
14651
|
-
wsLog({ event: "closed", code: 1000 });
|
|
14652
|
-
return;
|
|
14653
|
-
}
|
|
14654
|
-
const reason = code === 1006 ? "network drop" : code === 1012 ? "service restart" : code === 1013 ? "server back-off" : `code ${code}`;
|
|
14744
|
+
}
|
|
14745
|
+
function getReconnectDelay() {
|
|
14746
|
+
const delay = Math.min(1000 * 2 ** Math.min(reconnectAttempt, 4), 15000);
|
|
14747
|
+
reconnectAttempt++;
|
|
14748
|
+
return delay + delay * 0.5 * Math.random();
|
|
14749
|
+
}
|
|
14750
|
+
function connect() {
|
|
14751
|
+
const ws = new WebSocket(`${wsUrl}/api/rooms/${roomId}/ws`, wsHeaders);
|
|
14752
|
+
const connectTimeout = setTimeout(() => {
|
|
14753
|
+
if (ws.readyState !== WebSocket.OPEN) {
|
|
14754
|
+
wsLog({ event: "timeout", after_ms: 30000 });
|
|
14755
|
+
try {
|
|
14756
|
+
ws.close(4000, "connect timeout");
|
|
14757
|
+
} catch {}
|
|
14655
14758
|
const delay = getReconnectDelay();
|
|
14656
|
-
wsLog({ event: "disconnected", code, reason });
|
|
14657
14759
|
wsLog({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
|
|
14658
14760
|
setTimeout(connect, delay);
|
|
14659
|
-
};
|
|
14660
|
-
ws.onerror = () => {};
|
|
14661
|
-
return ws;
|
|
14662
|
-
}
|
|
14663
|
-
return connect();
|
|
14664
|
-
},
|
|
14665
|
-
async sendLog(roomId, sender, content, color, messageId) {
|
|
14666
|
-
return withRetry(async () => {
|
|
14667
|
-
const res = await fetch(`${baseUrl}/api/rooms/${roomId}/logs`, {
|
|
14668
|
-
method: "POST",
|
|
14669
|
-
headers: headers(),
|
|
14670
|
-
body: JSON.stringify({
|
|
14671
|
-
sender,
|
|
14672
|
-
content,
|
|
14673
|
-
...color && { color },
|
|
14674
|
-
...messageId && { message_id: messageId }
|
|
14675
|
-
})
|
|
14676
|
-
});
|
|
14677
|
-
if (!res.ok) {
|
|
14678
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14679
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14680
14761
|
}
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
|
|
14696
|
-
|
|
14697
|
-
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
method: "POST",
|
|
14703
|
-
headers: headers(),
|
|
14704
|
-
body: payload
|
|
14705
|
-
});
|
|
14706
|
-
if (!res.ok) {
|
|
14707
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14708
|
-
const msg = err2.error;
|
|
14709
|
-
throw new Error(typeof msg === "string" ? msg : msg ? JSON.stringify(msg) : `HTTP ${res.status}`);
|
|
14762
|
+
}, 30000);
|
|
14763
|
+
ws.onopen = async () => {
|
|
14764
|
+
clearTimeout(connectTimeout);
|
|
14765
|
+
const wasReconnect = reconnectAttempt > 0;
|
|
14766
|
+
reconnectAttempt = 0;
|
|
14767
|
+
wsLog({ event: wasReconnect ? "reconnected" : "connected" });
|
|
14768
|
+
if (pingInterval)
|
|
14769
|
+
clearInterval(pingInterval);
|
|
14770
|
+
pingInterval = setInterval(() => {
|
|
14771
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
14772
|
+
ws.send(JSON.stringify({ type: "ping" }));
|
|
14773
|
+
}
|
|
14774
|
+
}, 30000);
|
|
14775
|
+
if (lastSeenId) {
|
|
14776
|
+
try {
|
|
14777
|
+
const missed = await transport.getJson(`/api/rooms/${roomId}/messages`, { query: { after: lastSeenId } });
|
|
14778
|
+
if (missed.length)
|
|
14779
|
+
wsLog({ event: "catchup", count: missed.length });
|
|
14780
|
+
for (const msg of missed)
|
|
14781
|
+
deliver(msg);
|
|
14782
|
+
} catch {}
|
|
14710
14783
|
}
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
});
|
|
14721
|
-
if (!res.ok) {
|
|
14722
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14723
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14784
|
+
};
|
|
14785
|
+
ws.onmessage = (event) => {
|
|
14786
|
+
const text = typeof event.data === "string" ? event.data : new TextDecoder().decode(event.data);
|
|
14787
|
+
const data = JSON.parse(text);
|
|
14788
|
+
if (data.type === "pong")
|
|
14789
|
+
return;
|
|
14790
|
+
if (data.type === "terminal_subscribe" || data.type === "terminal_unsubscribe") {
|
|
14791
|
+
options?.onMessage?.(data);
|
|
14792
|
+
return;
|
|
14724
14793
|
}
|
|
14725
|
-
|
|
14726
|
-
});
|
|
14727
|
-
},
|
|
14728
|
-
async getMessageAttachments(roomId, messageId) {
|
|
14729
|
-
const res = await fetch(`${baseUrl}/api/rooms/${roomId}/messages/${messageId}/attachments`, {
|
|
14730
|
-
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined
|
|
14731
|
-
});
|
|
14732
|
-
if (!res.ok) {
|
|
14733
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14734
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14735
|
-
}
|
|
14736
|
-
return res.json();
|
|
14737
|
-
},
|
|
14738
|
-
async downloadAttachment(attachmentId) {
|
|
14739
|
-
cleanupOldAttachments();
|
|
14740
|
-
const res = await fetch(`${baseUrl}/api/attachments/${attachmentId}`, {
|
|
14741
|
-
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined
|
|
14742
|
-
});
|
|
14743
|
-
if (!res.ok) {
|
|
14744
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14745
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
14746
|
-
}
|
|
14747
|
-
const { mkdirSync, writeFileSync } = await import("node:fs");
|
|
14748
|
-
const dir = "/tmp/meet-ai-attachments";
|
|
14749
|
-
mkdirSync(dir, { recursive: true });
|
|
14750
|
-
const safeId = attachmentId.replace(/[^a-zA-Z0-9_-]/g, "") || "unknown";
|
|
14751
|
-
const localPath = `${dir}/${safeId}.bin`;
|
|
14752
|
-
const buffer = Buffer.from(await res.arrayBuffer());
|
|
14753
|
-
writeFileSync(localPath, buffer);
|
|
14754
|
-
return localPath;
|
|
14755
|
-
},
|
|
14756
|
-
listenLobby(options) {
|
|
14757
|
-
const wsUrl = baseUrl.replace(/^http/, "ws");
|
|
14758
|
-
const tokenParam = apiKey ? `?token=${apiKey}` : "";
|
|
14759
|
-
let pingInterval = null;
|
|
14760
|
-
let reconnectAttempt = 0;
|
|
14761
|
-
let reconnectScheduled = false;
|
|
14762
|
-
const log = options?.silent ? () => {} : wsLog;
|
|
14763
|
-
function getReconnectDelay() {
|
|
14764
|
-
const delay = Math.min(1000 * 2 ** Math.min(reconnectAttempt, 4), 15000);
|
|
14765
|
-
reconnectAttempt++;
|
|
14766
|
-
return delay + delay * 0.5 * Math.random();
|
|
14767
|
-
}
|
|
14768
|
-
function scheduleReconnect() {
|
|
14769
|
-
if (reconnectScheduled)
|
|
14794
|
+
if (data.type === "terminal_data")
|
|
14770
14795
|
return;
|
|
14771
|
-
|
|
14796
|
+
deliver(data);
|
|
14797
|
+
};
|
|
14798
|
+
ws.onclose = (event) => {
|
|
14799
|
+
clearTimeout(connectTimeout);
|
|
14800
|
+
if (pingInterval)
|
|
14801
|
+
clearInterval(pingInterval);
|
|
14802
|
+
const code = event.code;
|
|
14803
|
+
if (code === 1000) {
|
|
14804
|
+
wsLog({ event: "closed", code: 1000 });
|
|
14805
|
+
return;
|
|
14806
|
+
}
|
|
14807
|
+
const reason = code === 1006 ? "network drop" : code === 1012 ? "service restart" : code === 1013 ? "server back-off" : `code ${code}`;
|
|
14772
14808
|
const delay = getReconnectDelay();
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
|
|
14781
|
-
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
|
|
14794
|
-
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14798
|
-
|
|
14799
|
-
|
|
14800
|
-
|
|
14801
|
-
|
|
14802
|
-
|
|
14809
|
+
wsLog({ event: "disconnected", code, reason });
|
|
14810
|
+
wsLog({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
|
|
14811
|
+
setTimeout(connect, delay);
|
|
14812
|
+
};
|
|
14813
|
+
ws.onerror = () => {};
|
|
14814
|
+
return ws;
|
|
14815
|
+
}
|
|
14816
|
+
return connect();
|
|
14817
|
+
}
|
|
14818
|
+
listenLobby(options) {
|
|
14819
|
+
const wsUrl = this.baseUrl.replace(/^http/, "ws");
|
|
14820
|
+
const wsHeaders = this.apiKey ? { headers: { Authorization: `Bearer ${this.apiKey}` } } : undefined;
|
|
14821
|
+
let pingInterval = null;
|
|
14822
|
+
let reconnectAttempt = 0;
|
|
14823
|
+
let reconnectScheduled = false;
|
|
14824
|
+
const log = options?.silent ? () => {} : wsLog;
|
|
14825
|
+
function getReconnectDelay() {
|
|
14826
|
+
const delay = Math.min(1000 * 2 ** Math.min(reconnectAttempt, 4), 15000);
|
|
14827
|
+
reconnectAttempt++;
|
|
14828
|
+
return delay + delay * 0.5 * Math.random();
|
|
14829
|
+
}
|
|
14830
|
+
function scheduleReconnect() {
|
|
14831
|
+
if (reconnectScheduled)
|
|
14832
|
+
return;
|
|
14833
|
+
reconnectScheduled = true;
|
|
14834
|
+
const delay = getReconnectDelay();
|
|
14835
|
+
log({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
|
|
14836
|
+
setTimeout(() => {
|
|
14837
|
+
reconnectScheduled = false;
|
|
14838
|
+
connect();
|
|
14839
|
+
}, delay);
|
|
14840
|
+
}
|
|
14841
|
+
function connect() {
|
|
14842
|
+
const ws = new WebSocket(`${wsUrl}/api/lobby/ws`, wsHeaders);
|
|
14843
|
+
const connectTimeout = setTimeout(() => {
|
|
14844
|
+
if (ws.readyState !== WebSocket.OPEN) {
|
|
14803
14845
|
try {
|
|
14804
|
-
|
|
14805
|
-
if (data.type === "pong")
|
|
14806
|
-
return;
|
|
14807
|
-
if (data.type === "room_created" && data.id && data.name) {
|
|
14808
|
-
options?.onRoomCreated?.(data.id, data.name);
|
|
14809
|
-
}
|
|
14810
|
-
if (data.type === "spawn_request" && data.room_name) {
|
|
14811
|
-
options?.onSpawnRequest?.(data.room_name);
|
|
14812
|
-
}
|
|
14846
|
+
ws.close(4000, "connect timeout");
|
|
14813
14847
|
} catch {}
|
|
14814
|
-
};
|
|
14815
|
-
ws.onclose = (event) => {
|
|
14816
|
-
clearTimeout(connectTimeout);
|
|
14817
|
-
if (pingInterval)
|
|
14818
|
-
clearInterval(pingInterval);
|
|
14819
|
-
if (event.code === 1000)
|
|
14820
|
-
return;
|
|
14821
14848
|
scheduleReconnect();
|
|
14822
|
-
}
|
|
14823
|
-
|
|
14824
|
-
|
|
14849
|
+
}
|
|
14850
|
+
}, 30000);
|
|
14851
|
+
ws.onopen = () => {
|
|
14852
|
+
clearTimeout(connectTimeout);
|
|
14853
|
+
reconnectAttempt = 0;
|
|
14854
|
+
log({ event: "lobby_connected" });
|
|
14855
|
+
if (pingInterval)
|
|
14856
|
+
clearInterval(pingInterval);
|
|
14857
|
+
pingInterval = setInterval(() => {
|
|
14858
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
14859
|
+
ws.send(JSON.stringify({ type: "ping" }));
|
|
14860
|
+
}
|
|
14861
|
+
}, 30000);
|
|
14862
|
+
};
|
|
14863
|
+
ws.onmessage = (event) => {
|
|
14864
|
+
const text = typeof event.data === "string" ? event.data : new TextDecoder().decode(event.data);
|
|
14865
|
+
try {
|
|
14866
|
+
const data = JSON.parse(text);
|
|
14867
|
+
if (data.type === "pong")
|
|
14868
|
+
return;
|
|
14869
|
+
if (data.type === "room_created" && data.id && data.name) {
|
|
14870
|
+
options?.onRoomCreated?.(data.id, data.name);
|
|
14871
|
+
}
|
|
14872
|
+
if (data.type === "spawn_request" && data.room_name) {
|
|
14873
|
+
const codingAgent = typeof data.coding_agent === "string" && isCodingAgentId(data.coding_agent) ? data.coding_agent : "claude";
|
|
14874
|
+
options?.onSpawnRequest?.({ roomName: data.room_name, codingAgent });
|
|
14875
|
+
}
|
|
14876
|
+
} catch {}
|
|
14877
|
+
};
|
|
14878
|
+
ws.onclose = (event) => {
|
|
14879
|
+
clearTimeout(connectTimeout);
|
|
14880
|
+
if (pingInterval)
|
|
14881
|
+
clearInterval(pingInterval);
|
|
14882
|
+
if (event.code === 1000)
|
|
14883
|
+
return;
|
|
14884
|
+
scheduleReconnect();
|
|
14885
|
+
};
|
|
14886
|
+
ws.onerror = () => {};
|
|
14887
|
+
return ws;
|
|
14888
|
+
}
|
|
14889
|
+
return connect();
|
|
14890
|
+
}
|
|
14891
|
+
async generateKey() {
|
|
14892
|
+
return this.transport.postJson("/api/keys");
|
|
14893
|
+
}
|
|
14894
|
+
}
|
|
14895
|
+
var init_ConnectionAdapter = __esm(() => {
|
|
14896
|
+
init_coding_agents();
|
|
14897
|
+
});
|
|
14898
|
+
|
|
14899
|
+
// src/domain/adapters/FileSystemAdapter.ts
|
|
14900
|
+
import {
|
|
14901
|
+
readFileSync as readFileSync3,
|
|
14902
|
+
writeFileSync as writeFileSync2,
|
|
14903
|
+
mkdirSync as mkdirSync2,
|
|
14904
|
+
existsSync as existsSync3,
|
|
14905
|
+
statSync as statSync2
|
|
14906
|
+
} from "node:fs";
|
|
14907
|
+
|
|
14908
|
+
class FileSystemAdapter {
|
|
14909
|
+
readFileSync(path, encoding) {
|
|
14910
|
+
return readFileSync3(path, encoding);
|
|
14911
|
+
}
|
|
14912
|
+
writeFileSync(path, data, encoding) {
|
|
14913
|
+
writeFileSync2(path, data, encoding);
|
|
14914
|
+
}
|
|
14915
|
+
mkdirSync(path, opts) {
|
|
14916
|
+
mkdirSync2(path, opts);
|
|
14917
|
+
}
|
|
14918
|
+
existsSync(path) {
|
|
14919
|
+
return existsSync3(path);
|
|
14920
|
+
}
|
|
14921
|
+
statSync(path) {
|
|
14922
|
+
const stat = statSync2(path);
|
|
14923
|
+
return { mtimeMs: stat.mtimeMs, size: stat.size };
|
|
14924
|
+
}
|
|
14925
|
+
}
|
|
14926
|
+
var init_FileSystemAdapter = () => {};
|
|
14927
|
+
|
|
14928
|
+
// src/domain/repositories/MessageRepository.ts
|
|
14929
|
+
class MessageRepository {
|
|
14930
|
+
transport;
|
|
14931
|
+
constructor(transport) {
|
|
14932
|
+
this.transport = transport;
|
|
14933
|
+
}
|
|
14934
|
+
async send(roomId, sender, content, color) {
|
|
14935
|
+
return this.transport.postJson(`/api/rooms/${roomId}/messages`, { sender, content, sender_type: "agent", ...color && { color } }, RETRY);
|
|
14936
|
+
}
|
|
14937
|
+
async list(roomId, opts) {
|
|
14938
|
+
const query = {};
|
|
14939
|
+
if (opts?.after)
|
|
14940
|
+
query.after = opts.after;
|
|
14941
|
+
if (opts?.exclude)
|
|
14942
|
+
query.exclude = opts.exclude;
|
|
14943
|
+
if (opts?.senderType)
|
|
14944
|
+
query.sender_type = opts.senderType;
|
|
14945
|
+
return this.transport.getJson(`/api/rooms/${roomId}/messages`, { query });
|
|
14946
|
+
}
|
|
14947
|
+
async sendLog(roomId, sender, content, opts) {
|
|
14948
|
+
return this.transport.postJson(`/api/rooms/${roomId}/logs`, {
|
|
14949
|
+
sender,
|
|
14950
|
+
content,
|
|
14951
|
+
...opts?.color && { color: opts.color },
|
|
14952
|
+
...opts?.messageId && { message_id: opts.messageId }
|
|
14953
|
+
}, RETRY);
|
|
14954
|
+
}
|
|
14955
|
+
}
|
|
14956
|
+
var RETRY;
|
|
14957
|
+
var init_MessageRepository = __esm(() => {
|
|
14958
|
+
RETRY = { retry: { maxRetries: 3, baseDelay: 1000 } };
|
|
14959
|
+
});
|
|
14960
|
+
|
|
14961
|
+
// src/domain/repositories/RoomRepository.ts
|
|
14962
|
+
class RoomRepository {
|
|
14963
|
+
transport;
|
|
14964
|
+
constructor(transport) {
|
|
14965
|
+
this.transport = transport;
|
|
14966
|
+
}
|
|
14967
|
+
async create(name) {
|
|
14968
|
+
return this.transport.postJson("/api/rooms", { name });
|
|
14969
|
+
}
|
|
14970
|
+
async delete(roomId) {
|
|
14971
|
+
return this.transport.del(`/api/rooms/${roomId}`);
|
|
14972
|
+
}
|
|
14973
|
+
async sendTeamInfo(roomId, payload) {
|
|
14974
|
+
return this.transport.postText(`/api/rooms/${roomId}/team-info`, JSON.parse(payload), {
|
|
14975
|
+
retry: RETRY2
|
|
14976
|
+
});
|
|
14977
|
+
}
|
|
14978
|
+
async sendCommands(roomId, payload) {
|
|
14979
|
+
return this.transport.postText(`/api/rooms/${roomId}/commands`, JSON.parse(payload), {
|
|
14980
|
+
retry: RETRY2
|
|
14981
|
+
});
|
|
14982
|
+
}
|
|
14983
|
+
async sendTasks(roomId, payload) {
|
|
14984
|
+
return this.transport.postText(`/api/rooms/${roomId}/tasks`, JSON.parse(payload), {
|
|
14985
|
+
retry: RETRY2
|
|
14986
|
+
});
|
|
14987
|
+
}
|
|
14988
|
+
async sendTerminalData(roomId, data) {
|
|
14989
|
+
try {
|
|
14990
|
+
await this.transport.postJson(`/api/rooms/${roomId}/terminal`, { data });
|
|
14991
|
+
} catch {}
|
|
14992
|
+
}
|
|
14993
|
+
}
|
|
14994
|
+
var RETRY2;
|
|
14995
|
+
var init_RoomRepository = __esm(() => {
|
|
14996
|
+
RETRY2 = { maxRetries: 3, baseDelay: 1000 };
|
|
14997
|
+
});
|
|
14998
|
+
|
|
14999
|
+
// src/domain/repositories/AttachmentRepository.ts
|
|
15000
|
+
class AttachmentRepository {
|
|
15001
|
+
transport;
|
|
15002
|
+
constructor(transport) {
|
|
15003
|
+
this.transport = transport;
|
|
15004
|
+
}
|
|
15005
|
+
async listForMessage(roomId, messageId) {
|
|
15006
|
+
return this.transport.getJson(`/api/rooms/${roomId}/messages/${messageId}/attachments`);
|
|
15007
|
+
}
|
|
15008
|
+
async download(attachmentId) {
|
|
15009
|
+
return this.transport.getRaw(`/api/attachments/${attachmentId}`);
|
|
15010
|
+
}
|
|
15011
|
+
}
|
|
15012
|
+
|
|
15013
|
+
// src/domain/usecases/SendMessage.ts
|
|
15014
|
+
class SendMessage {
|
|
15015
|
+
messageRepository;
|
|
15016
|
+
constructor(messageRepository) {
|
|
15017
|
+
this.messageRepository = messageRepository;
|
|
15018
|
+
}
|
|
15019
|
+
async execute(roomId, sender, content, color) {
|
|
15020
|
+
return this.messageRepository.send(roomId, sender, content, color);
|
|
15021
|
+
}
|
|
15022
|
+
}
|
|
15023
|
+
|
|
15024
|
+
// src/domain/usecases/CreateRoom.ts
|
|
15025
|
+
class CreateRoom {
|
|
15026
|
+
roomRepository;
|
|
15027
|
+
constructor(roomRepository) {
|
|
15028
|
+
this.roomRepository = roomRepository;
|
|
15029
|
+
}
|
|
15030
|
+
async execute(name) {
|
|
15031
|
+
return this.roomRepository.create(name);
|
|
15032
|
+
}
|
|
15033
|
+
}
|
|
15034
|
+
|
|
15035
|
+
// src/domain/usecases/DeleteRoom.ts
|
|
15036
|
+
class DeleteRoom {
|
|
15037
|
+
roomRepository;
|
|
15038
|
+
constructor(roomRepository) {
|
|
15039
|
+
this.roomRepository = roomRepository;
|
|
15040
|
+
}
|
|
15041
|
+
async execute(roomId) {
|
|
15042
|
+
return this.roomRepository.delete(roomId);
|
|
15043
|
+
}
|
|
15044
|
+
}
|
|
15045
|
+
|
|
15046
|
+
// src/domain/usecases/SendLog.ts
|
|
15047
|
+
class SendLog {
|
|
15048
|
+
messageRepository;
|
|
15049
|
+
constructor(messageRepository) {
|
|
15050
|
+
this.messageRepository = messageRepository;
|
|
15051
|
+
}
|
|
15052
|
+
async execute(roomId, sender, content, opts) {
|
|
15053
|
+
return this.messageRepository.sendLog(roomId, sender, content, opts);
|
|
15054
|
+
}
|
|
15055
|
+
}
|
|
15056
|
+
|
|
15057
|
+
// src/domain/usecases/SendTeamInfo.ts
|
|
15058
|
+
class SendTeamInfo {
|
|
15059
|
+
roomRepository;
|
|
15060
|
+
constructor(roomRepository) {
|
|
15061
|
+
this.roomRepository = roomRepository;
|
|
15062
|
+
}
|
|
15063
|
+
async execute(roomId, payload) {
|
|
15064
|
+
return this.roomRepository.sendTeamInfo(roomId, payload);
|
|
15065
|
+
}
|
|
15066
|
+
}
|
|
15067
|
+
|
|
15068
|
+
// src/domain/usecases/SendCommands.ts
|
|
15069
|
+
class SendCommands {
|
|
15070
|
+
roomRepository;
|
|
15071
|
+
constructor(roomRepository) {
|
|
15072
|
+
this.roomRepository = roomRepository;
|
|
15073
|
+
}
|
|
15074
|
+
async execute(roomId, payload) {
|
|
15075
|
+
return this.roomRepository.sendCommands(roomId, payload);
|
|
15076
|
+
}
|
|
15077
|
+
}
|
|
15078
|
+
|
|
15079
|
+
// src/domain/usecases/SendTasks.ts
|
|
15080
|
+
class SendTasks {
|
|
15081
|
+
roomRepository;
|
|
15082
|
+
constructor(roomRepository) {
|
|
15083
|
+
this.roomRepository = roomRepository;
|
|
15084
|
+
}
|
|
15085
|
+
async execute(roomId, payload) {
|
|
15086
|
+
return this.roomRepository.sendTasks(roomId, payload);
|
|
15087
|
+
}
|
|
15088
|
+
}
|
|
15089
|
+
|
|
15090
|
+
// src/domain/usecases/SendTerminalData.ts
|
|
15091
|
+
class SendTerminalData {
|
|
15092
|
+
roomRepository;
|
|
15093
|
+
constructor(roomRepository) {
|
|
15094
|
+
this.roomRepository = roomRepository;
|
|
15095
|
+
}
|
|
15096
|
+
async execute(roomId, data) {
|
|
15097
|
+
return this.roomRepository.sendTerminalData(roomId, data);
|
|
15098
|
+
}
|
|
15099
|
+
}
|
|
15100
|
+
|
|
15101
|
+
// src/domain/services/InboxRouter.ts
|
|
15102
|
+
import { dirname as dirname2 } from "node:path";
|
|
15103
|
+
|
|
15104
|
+
class InboxRouter {
|
|
15105
|
+
fs;
|
|
15106
|
+
constructor(fs) {
|
|
15107
|
+
this.fs = fs;
|
|
15108
|
+
}
|
|
15109
|
+
route(msg, opts) {
|
|
15110
|
+
const entry = {
|
|
15111
|
+
from: `meet-ai:${msg.sender}`,
|
|
15112
|
+
text: msg.content,
|
|
15113
|
+
timestamp: new Date().toISOString(),
|
|
15114
|
+
read: false
|
|
15115
|
+
};
|
|
15116
|
+
if (opts.attachmentPaths?.length) {
|
|
15117
|
+
entry.attachments = opts.attachmentPaths;
|
|
15118
|
+
}
|
|
15119
|
+
const members = this.getTeamMembers(opts.teamDir);
|
|
15120
|
+
const targets = this.resolveInboxTargets(msg.content, members);
|
|
15121
|
+
if (targets) {
|
|
15122
|
+
for (const target of targets) {
|
|
15123
|
+
this.appendToInbox(`${opts.inboxDir}/${target}.json`, entry);
|
|
15124
|
+
}
|
|
15125
|
+
} else if (opts.defaultInboxPath) {
|
|
15126
|
+
this.appendToInbox(opts.defaultInboxPath, entry);
|
|
15127
|
+
}
|
|
15128
|
+
}
|
|
15129
|
+
checkIdle(opts) {
|
|
15130
|
+
const members = this.getTeamMembers(opts.teamDir);
|
|
15131
|
+
const newlyIdle = this.checkIdleAgents(opts.inboxDir, members, opts.inbox, opts.notified);
|
|
15132
|
+
for (const agent of newlyIdle) {
|
|
15133
|
+
opts.notified.add(agent);
|
|
15134
|
+
if (opts.defaultInboxPath) {
|
|
15135
|
+
this.appendToInbox(opts.defaultInboxPath, {
|
|
15136
|
+
from: "meet-ai:idle-check",
|
|
15137
|
+
text: `${agent} idle for 5+ minutes`,
|
|
15138
|
+
timestamp: new Date().toISOString(),
|
|
15139
|
+
read: false
|
|
15140
|
+
});
|
|
14825
15141
|
}
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14835
|
-
|
|
15142
|
+
}
|
|
15143
|
+
}
|
|
15144
|
+
appendToInbox(path, entry) {
|
|
15145
|
+
this.fs.mkdirSync(dirname2(path), { recursive: true });
|
|
15146
|
+
let messages = [];
|
|
15147
|
+
try {
|
|
15148
|
+
messages = JSON.parse(this.fs.readFileSync(path, "utf-8"));
|
|
15149
|
+
} catch {}
|
|
15150
|
+
messages.push(entry);
|
|
15151
|
+
this.fs.writeFileSync(path, JSON.stringify(messages, null, 2));
|
|
15152
|
+
}
|
|
15153
|
+
getTeamMembers(teamDir) {
|
|
15154
|
+
try {
|
|
15155
|
+
const config2 = JSON.parse(this.fs.readFileSync(`${teamDir}/config.json`, "utf-8"));
|
|
15156
|
+
return new Set(config2.members?.map((m) => m.name) || []);
|
|
15157
|
+
} catch {
|
|
15158
|
+
return new Set;
|
|
15159
|
+
}
|
|
15160
|
+
}
|
|
15161
|
+
resolveInboxTargets(content, members) {
|
|
15162
|
+
const mentions = content.match(/@([\w-]+)/g);
|
|
15163
|
+
if (!mentions)
|
|
15164
|
+
return null;
|
|
15165
|
+
const valid = [...new Set(mentions.map((m) => m.slice(1)))].filter((name) => members.has(name));
|
|
15166
|
+
return valid.length > 0 ? valid : null;
|
|
15167
|
+
}
|
|
15168
|
+
checkIdleAgents(inboxDir, members, excludeAgent, notified, now = Date.now()) {
|
|
15169
|
+
const newlyIdle = [];
|
|
15170
|
+
for (const member of members) {
|
|
15171
|
+
if (member === excludeAgent)
|
|
15172
|
+
continue;
|
|
15173
|
+
const inboxPath = `${inboxDir}/${member}.json`;
|
|
15174
|
+
let mtime;
|
|
15175
|
+
try {
|
|
15176
|
+
mtime = this.fs.statSync(inboxPath).mtimeMs;
|
|
15177
|
+
} catch {
|
|
15178
|
+
continue;
|
|
14836
15179
|
}
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
if (!res.ok) {
|
|
14845
|
-
const err2 = await res.json().catch(() => ({}));
|
|
14846
|
-
throw new Error(err2.error ?? `HTTP ${res.status}`);
|
|
15180
|
+
const idleMs = now - mtime;
|
|
15181
|
+
if (idleMs >= IDLE_THRESHOLD_MS) {
|
|
15182
|
+
if (!notified.has(member)) {
|
|
15183
|
+
newlyIdle.push(member);
|
|
15184
|
+
}
|
|
15185
|
+
} else {
|
|
15186
|
+
notified.delete(member);
|
|
14847
15187
|
}
|
|
14848
|
-
},
|
|
14849
|
-
async sendTerminalData(roomId, data) {
|
|
14850
|
-
try {
|
|
14851
|
-
await fetch(`${baseUrl}/api/rooms/${roomId}/terminal`, {
|
|
14852
|
-
method: "POST",
|
|
14853
|
-
headers: headers(),
|
|
14854
|
-
body: JSON.stringify({ data })
|
|
14855
|
-
});
|
|
14856
|
-
} catch {}
|
|
14857
15188
|
}
|
|
14858
|
-
|
|
15189
|
+
return newlyIdle;
|
|
15190
|
+
}
|
|
14859
15191
|
}
|
|
14860
|
-
var
|
|
14861
|
-
var
|
|
14862
|
-
|
|
15192
|
+
var IDLE_THRESHOLD_MS;
|
|
15193
|
+
var init_InboxRouter = __esm(() => {
|
|
15194
|
+
IDLE_THRESHOLD_MS = 5 * 60 * 1000;
|
|
14863
15195
|
});
|
|
14864
15196
|
|
|
14865
|
-
// src/
|
|
14866
|
-
|
|
14867
|
-
|
|
15197
|
+
// src/domain/usecases/Listen.ts
|
|
15198
|
+
class Listen {
|
|
15199
|
+
connectionAdapter;
|
|
15200
|
+
messageRepository;
|
|
15201
|
+
constructor(connectionAdapter, messageRepository) {
|
|
15202
|
+
this.connectionAdapter = connectionAdapter;
|
|
15203
|
+
this.messageRepository = messageRepository;
|
|
15204
|
+
}
|
|
15205
|
+
execute(roomId, opts) {
|
|
15206
|
+
return this.connectionAdapter.listen(roomId, opts);
|
|
15207
|
+
}
|
|
15208
|
+
}
|
|
15209
|
+
|
|
15210
|
+
// src/domain/usecases/ListenLobby.ts
|
|
15211
|
+
class ListenLobby {
|
|
15212
|
+
connectionAdapter;
|
|
15213
|
+
constructor(connectionAdapter) {
|
|
15214
|
+
this.connectionAdapter = connectionAdapter;
|
|
15215
|
+
}
|
|
15216
|
+
execute(opts) {
|
|
15217
|
+
return this.connectionAdapter.listenLobby(opts);
|
|
15218
|
+
}
|
|
15219
|
+
}
|
|
15220
|
+
|
|
15221
|
+
// src/domain/usecases/Poll.ts
|
|
15222
|
+
class Poll {
|
|
15223
|
+
messageRepository;
|
|
15224
|
+
constructor(messageRepository) {
|
|
15225
|
+
this.messageRepository = messageRepository;
|
|
15226
|
+
}
|
|
15227
|
+
async execute(roomId, opts) {
|
|
15228
|
+
return this.messageRepository.list(roomId, opts);
|
|
15229
|
+
}
|
|
15230
|
+
}
|
|
15231
|
+
|
|
15232
|
+
// src/domain/usecases/GenerateKey.ts
|
|
15233
|
+
class GenerateKey {
|
|
15234
|
+
connectionAdapter;
|
|
15235
|
+
constructor(connectionAdapter) {
|
|
15236
|
+
this.connectionAdapter = connectionAdapter;
|
|
15237
|
+
}
|
|
15238
|
+
async execute() {
|
|
15239
|
+
return this.connectionAdapter.generateKey();
|
|
15240
|
+
}
|
|
15241
|
+
}
|
|
15242
|
+
|
|
15243
|
+
// src/domain/usecases/GetAttachments.ts
|
|
15244
|
+
class GetAttachments {
|
|
15245
|
+
attachmentRepository;
|
|
15246
|
+
constructor(attachmentRepository) {
|
|
15247
|
+
this.attachmentRepository = attachmentRepository;
|
|
15248
|
+
}
|
|
15249
|
+
async execute(roomId, messageId) {
|
|
15250
|
+
return this.attachmentRepository.listForMessage(roomId, messageId);
|
|
15251
|
+
}
|
|
15252
|
+
}
|
|
15253
|
+
|
|
15254
|
+
// src/domain/usecases/DownloadAttachment.ts
|
|
15255
|
+
class DownloadAttachment {
|
|
15256
|
+
attachmentRepository;
|
|
15257
|
+
constructor(attachmentRepository) {
|
|
15258
|
+
this.attachmentRepository = attachmentRepository;
|
|
15259
|
+
}
|
|
15260
|
+
async execute(attachmentId) {
|
|
15261
|
+
return this.attachmentRepository.download(attachmentId);
|
|
15262
|
+
}
|
|
15263
|
+
}
|
|
15264
|
+
|
|
15265
|
+
// src/domain/bootstrap.ts
|
|
15266
|
+
var exports_bootstrap = {};
|
|
15267
|
+
__export(exports_bootstrap, {
|
|
15268
|
+
getContainer: () => getContainer,
|
|
14868
15269
|
getClient: () => getClient
|
|
14869
15270
|
});
|
|
15271
|
+
function cleanupOldAttachments() {
|
|
15272
|
+
try {
|
|
15273
|
+
const { readdirSync: readdirSync2, statSync: statSync3, unlinkSync } = __require("node:fs");
|
|
15274
|
+
const now = Date.now();
|
|
15275
|
+
for (const entry of readdirSync2(ATTACHMENTS_DIR)) {
|
|
15276
|
+
try {
|
|
15277
|
+
const filePath = `${ATTACHMENTS_DIR}/${entry}`;
|
|
15278
|
+
const mtime = statSync3(filePath).mtimeMs;
|
|
15279
|
+
if (now - mtime > MAX_AGE_MS) {
|
|
15280
|
+
unlinkSync(filePath);
|
|
15281
|
+
}
|
|
15282
|
+
} catch {}
|
|
15283
|
+
}
|
|
15284
|
+
} catch {}
|
|
15285
|
+
}
|
|
15286
|
+
function createContainer() {
|
|
15287
|
+
const config2 = getMeetAiConfig();
|
|
15288
|
+
const transport = new HttpTransport(config2.url, config2.key);
|
|
15289
|
+
const messageRepository = new MessageRepository(transport);
|
|
15290
|
+
const roomRepository = new RoomRepository(transport);
|
|
15291
|
+
const attachmentRepository = new AttachmentRepository(transport);
|
|
15292
|
+
const connectionAdapter = new ConnectionAdapter(transport, config2.url, config2.key);
|
|
15293
|
+
const fileSystem = new FileSystemAdapter;
|
|
15294
|
+
const inboxRouter = new InboxRouter(fileSystem);
|
|
15295
|
+
return {
|
|
15296
|
+
sendMessage: new SendMessage(messageRepository),
|
|
15297
|
+
createRoom: new CreateRoom(roomRepository),
|
|
15298
|
+
deleteRoom: new DeleteRoom(roomRepository),
|
|
15299
|
+
sendLog: new SendLog(messageRepository),
|
|
15300
|
+
sendTeamInfo: new SendTeamInfo(roomRepository),
|
|
15301
|
+
sendCommands: new SendCommands(roomRepository),
|
|
15302
|
+
sendTasks: new SendTasks(roomRepository),
|
|
15303
|
+
sendTerminalData: new SendTerminalData(roomRepository),
|
|
15304
|
+
listen: new Listen(connectionAdapter, messageRepository),
|
|
15305
|
+
listenLobby: new ListenLobby(connectionAdapter),
|
|
15306
|
+
poll: new Poll(messageRepository),
|
|
15307
|
+
generateKey: new GenerateKey(connectionAdapter),
|
|
15308
|
+
getAttachments: new GetAttachments(attachmentRepository),
|
|
15309
|
+
downloadAttachment: new DownloadAttachment(attachmentRepository),
|
|
15310
|
+
inboxRouter
|
|
15311
|
+
};
|
|
15312
|
+
}
|
|
15313
|
+
function getContainer() {
|
|
15314
|
+
if (!container) {
|
|
15315
|
+
container = createContainer();
|
|
15316
|
+
}
|
|
15317
|
+
return container;
|
|
15318
|
+
}
|
|
14870
15319
|
function getClient() {
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
14875
|
-
|
|
15320
|
+
const c = getContainer();
|
|
15321
|
+
return {
|
|
15322
|
+
createRoom: (name) => c.createRoom.execute(name),
|
|
15323
|
+
sendMessage: (roomId, sender, content, color) => c.sendMessage.execute(roomId, sender, content, color),
|
|
15324
|
+
getMessages: (roomId, options) => c.poll.execute(roomId, options),
|
|
15325
|
+
listen: (roomId, options) => c.listen.execute(roomId, options),
|
|
15326
|
+
sendLog: (roomId, sender, content, color, messageId) => c.sendLog.execute(roomId, sender, content, { color, messageId }),
|
|
15327
|
+
sendTeamInfo: (roomId, payload) => c.sendTeamInfo.execute(roomId, payload),
|
|
15328
|
+
sendCommands: (roomId, payload) => c.sendCommands.execute(roomId, payload),
|
|
15329
|
+
sendTasks: (roomId, payload) => c.sendTasks.execute(roomId, payload),
|
|
15330
|
+
getMessageAttachments: (roomId, messageId) => c.getAttachments.execute(roomId, messageId),
|
|
15331
|
+
downloadAttachment: async (attachmentId) => {
|
|
15332
|
+
cleanupOldAttachments();
|
|
15333
|
+
const response = await c.downloadAttachment.execute(attachmentId);
|
|
15334
|
+
const { mkdirSync: mkdirSync3, writeFileSync: writeFileSync3 } = await import("node:fs");
|
|
15335
|
+
mkdirSync3(ATTACHMENTS_DIR, { recursive: true });
|
|
15336
|
+
const safeId = attachmentId.replace(/[^a-zA-Z0-9_-]/g, "") || "unknown";
|
|
15337
|
+
const localPath = `${ATTACHMENTS_DIR}/${safeId}.bin`;
|
|
15338
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
15339
|
+
writeFileSync3(localPath, buffer);
|
|
15340
|
+
return localPath;
|
|
15341
|
+
},
|
|
15342
|
+
listenLobby: (options) => c.listenLobby.execute(options),
|
|
15343
|
+
generateKey: () => c.generateKey.execute(),
|
|
15344
|
+
deleteRoom: (roomId) => c.deleteRoom.execute(roomId),
|
|
15345
|
+
sendTerminalData: (roomId, data) => c.sendTerminalData.execute(roomId, data)
|
|
15346
|
+
};
|
|
14876
15347
|
}
|
|
14877
|
-
var
|
|
14878
|
-
var
|
|
15348
|
+
var ATTACHMENTS_DIR = "/tmp/meet-ai-attachments", MAX_AGE_MS, container = null;
|
|
15349
|
+
var init_bootstrap = __esm(() => {
|
|
14879
15350
|
init_config();
|
|
14880
|
-
|
|
15351
|
+
init_ConnectionAdapter();
|
|
15352
|
+
init_FileSystemAdapter();
|
|
15353
|
+
init_MessageRepository();
|
|
15354
|
+
init_RoomRepository();
|
|
15355
|
+
init_InboxRouter();
|
|
15356
|
+
MAX_AGE_MS = 5 * 60 * 1000;
|
|
14881
15357
|
});
|
|
14882
15358
|
|
|
14883
15359
|
// src/commands/create-room/schema.ts
|
|
@@ -14909,7 +15385,7 @@ __export(exports_command, {
|
|
|
14909
15385
|
var command_default;
|
|
14910
15386
|
var init_command = __esm(() => {
|
|
14911
15387
|
init_dist();
|
|
14912
|
-
|
|
15388
|
+
init_bootstrap();
|
|
14913
15389
|
init_usecase();
|
|
14914
15390
|
init_output();
|
|
14915
15391
|
command_default = defineCommand({
|
|
@@ -14964,7 +15440,7 @@ __export(exports_command2, {
|
|
|
14964
15440
|
var command_default2;
|
|
14965
15441
|
var init_command2 = __esm(() => {
|
|
14966
15442
|
init_dist();
|
|
14967
|
-
|
|
15443
|
+
init_bootstrap();
|
|
14968
15444
|
init_usecase2();
|
|
14969
15445
|
init_output();
|
|
14970
15446
|
command_default2 = defineCommand({
|
|
@@ -15040,7 +15516,7 @@ __export(exports_command3, {
|
|
|
15040
15516
|
var command_default3;
|
|
15041
15517
|
var init_command3 = __esm(() => {
|
|
15042
15518
|
init_dist();
|
|
15043
|
-
|
|
15519
|
+
init_bootstrap();
|
|
15044
15520
|
init_usecase3();
|
|
15045
15521
|
init_output();
|
|
15046
15522
|
command_default3 = defineCommand({
|
|
@@ -15123,7 +15599,7 @@ __export(exports_command4, {
|
|
|
15123
15599
|
var command_default4;
|
|
15124
15600
|
var init_command4 = __esm(() => {
|
|
15125
15601
|
init_dist();
|
|
15126
|
-
|
|
15602
|
+
init_bootstrap();
|
|
15127
15603
|
init_usecase4();
|
|
15128
15604
|
init_output();
|
|
15129
15605
|
command_default4 = defineCommand({
|
|
@@ -15241,7 +15717,7 @@ __export(exports_command5, {
|
|
|
15241
15717
|
var command_default5;
|
|
15242
15718
|
var init_command5 = __esm(() => {
|
|
15243
15719
|
init_dist();
|
|
15244
|
-
|
|
15720
|
+
init_bootstrap();
|
|
15245
15721
|
init_usecase5();
|
|
15246
15722
|
init_output();
|
|
15247
15723
|
command_default5 = defineCommand({
|
|
@@ -15288,78 +15764,28 @@ var init_command5 = __esm(() => {
|
|
|
15288
15764
|
});
|
|
15289
15765
|
});
|
|
15290
15766
|
|
|
15767
|
+
// src/inbox-router.ts
|
|
15768
|
+
var IDLE_CHECK_INTERVAL_MS = 60000, IDLE_THRESHOLD_MS2;
|
|
15769
|
+
var init_inbox_router = __esm(() => {
|
|
15770
|
+
IDLE_THRESHOLD_MS2 = 5 * 60 * 1000;
|
|
15771
|
+
});
|
|
15772
|
+
|
|
15291
15773
|
// src/commands/listen/schema.ts
|
|
15292
15774
|
var ListenInput;
|
|
15293
15775
|
var init_schema6 = __esm(() => {
|
|
15294
15776
|
init_zod();
|
|
15295
15777
|
ListenInput = exports_external.object({
|
|
15296
|
-
roomId: exports_external.
|
|
15778
|
+
roomId: exports_external.uuid({ error: "Room ID must be a valid uuid" }),
|
|
15297
15779
|
exclude: exports_external.string().optional(),
|
|
15298
15780
|
senderType: exports_external.string().optional(),
|
|
15299
15781
|
team: exports_external.string().optional(),
|
|
15300
|
-
inbox: exports_external.string().optional()
|
|
15301
|
-
stdinPane: exports_external.string().optional()
|
|
15782
|
+
inbox: exports_external.string().optional()
|
|
15302
15783
|
}).refine((data) => !(data.inbox && !data.team), {
|
|
15303
15784
|
message: "--inbox requires --team",
|
|
15304
15785
|
path: ["inbox"]
|
|
15305
15786
|
});
|
|
15306
15787
|
});
|
|
15307
15788
|
|
|
15308
|
-
// src/inbox-router.ts
|
|
15309
|
-
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, statSync } from "node:fs";
|
|
15310
|
-
import { dirname } from "node:path";
|
|
15311
|
-
function appendToInbox(path, entry) {
|
|
15312
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
15313
|
-
let messages = [];
|
|
15314
|
-
try {
|
|
15315
|
-
messages = JSON.parse(readFileSync2(path, "utf-8"));
|
|
15316
|
-
} catch {}
|
|
15317
|
-
messages.push(entry);
|
|
15318
|
-
writeFileSync(path, JSON.stringify(messages, null, 2));
|
|
15319
|
-
}
|
|
15320
|
-
function getTeamMembers(teamDir) {
|
|
15321
|
-
try {
|
|
15322
|
-
const config2 = JSON.parse(readFileSync2(`${teamDir}/config.json`, "utf-8"));
|
|
15323
|
-
return new Set(config2.members?.map((m) => m.name) || []);
|
|
15324
|
-
} catch {
|
|
15325
|
-
return new Set;
|
|
15326
|
-
}
|
|
15327
|
-
}
|
|
15328
|
-
function resolveInboxTargets(content, members) {
|
|
15329
|
-
const mentions = content.match(/@([\w-]+)/g);
|
|
15330
|
-
if (!mentions)
|
|
15331
|
-
return null;
|
|
15332
|
-
const valid = [...new Set(mentions.map((m) => m.slice(1)))].filter((name) => members.has(name));
|
|
15333
|
-
return valid.length > 0 ? valid : null;
|
|
15334
|
-
}
|
|
15335
|
-
function checkIdleAgents(inboxDir, members, excludeAgent, notified, now = Date.now()) {
|
|
15336
|
-
const newlyIdle = [];
|
|
15337
|
-
for (const member of members) {
|
|
15338
|
-
if (member === excludeAgent)
|
|
15339
|
-
continue;
|
|
15340
|
-
const inboxPath = `${inboxDir}/${member}.json`;
|
|
15341
|
-
let mtime;
|
|
15342
|
-
try {
|
|
15343
|
-
mtime = statSync(inboxPath).mtimeMs;
|
|
15344
|
-
} catch {
|
|
15345
|
-
continue;
|
|
15346
|
-
}
|
|
15347
|
-
const idleMs = now - mtime;
|
|
15348
|
-
if (idleMs >= IDLE_THRESHOLD_MS) {
|
|
15349
|
-
if (!notified.has(member)) {
|
|
15350
|
-
newlyIdle.push(member);
|
|
15351
|
-
}
|
|
15352
|
-
} else {
|
|
15353
|
-
notified.delete(member);
|
|
15354
|
-
}
|
|
15355
|
-
}
|
|
15356
|
-
return newlyIdle;
|
|
15357
|
-
}
|
|
15358
|
-
var IDLE_CHECK_INTERVAL_MS = 60000, IDLE_THRESHOLD_MS;
|
|
15359
|
-
var init_inbox_router = __esm(() => {
|
|
15360
|
-
IDLE_THRESHOLD_MS = 5 * 60 * 1000;
|
|
15361
|
-
});
|
|
15362
|
-
|
|
15363
15789
|
// src/lib/tmux-client.ts
|
|
15364
15790
|
import { execFileSync, execFile as execFileCb } from "node:child_process";
|
|
15365
15791
|
function validateSessionName(name) {
|
|
@@ -15367,10 +15793,10 @@ function validateSessionName(name) {
|
|
|
15367
15793
|
throw new Error(`Invalid tmux session name: ${name}`);
|
|
15368
15794
|
}
|
|
15369
15795
|
}
|
|
15370
|
-
function parseVersion(
|
|
15371
|
-
if (!
|
|
15796
|
+
function parseVersion(version3) {
|
|
15797
|
+
if (!version3)
|
|
15372
15798
|
return [0, 0];
|
|
15373
|
-
const match =
|
|
15799
|
+
const match = version3.match(/(\d+)\.(\d+)/);
|
|
15374
15800
|
if (!match)
|
|
15375
15801
|
return [0, 0];
|
|
15376
15802
|
return [Number(match[1]), Number(match[2])];
|
|
@@ -15390,6 +15816,9 @@ class TmuxClient {
|
|
|
15390
15816
|
timeout: 5000,
|
|
15391
15817
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15392
15818
|
}).trim();
|
|
15819
|
+
if (!result) {
|
|
15820
|
+
return { available: false, version: null, error: "tmux returned an empty version string" };
|
|
15821
|
+
}
|
|
15393
15822
|
return { available: true, version: result };
|
|
15394
15823
|
} catch (error48) {
|
|
15395
15824
|
return {
|
|
@@ -15401,11 +15830,7 @@ class TmuxClient {
|
|
|
15401
15830
|
}
|
|
15402
15831
|
newSession(name, commandArgs, env) {
|
|
15403
15832
|
validateSessionName(name);
|
|
15404
|
-
|
|
15405
|
-
for (const [key, value] of Object.entries(env)) {
|
|
15406
|
-
this.exec(["-L", this.server, "set-environment", "-g", key, value]);
|
|
15407
|
-
}
|
|
15408
|
-
}
|
|
15833
|
+
const envArgs = env ? ["env", ...Object.entries(env).map(([key, value]) => `${key}=${value}`)] : [];
|
|
15409
15834
|
const args = [
|
|
15410
15835
|
"-L",
|
|
15411
15836
|
this.server,
|
|
@@ -15418,14 +15843,10 @@ class TmuxClient {
|
|
|
15418
15843
|
"-y",
|
|
15419
15844
|
"40",
|
|
15420
15845
|
"--",
|
|
15846
|
+
...envArgs,
|
|
15421
15847
|
...commandArgs
|
|
15422
15848
|
];
|
|
15423
15849
|
const result = this.exec(args);
|
|
15424
|
-
if (env) {
|
|
15425
|
-
for (const key of Object.keys(env)) {
|
|
15426
|
-
this.exec(["-L", this.server, "set-environment", "-g", "-u", key]);
|
|
15427
|
-
}
|
|
15428
|
-
}
|
|
15429
15850
|
if (!result.ok)
|
|
15430
15851
|
return result;
|
|
15431
15852
|
this.exec(["-L", this.server, "set-option", "-t", name, "remain-on-exit", "on"]);
|
|
@@ -15465,13 +15886,13 @@ class TmuxClient {
|
|
|
15465
15886
|
"-F",
|
|
15466
15887
|
"#{pane_id}\t#{session_name}\t#{pane_title}\t#{pane_current_command}"
|
|
15467
15888
|
];
|
|
15468
|
-
return new Promise((
|
|
15889
|
+
return new Promise((resolve3) => {
|
|
15469
15890
|
execFileCb("tmux", args, { encoding: "utf8", timeout: 5000 }, (error48, stdout) => {
|
|
15470
15891
|
if (error48) {
|
|
15471
|
-
|
|
15892
|
+
resolve3([]);
|
|
15472
15893
|
return;
|
|
15473
15894
|
}
|
|
15474
|
-
|
|
15895
|
+
resolve3(stdout.trim().split(`
|
|
15475
15896
|
`).filter((line) => line.trim()).map((line) => {
|
|
15476
15897
|
const [paneId, sessionName, title, command] = line.split("\t");
|
|
15477
15898
|
return { paneId: paneId ?? "", sessionName: sessionName ?? "", title: title ?? "", command: command ?? "" };
|
|
@@ -15524,10 +15945,10 @@ class TmuxClient {
|
|
|
15524
15945
|
if (lines > 0) {
|
|
15525
15946
|
args.push("-S", `-${lines}`);
|
|
15526
15947
|
}
|
|
15527
|
-
return new Promise((
|
|
15948
|
+
return new Promise((resolve3) => {
|
|
15528
15949
|
execFileCb("tmux", args, { encoding: "utf8", timeout: 5000 }, (error48, stdout) => {
|
|
15529
15950
|
if (error48) {
|
|
15530
|
-
|
|
15951
|
+
resolve3([]);
|
|
15531
15952
|
return;
|
|
15532
15953
|
}
|
|
15533
15954
|
const result = stdout.split(`
|
|
@@ -15535,7 +15956,7 @@ class TmuxClient {
|
|
|
15535
15956
|
while (result.length > 0 && result[result.length - 1] === "") {
|
|
15536
15957
|
result.pop();
|
|
15537
15958
|
}
|
|
15538
|
-
|
|
15959
|
+
resolve3(result);
|
|
15539
15960
|
});
|
|
15540
15961
|
});
|
|
15541
15962
|
}
|
|
@@ -15579,36 +16000,12 @@ var init_tmux_client = __esm(() => {
|
|
|
15579
16000
|
SESSION_NAME_RE = /^[a-zA-Z0-9_-]+$/;
|
|
15580
16001
|
});
|
|
15581
16002
|
|
|
15582
|
-
// src/commands/listen/
|
|
15583
|
-
function
|
|
15584
|
-
const
|
|
15585
|
-
from: `meet-ai:${msg.sender}`,
|
|
15586
|
-
text: msg.content,
|
|
15587
|
-
timestamp: new Date().toISOString(),
|
|
15588
|
-
read: false
|
|
15589
|
-
};
|
|
15590
|
-
if (attachmentPaths?.length) {
|
|
15591
|
-
entry.attachments = attachmentPaths;
|
|
15592
|
-
}
|
|
15593
|
-
const members = getTeamMembers(teamDir);
|
|
15594
|
-
const targets = resolveInboxTargets(msg.content, members);
|
|
15595
|
-
if (targets) {
|
|
15596
|
-
for (const target of targets) {
|
|
15597
|
-
appendToInbox(`${inboxDir}/${target}.json`, entry);
|
|
15598
|
-
}
|
|
15599
|
-
} else if (stdinPane) {} else if (defaultInboxPath) {
|
|
15600
|
-
appendToInbox(defaultInboxPath, entry);
|
|
15601
|
-
}
|
|
15602
|
-
}
|
|
15603
|
-
function listen(client, input) {
|
|
15604
|
-
const parsed = ListenInput.parse(input);
|
|
15605
|
-
const { roomId, exclude, senderType, team, inbox, stdinPane } = parsed;
|
|
15606
|
-
const inboxDir = team ? `${process.env.HOME}/.claude/teams/${team}/inboxes` : null;
|
|
15607
|
-
const defaultInboxPath = inboxDir && inbox ? `${inboxDir}/${inbox}.json` : null;
|
|
15608
|
-
const teamDir = team ? `${process.env.HOME}/.claude/teams/${team}` : null;
|
|
16003
|
+
// src/commands/listen/shared.ts
|
|
16004
|
+
function createTerminalControlHandler(input) {
|
|
16005
|
+
const { client, roomId, teamDir } = input;
|
|
15609
16006
|
const tmuxClient = new TmuxClient({ server: "meet-ai", scrollback: 50000 });
|
|
15610
16007
|
let terminalInterval = null;
|
|
15611
|
-
|
|
16008
|
+
function handle(msg) {
|
|
15612
16009
|
if (msg.type === "terminal_resize") {
|
|
15613
16010
|
const cols = msg.cols;
|
|
15614
16011
|
if (typeof cols === "number" && cols > 0) {
|
|
@@ -15620,7 +16017,7 @@ function listen(client, input) {
|
|
|
15620
16017
|
}
|
|
15621
16018
|
});
|
|
15622
16019
|
}
|
|
15623
|
-
return;
|
|
16020
|
+
return true;
|
|
15624
16021
|
}
|
|
15625
16022
|
if (msg.type === "terminal_subscribe") {
|
|
15626
16023
|
const roomPrefix = roomId.slice(0, 8);
|
|
@@ -15673,50 +16070,76 @@ function listen(client, input) {
|
|
|
15673
16070
|
await client.sendTerminalData(roomId, payload);
|
|
15674
16071
|
} catch {}
|
|
15675
16072
|
}, TERMINAL_POLL_MS);
|
|
15676
|
-
return;
|
|
16073
|
+
return true;
|
|
15677
16074
|
}
|
|
15678
16075
|
if (msg.type === "terminal_unsubscribe") {
|
|
15679
16076
|
if (terminalInterval) {
|
|
15680
16077
|
clearInterval(terminalInterval);
|
|
15681
16078
|
terminalInterval = null;
|
|
15682
16079
|
}
|
|
15683
|
-
return;
|
|
16080
|
+
return true;
|
|
15684
16081
|
}
|
|
15685
16082
|
if (msg.type === "terminal_data") {
|
|
15686
|
-
return;
|
|
16083
|
+
return true;
|
|
16084
|
+
}
|
|
16085
|
+
return false;
|
|
16086
|
+
}
|
|
16087
|
+
function shutdown() {
|
|
16088
|
+
if (terminalInterval) {
|
|
16089
|
+
clearInterval(terminalInterval);
|
|
16090
|
+
terminalInterval = null;
|
|
15687
16091
|
}
|
|
15688
|
-
|
|
16092
|
+
}
|
|
16093
|
+
return { handle, shutdown };
|
|
16094
|
+
}
|
|
16095
|
+
var init_shared = __esm(() => {
|
|
16096
|
+
init_tmux_client();
|
|
16097
|
+
});
|
|
16098
|
+
|
|
16099
|
+
// src/commands/listen/listen-claude.ts
|
|
16100
|
+
function listenClaude(client, input, inboxRouter) {
|
|
16101
|
+
const parsed = ListenInput.parse(input);
|
|
16102
|
+
const { roomId, exclude, senderType, team, inbox } = parsed;
|
|
16103
|
+
const inboxDir = team ? `${process.env.HOME}/.claude/teams/${team}/inboxes` : null;
|
|
16104
|
+
const defaultInboxPath = inboxDir && inbox ? `${inboxDir}/${inbox}.json` : null;
|
|
16105
|
+
const teamDir = team ? `${process.env.HOME}/.claude/teams/${team}` : undefined;
|
|
16106
|
+
const terminal = createTerminalControlHandler({ client, roomId, teamDir, inboxRouter });
|
|
16107
|
+
const onMessage = (msg) => {
|
|
16108
|
+
if (terminal.handle(msg))
|
|
16109
|
+
return;
|
|
16110
|
+
if (msg.id && msg.room_id && (msg.attachment_count ?? 0) > 0) {
|
|
15689
16111
|
downloadMessageAttachments(client, msg.room_id, msg.id).then((paths) => {
|
|
15690
16112
|
const output = paths.length ? { ...msg, attachments: paths } : msg;
|
|
15691
16113
|
console.log(JSON.stringify(output));
|
|
15692
|
-
if (inboxDir && teamDir)
|
|
15693
|
-
|
|
16114
|
+
if (inboxDir && teamDir && inboxRouter) {
|
|
16115
|
+
inboxRouter.route(msg, {
|
|
16116
|
+
inboxDir,
|
|
16117
|
+
defaultInboxPath,
|
|
16118
|
+
teamDir,
|
|
16119
|
+
attachmentPaths: paths
|
|
16120
|
+
});
|
|
16121
|
+
}
|
|
15694
16122
|
});
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
16123
|
+
return;
|
|
16124
|
+
}
|
|
16125
|
+
console.log(JSON.stringify(msg));
|
|
16126
|
+
if (inboxDir && teamDir && inboxRouter) {
|
|
16127
|
+
inboxRouter.route(msg, { inboxDir, defaultInboxPath, teamDir });
|
|
15699
16128
|
}
|
|
15700
16129
|
};
|
|
15701
16130
|
const ws = client.listen(roomId, { exclude, senderType, onMessage });
|
|
15702
16131
|
let idleCheckTimeout = null;
|
|
15703
16132
|
const idleNotified = new Set;
|
|
15704
|
-
if (inboxDir && inbox && teamDir) {
|
|
16133
|
+
if (inboxDir && inbox && teamDir && inboxRouter) {
|
|
15705
16134
|
let scheduleIdleCheck = function() {
|
|
15706
16135
|
idleCheckTimeout = setTimeout(() => {
|
|
15707
|
-
|
|
15708
|
-
|
|
15709
|
-
|
|
15710
|
-
|
|
15711
|
-
|
|
15712
|
-
|
|
15713
|
-
|
|
15714
|
-
text: `${agent} idle for 5+ minutes`,
|
|
15715
|
-
timestamp: new Date().toISOString(),
|
|
15716
|
-
read: false
|
|
15717
|
-
});
|
|
15718
|
-
}
|
|
15719
|
-
}
|
|
16136
|
+
inboxRouter.checkIdle({
|
|
16137
|
+
inboxDir,
|
|
16138
|
+
teamDir,
|
|
16139
|
+
inbox,
|
|
16140
|
+
defaultInboxPath: defaultInboxPath ?? null,
|
|
16141
|
+
notified: idleNotified
|
|
16142
|
+
});
|
|
15720
16143
|
scheduleIdleCheck();
|
|
15721
16144
|
}, IDLE_CHECK_INTERVAL_MS);
|
|
15722
16145
|
};
|
|
@@ -15725,10 +16148,621 @@ function listen(client, input) {
|
|
|
15725
16148
|
function shutdown() {
|
|
15726
16149
|
if (idleCheckTimeout)
|
|
15727
16150
|
clearTimeout(idleCheckTimeout);
|
|
15728
|
-
|
|
15729
|
-
|
|
15730
|
-
|
|
16151
|
+
terminal.shutdown();
|
|
16152
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
16153
|
+
ws.close(1000, "client shutdown");
|
|
16154
|
+
}
|
|
16155
|
+
process.exit(0);
|
|
16156
|
+
}
|
|
16157
|
+
process.on("SIGINT", shutdown);
|
|
16158
|
+
process.on("SIGTERM", shutdown);
|
|
16159
|
+
process.on("SIGHUP", shutdown);
|
|
16160
|
+
return ws;
|
|
16161
|
+
}
|
|
16162
|
+
var init_listen_claude = __esm(() => {
|
|
16163
|
+
init_inbox_router();
|
|
16164
|
+
init_schema6();
|
|
16165
|
+
init_shared();
|
|
16166
|
+
});
|
|
16167
|
+
|
|
16168
|
+
// src/lib/codex-app-server.ts
|
|
16169
|
+
import {
|
|
16170
|
+
spawn
|
|
16171
|
+
} from "node:child_process";
|
|
16172
|
+
import { stderr } from "node:process";
|
|
16173
|
+
import { createInterface } from "node:readline";
|
|
16174
|
+
function isObject2(value) {
|
|
16175
|
+
return typeof value === "object" && value !== null;
|
|
16176
|
+
}
|
|
16177
|
+
function isJsonRpcResponse(value) {
|
|
16178
|
+
return isObject2(value) && "id" in value && (("result" in value) || ("error" in value));
|
|
16179
|
+
}
|
|
16180
|
+
function isJsonRpcServerRequest(value) {
|
|
16181
|
+
return isObject2(value) && typeof value.method === "string" && "id" in value && !("result" in value) && !("error" in value);
|
|
16182
|
+
}
|
|
16183
|
+
function isJsonRpcNotification(value) {
|
|
16184
|
+
return isObject2(value) && typeof value.method === "string" && !("id" in value);
|
|
16185
|
+
}
|
|
16186
|
+
function toErrorMessage(error48) {
|
|
16187
|
+
if (error48 instanceof Error)
|
|
16188
|
+
return error48.message;
|
|
16189
|
+
return String(error48);
|
|
16190
|
+
}
|
|
16191
|
+
function formatRoomMessageForCodex(input) {
|
|
16192
|
+
const lines = [
|
|
16193
|
+
`New message from meet-ai sender "${input.sender}" at ${input.timestamp ?? new Date().toISOString()}:`,
|
|
16194
|
+
"",
|
|
16195
|
+
input.content
|
|
16196
|
+
];
|
|
16197
|
+
if (input.attachments?.length) {
|
|
16198
|
+
lines.push("", `Attachments: ${input.attachments.join(", ")}`);
|
|
16199
|
+
}
|
|
16200
|
+
return lines.join(`
|
|
16201
|
+
`);
|
|
16202
|
+
}
|
|
16203
|
+
function maybeActiveTurnId(thread) {
|
|
16204
|
+
if (!thread || !Array.isArray(thread.turns))
|
|
16205
|
+
return null;
|
|
16206
|
+
for (let index = thread.turns.length - 1;index >= 0; index -= 1) {
|
|
16207
|
+
const turn = thread.turns[index];
|
|
16208
|
+
if (turn?.status === "inProgress" && typeof turn.id === "string") {
|
|
16209
|
+
return turn.id;
|
|
16210
|
+
}
|
|
16211
|
+
}
|
|
16212
|
+
return null;
|
|
16213
|
+
}
|
|
16214
|
+
function isSteerPreconditionError(error48) {
|
|
16215
|
+
if (!isObject2(error48))
|
|
16216
|
+
return false;
|
|
16217
|
+
const message = typeof error48.message === "string" ? error48.message.toLowerCase() : "";
|
|
16218
|
+
return message.includes("expected") || message.includes("active turn") || message.includes("precondition");
|
|
16219
|
+
}
|
|
16220
|
+
function isAgentMessageDeltaNotification(params) {
|
|
16221
|
+
return isObject2(params) && typeof params.threadId === "string" && typeof params.turnId === "string" && typeof params.itemId === "string" && typeof params.delta === "string";
|
|
16222
|
+
}
|
|
16223
|
+
function extractAgentMessageDelta(params) {
|
|
16224
|
+
if (!isAgentMessageDeltaNotification(params)) {
|
|
16225
|
+
return { itemId: null, turnId: null, text: null };
|
|
16226
|
+
}
|
|
16227
|
+
return {
|
|
16228
|
+
itemId: params.itemId,
|
|
16229
|
+
turnId: params.turnId,
|
|
16230
|
+
text: params.delta
|
|
16231
|
+
};
|
|
16232
|
+
}
|
|
16233
|
+
function isItemCompletedNotification(params) {
|
|
16234
|
+
return isObject2(params) && typeof params.threadId === "string" && typeof params.turnId === "string" && isObject2(params.item) && typeof params.item.type === "string" && typeof params.item.id === "string";
|
|
16235
|
+
}
|
|
16236
|
+
function extractCompletedAgentMessage(params) {
|
|
16237
|
+
if (!isItemCompletedNotification(params))
|
|
16238
|
+
return null;
|
|
16239
|
+
if (params.item.type !== "agentMessage")
|
|
16240
|
+
return null;
|
|
16241
|
+
return {
|
|
16242
|
+
itemId: params.item.id,
|
|
16243
|
+
turnId: params.turnId,
|
|
16244
|
+
text: params.item.text
|
|
16245
|
+
};
|
|
16246
|
+
}
|
|
16247
|
+
function isThreadStartedNotification(params) {
|
|
16248
|
+
return isObject2(params) && isObject2(params.thread) && typeof params.thread.id === "string";
|
|
16249
|
+
}
|
|
16250
|
+
function isTurnStartedNotification(params) {
|
|
16251
|
+
return isObject2(params) && typeof params.threadId === "string" && isObject2(params.turn) && typeof params.turn.id === "string";
|
|
16252
|
+
}
|
|
16253
|
+
function isTurnCompletedNotification(params) {
|
|
16254
|
+
return isObject2(params) && typeof params.threadId === "string" && isObject2(params.turn) && typeof params.turn.id === "string";
|
|
16255
|
+
}
|
|
16256
|
+
|
|
16257
|
+
class CodexAppServerBridge {
|
|
16258
|
+
threadId;
|
|
16259
|
+
cwd;
|
|
16260
|
+
codexBin;
|
|
16261
|
+
clientName;
|
|
16262
|
+
clientTitle;
|
|
16263
|
+
clientVersion;
|
|
16264
|
+
experimentalApi;
|
|
16265
|
+
env;
|
|
16266
|
+
spawnFn;
|
|
16267
|
+
stderrStream;
|
|
16268
|
+
child = null;
|
|
16269
|
+
stdoutReader = null;
|
|
16270
|
+
readyPromise = null;
|
|
16271
|
+
pendingRequests = new Map;
|
|
16272
|
+
nextRequestId = 1;
|
|
16273
|
+
activeTurnId = null;
|
|
16274
|
+
injectionQueue = Promise.resolve();
|
|
16275
|
+
eventHandler = null;
|
|
16276
|
+
constructor(options) {
|
|
16277
|
+
this.threadId = options.threadId ?? null;
|
|
16278
|
+
this.cwd = options.cwd;
|
|
16279
|
+
this.codexBin = options.codexBin ?? options.env?.MEET_AI_CODEX_PATH ?? process.env.MEET_AI_CODEX_PATH ?? "codex";
|
|
16280
|
+
this.clientName = options.clientName ?? "meet_ai";
|
|
16281
|
+
this.clientTitle = options.clientTitle ?? "meet-ai CLI";
|
|
16282
|
+
this.clientVersion = options.clientVersion ?? "0.0.0";
|
|
16283
|
+
this.experimentalApi = options.experimentalApi ?? false;
|
|
16284
|
+
this.env = options.env ?? process.env;
|
|
16285
|
+
this.spawnFn = options.spawnFn ?? spawn;
|
|
16286
|
+
this.stderrStream = options.stderr ?? stderr;
|
|
16287
|
+
}
|
|
16288
|
+
async start() {
|
|
16289
|
+
if (!this.readyPromise) {
|
|
16290
|
+
this.readyPromise = this.startInternal().catch((error48) => {
|
|
16291
|
+
this.readyPromise = null;
|
|
16292
|
+
throw error48;
|
|
16293
|
+
});
|
|
16294
|
+
}
|
|
16295
|
+
return this.readyPromise;
|
|
16296
|
+
}
|
|
16297
|
+
async injectText(input) {
|
|
16298
|
+
const text = formatRoomMessageForCodex(input);
|
|
16299
|
+
return this.injectPrompt(text);
|
|
16300
|
+
}
|
|
16301
|
+
async injectPrompt(text) {
|
|
16302
|
+
return this.enqueue(async () => {
|
|
16303
|
+
await this.start();
|
|
16304
|
+
const payload = [{ type: "text", text, text_elements: [] }];
|
|
16305
|
+
const threadId = this.threadId;
|
|
16306
|
+
if (!threadId) {
|
|
16307
|
+
throw new Error("Codex app-server bridge does not have an active thread");
|
|
16308
|
+
}
|
|
16309
|
+
if (this.activeTurnId) {
|
|
16310
|
+
try {
|
|
16311
|
+
const result2 = await this.request("turn/steer", {
|
|
16312
|
+
threadId,
|
|
16313
|
+
input: payload,
|
|
16314
|
+
expectedTurnId: this.activeTurnId
|
|
16315
|
+
});
|
|
16316
|
+
this.activeTurnId = result2.turnId;
|
|
16317
|
+
return { mode: "steer", threadId, turnId: result2.turnId };
|
|
16318
|
+
} catch (error48) {
|
|
16319
|
+
if (!isSteerPreconditionError(error48))
|
|
16320
|
+
throw error48;
|
|
16321
|
+
this.activeTurnId = null;
|
|
16322
|
+
}
|
|
16323
|
+
}
|
|
16324
|
+
const result = await this.request("turn/start", {
|
|
16325
|
+
threadId,
|
|
16326
|
+
input: payload
|
|
16327
|
+
});
|
|
16328
|
+
this.activeTurnId = result.turn.id;
|
|
16329
|
+
return { mode: "start", threadId, turnId: result.turn.id };
|
|
16330
|
+
});
|
|
16331
|
+
}
|
|
16332
|
+
getThreadId() {
|
|
16333
|
+
return this.threadId;
|
|
16334
|
+
}
|
|
16335
|
+
async close() {
|
|
16336
|
+
this.readyPromise = null;
|
|
16337
|
+
this.activeTurnId = null;
|
|
16338
|
+
if (this.stdoutReader) {
|
|
16339
|
+
this.stdoutReader.close();
|
|
16340
|
+
this.stdoutReader = null;
|
|
16341
|
+
}
|
|
16342
|
+
const child = this.child;
|
|
16343
|
+
this.child = null;
|
|
16344
|
+
if (!child)
|
|
16345
|
+
return;
|
|
16346
|
+
for (const pending of this.pendingRequests.values()) {
|
|
16347
|
+
pending.reject(new Error("Codex app-server bridge closed"));
|
|
16348
|
+
}
|
|
16349
|
+
this.pendingRequests.clear();
|
|
16350
|
+
child.kill();
|
|
16351
|
+
}
|
|
16352
|
+
setEventHandler(handler) {
|
|
16353
|
+
this.eventHandler = handler;
|
|
16354
|
+
}
|
|
16355
|
+
enqueue(fn) {
|
|
16356
|
+
const next = this.injectionQueue.then(fn, fn);
|
|
16357
|
+
this.injectionQueue = next.catch(() => {
|
|
16358
|
+
return;
|
|
16359
|
+
});
|
|
16360
|
+
return next;
|
|
16361
|
+
}
|
|
16362
|
+
async startInternal() {
|
|
16363
|
+
const child = this.spawnFn(this.codexBin, [
|
|
16364
|
+
"app-server",
|
|
16365
|
+
"--enable",
|
|
16366
|
+
"multi_agent",
|
|
16367
|
+
"--enable",
|
|
16368
|
+
"memories",
|
|
16369
|
+
"--enable",
|
|
16370
|
+
"realtime_conversation",
|
|
16371
|
+
"-c",
|
|
16372
|
+
'sandbox_mode="workspace-write"',
|
|
16373
|
+
"-c",
|
|
16374
|
+
"sandbox_workspace_write.network_access=true",
|
|
16375
|
+
"-c",
|
|
16376
|
+
'web_search="live"',
|
|
16377
|
+
"--listen",
|
|
16378
|
+
"stdio://"
|
|
16379
|
+
], {
|
|
16380
|
+
cwd: this.cwd,
|
|
16381
|
+
env: this.env,
|
|
16382
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
16383
|
+
});
|
|
16384
|
+
this.child = child;
|
|
16385
|
+
this.stdoutReader = createInterface({ input: child.stdout });
|
|
16386
|
+
this.stdoutReader.on("line", (line) => {
|
|
16387
|
+
this.handleLine(line);
|
|
16388
|
+
});
|
|
16389
|
+
child.stderr.on("data", (chunk) => {
|
|
16390
|
+
this.stderrStream.write(chunk);
|
|
16391
|
+
});
|
|
16392
|
+
child.on("exit", (_code, signal) => {
|
|
16393
|
+
const reason = new Error(`codex app-server exited${signal ? ` with signal ${signal}` : ""}`);
|
|
16394
|
+
for (const pending of this.pendingRequests.values()) {
|
|
16395
|
+
pending.reject(reason);
|
|
16396
|
+
}
|
|
16397
|
+
this.pendingRequests.clear();
|
|
16398
|
+
this.child = null;
|
|
16399
|
+
this.stdoutReader = null;
|
|
16400
|
+
this.readyPromise = null;
|
|
16401
|
+
});
|
|
16402
|
+
await this.request("initialize", {
|
|
16403
|
+
clientInfo: {
|
|
16404
|
+
name: this.clientName,
|
|
16405
|
+
title: this.clientTitle,
|
|
16406
|
+
version: this.clientVersion
|
|
16407
|
+
},
|
|
16408
|
+
capabilities: {
|
|
16409
|
+
experimentalApi: this.experimentalApi
|
|
16410
|
+
}
|
|
16411
|
+
});
|
|
16412
|
+
this.notify("initialized");
|
|
16413
|
+
if (this.threadId) {
|
|
16414
|
+
const resumeParams = {
|
|
16415
|
+
threadId: this.threadId,
|
|
16416
|
+
persistExtendedHistory: this.experimentalApi
|
|
16417
|
+
};
|
|
16418
|
+
try {
|
|
16419
|
+
const resumeResult = await this.request("thread/resume", resumeParams);
|
|
16420
|
+
this.threadId = typeof resumeResult.thread?.id === "string" ? resumeResult.thread.id : this.threadId;
|
|
16421
|
+
this.activeTurnId = maybeActiveTurnId(resumeResult.thread);
|
|
16422
|
+
return;
|
|
16423
|
+
} catch {
|
|
16424
|
+
this.stderrStream.write(`meet-ai: codex app-server could not resume thread ${this.threadId}, starting fresh
|
|
16425
|
+
`);
|
|
16426
|
+
this.threadId = null;
|
|
16427
|
+
this.activeTurnId = null;
|
|
16428
|
+
}
|
|
16429
|
+
}
|
|
16430
|
+
const startResult = await this.request("thread/start", {
|
|
16431
|
+
cwd: this.cwd,
|
|
16432
|
+
experimentalRawEvents: false,
|
|
16433
|
+
persistExtendedHistory: this.experimentalApi
|
|
16434
|
+
});
|
|
16435
|
+
this.threadId = typeof startResult.thread?.id === "string" ? startResult.thread.id : null;
|
|
16436
|
+
this.activeTurnId = maybeActiveTurnId(startResult.thread);
|
|
16437
|
+
}
|
|
16438
|
+
async handleLine(line) {
|
|
16439
|
+
const trimmed = line.trim();
|
|
16440
|
+
if (!trimmed)
|
|
16441
|
+
return;
|
|
16442
|
+
let message;
|
|
16443
|
+
try {
|
|
16444
|
+
message = JSON.parse(trimmed);
|
|
16445
|
+
} catch {
|
|
16446
|
+
this.stderrStream.write(`meet-ai: failed to parse codex app-server line: ${trimmed}
|
|
16447
|
+
`);
|
|
16448
|
+
return;
|
|
16449
|
+
}
|
|
16450
|
+
if (isJsonRpcResponse(message)) {
|
|
16451
|
+
const pending = this.pendingRequests.get(message.id);
|
|
16452
|
+
if (!pending)
|
|
16453
|
+
return;
|
|
16454
|
+
this.pendingRequests.delete(message.id);
|
|
16455
|
+
if (message.error) {
|
|
16456
|
+
pending.reject(new Error(message.error.message ?? "Unknown app-server error"));
|
|
16457
|
+
return;
|
|
16458
|
+
}
|
|
16459
|
+
pending.resolve(message.result);
|
|
16460
|
+
return;
|
|
16461
|
+
}
|
|
16462
|
+
if (isJsonRpcServerRequest(message)) {
|
|
16463
|
+
this.respondToServerRequest(message);
|
|
16464
|
+
return;
|
|
16465
|
+
}
|
|
16466
|
+
if (isJsonRpcNotification(message)) {
|
|
16467
|
+
this.handleNotification(message);
|
|
16468
|
+
}
|
|
16469
|
+
}
|
|
16470
|
+
handleNotification(message) {
|
|
16471
|
+
if (message.method === "thread/started") {
|
|
16472
|
+
if (isThreadStartedNotification(message.params))
|
|
16473
|
+
this.threadId = message.params.thread.id;
|
|
16474
|
+
return;
|
|
16475
|
+
}
|
|
16476
|
+
if (message.method === "turn/started") {
|
|
16477
|
+
if (isTurnStartedNotification(message.params) && message.params.threadId === this.threadId) {
|
|
16478
|
+
this.activeTurnId = message.params.turn.id;
|
|
16479
|
+
}
|
|
16480
|
+
return;
|
|
16481
|
+
}
|
|
16482
|
+
if (message.method === "turn/completed") {
|
|
16483
|
+
if (isTurnCompletedNotification(message.params) && message.params.threadId === this.threadId && message.params.turn.id === this.activeTurnId) {
|
|
16484
|
+
this.activeTurnId = null;
|
|
16485
|
+
}
|
|
16486
|
+
this.emitEvent({
|
|
16487
|
+
type: "turn_completed",
|
|
16488
|
+
turnId: isTurnCompletedNotification(message.params) ? message.params.turn.id : null
|
|
16489
|
+
});
|
|
16490
|
+
return;
|
|
16491
|
+
}
|
|
16492
|
+
if (message.method === "item/agentMessage/delta") {
|
|
16493
|
+
const event = extractAgentMessageDelta(message.params);
|
|
16494
|
+
if (event.text) {
|
|
16495
|
+
this.emitEvent({
|
|
16496
|
+
type: "agent_message_delta",
|
|
16497
|
+
itemId: event.itemId,
|
|
16498
|
+
turnId: event.turnId,
|
|
16499
|
+
text: event.text
|
|
16500
|
+
});
|
|
16501
|
+
}
|
|
16502
|
+
return;
|
|
16503
|
+
}
|
|
16504
|
+
if (message.method === "item/completed") {
|
|
16505
|
+
const event = extractCompletedAgentMessage(message.params);
|
|
16506
|
+
if (event?.text) {
|
|
16507
|
+
this.emitEvent({
|
|
16508
|
+
type: "agent_message_completed",
|
|
16509
|
+
itemId: event.itemId,
|
|
16510
|
+
turnId: event.turnId,
|
|
16511
|
+
text: event.text
|
|
16512
|
+
});
|
|
16513
|
+
}
|
|
16514
|
+
}
|
|
16515
|
+
}
|
|
16516
|
+
emitEvent(event) {
|
|
16517
|
+
if (!this.eventHandler)
|
|
16518
|
+
return;
|
|
16519
|
+
try {
|
|
16520
|
+
this.eventHandler(event);
|
|
16521
|
+
} catch (error48) {
|
|
16522
|
+
this.stderrStream.write(`meet-ai: codex app-server event handler failed: ${toErrorMessage(error48)}
|
|
16523
|
+
`);
|
|
16524
|
+
}
|
|
16525
|
+
}
|
|
16526
|
+
respondToServerRequest(message) {
|
|
16527
|
+
switch (message.method) {
|
|
16528
|
+
case "item/commandExecution/requestApproval": {
|
|
16529
|
+
this.stderrStream.write(`meet-ai: auto-resolving unsupported codex app-server request ${message.method}
|
|
16530
|
+
`);
|
|
16531
|
+
this.writeMessage({ id: message.id, result: { decision: "decline" } });
|
|
16532
|
+
return;
|
|
16533
|
+
}
|
|
16534
|
+
case "item/fileChange/requestApproval": {
|
|
16535
|
+
this.stderrStream.write(`meet-ai: auto-resolving unsupported codex app-server request ${message.method}
|
|
16536
|
+
`);
|
|
16537
|
+
this.writeMessage({ id: message.id, result: { decision: "decline" } });
|
|
16538
|
+
return;
|
|
16539
|
+
}
|
|
16540
|
+
case "item/tool/requestUserInput": {
|
|
16541
|
+
this.stderrStream.write(`meet-ai: auto-resolving unsupported codex app-server request ${message.method}
|
|
16542
|
+
`);
|
|
16543
|
+
this.writeMessage({ id: message.id, result: { answers: {} } });
|
|
16544
|
+
return;
|
|
16545
|
+
}
|
|
16546
|
+
case "mcpServer/elicitation/request": {
|
|
16547
|
+
this.stderrStream.write(`meet-ai: auto-resolving unsupported codex app-server request ${message.method}
|
|
16548
|
+
`);
|
|
16549
|
+
this.writeMessage({ id: message.id, result: { action: "cancel", content: null } });
|
|
16550
|
+
return;
|
|
16551
|
+
}
|
|
16552
|
+
case "applyPatchApproval": {
|
|
16553
|
+
this.stderrStream.write(`meet-ai: auto-resolving unsupported codex app-server request ${message.method}
|
|
16554
|
+
`);
|
|
16555
|
+
this.writeMessage({ id: message.id, result: { decision: "denied" } });
|
|
16556
|
+
return;
|
|
16557
|
+
}
|
|
16558
|
+
case "execCommandApproval": {
|
|
16559
|
+
this.stderrStream.write(`meet-ai: auto-resolving unsupported codex app-server request ${message.method}
|
|
16560
|
+
`);
|
|
16561
|
+
this.writeMessage({ id: message.id, result: { decision: "denied" } });
|
|
16562
|
+
return;
|
|
16563
|
+
}
|
|
16564
|
+
default: {
|
|
16565
|
+
this.stderrStream.write(`meet-ai: rejecting unsupported codex app-server request ${message.method}
|
|
16566
|
+
`);
|
|
16567
|
+
this.writeMessage({
|
|
16568
|
+
id: message.id,
|
|
16569
|
+
error: {
|
|
16570
|
+
message: `meet-ai app-server bridge does not support ${message.method}`
|
|
16571
|
+
}
|
|
16572
|
+
});
|
|
16573
|
+
}
|
|
16574
|
+
}
|
|
16575
|
+
}
|
|
16576
|
+
notify(method, params) {
|
|
16577
|
+
this.writeMessage(params === undefined ? { method } : { method, params });
|
|
16578
|
+
}
|
|
16579
|
+
request(method, params) {
|
|
16580
|
+
const id = this.nextRequestId++;
|
|
16581
|
+
return new Promise((resolve3, reject) => {
|
|
16582
|
+
this.pendingRequests.set(id, { resolve: resolve3, reject });
|
|
16583
|
+
try {
|
|
16584
|
+
this.writeMessage(params === undefined ? { method, id } : { method, id, params });
|
|
16585
|
+
} catch (error48) {
|
|
16586
|
+
this.pendingRequests.delete(id);
|
|
16587
|
+
reject(error48);
|
|
16588
|
+
}
|
|
16589
|
+
});
|
|
16590
|
+
}
|
|
16591
|
+
writeMessage(message) {
|
|
16592
|
+
const child = this.child;
|
|
16593
|
+
if (!child) {
|
|
16594
|
+
throw new Error("Codex app-server bridge is not connected");
|
|
16595
|
+
}
|
|
16596
|
+
child.stdin.write(`${JSON.stringify(message)}
|
|
16597
|
+
`);
|
|
16598
|
+
}
|
|
16599
|
+
}
|
|
16600
|
+
function createCodexAppServerBridge(options) {
|
|
16601
|
+
return new CodexAppServerBridge(options);
|
|
16602
|
+
}
|
|
16603
|
+
function describeCodexAppServerError(error48) {
|
|
16604
|
+
return `meet-ai: failed to inject message into Codex via app-server: ${toErrorMessage(error48)}`;
|
|
16605
|
+
}
|
|
16606
|
+
var init_codex_app_server = () => {};
|
|
16607
|
+
|
|
16608
|
+
// src/commands/listen/listen-codex.ts
|
|
16609
|
+
function formatCodexListenOutput(msg) {
|
|
16610
|
+
const lines = [
|
|
16611
|
+
`[meet-ai] ${msg.sender} ${msg.created_at ?? new Date().toISOString()}`,
|
|
16612
|
+
msg.content
|
|
16613
|
+
];
|
|
16614
|
+
if (msg.attachments?.length) {
|
|
16615
|
+
lines.push(`attachments: ${msg.attachments.join(", ")}`);
|
|
16616
|
+
}
|
|
16617
|
+
return `${lines.join(`
|
|
16618
|
+
`)}
|
|
16619
|
+
`;
|
|
16620
|
+
}
|
|
16621
|
+
function formatCodexInjectionOutput(result) {
|
|
16622
|
+
return `[meet-ai->codex] ${result.mode} ${result.turnId}
|
|
16623
|
+
`;
|
|
16624
|
+
}
|
|
16625
|
+
function isTruthyEnv(value) {
|
|
16626
|
+
if (!value)
|
|
16627
|
+
return false;
|
|
16628
|
+
const normalized = value.trim().toLowerCase();
|
|
16629
|
+
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
|
16630
|
+
}
|
|
16631
|
+
function normalizeFinalText(value) {
|
|
16632
|
+
return value.replace(/\r\n/g, `
|
|
16633
|
+
`).trim();
|
|
16634
|
+
}
|
|
16635
|
+
function makeMessageKey(event) {
|
|
16636
|
+
return event.itemId ?? event.turnId ?? "unknown";
|
|
16637
|
+
}
|
|
16638
|
+
function listenCodex(client, input, codexBridgeOverride) {
|
|
16639
|
+
const parsed = ListenInput.parse(input);
|
|
16640
|
+
const { roomId, exclude, senderType, team, inbox } = parsed;
|
|
16641
|
+
let shutdownStarted = false;
|
|
16642
|
+
if (team || inbox) {
|
|
16643
|
+
const flags = [team ? "--team" : null, inbox ? "--inbox" : null].filter(Boolean).join(", ");
|
|
16644
|
+
throw new Error(`Codex listen does not support Claude inbox routing flags (${flags}). Run meet-ai listen without Claude-specific routing options.`);
|
|
16645
|
+
}
|
|
16646
|
+
const terminal = createTerminalControlHandler({ client, roomId });
|
|
16647
|
+
const codexBridge = codexBridgeOverride ?? createCodexAppServerBridge({
|
|
16648
|
+
threadId: null,
|
|
16649
|
+
cwd: process.cwd(),
|
|
16650
|
+
experimentalApi: isTruthyEnv(process.env.MEET_AI_CODEX_APP_SERVER_EXPERIMENTAL)
|
|
16651
|
+
});
|
|
16652
|
+
const bootstrapPrompt = process.env.MEET_AI_CODEX_BOOTSTRAP_PROMPT?.trim();
|
|
16653
|
+
const codexSender = process.env.MEET_AI_AGENT_NAME?.trim() || "codex";
|
|
16654
|
+
const messageState = new Map;
|
|
16655
|
+
let publishQueue = Promise.resolve();
|
|
16656
|
+
const enqueuePublish = (task) => {
|
|
16657
|
+
publishQueue = publishQueue.then(task, task).catch((error48) => {
|
|
16658
|
+
console.error(`meet-ai: failed to publish Codex output to room: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
16659
|
+
});
|
|
16660
|
+
};
|
|
16661
|
+
const publishBufferedMessage = (key) => {
|
|
16662
|
+
const state = messageState.get(key);
|
|
16663
|
+
const text = normalizeFinalText(state?.text ?? "");
|
|
16664
|
+
if (!state || state.sent || state.sending || !text)
|
|
16665
|
+
return;
|
|
16666
|
+
state.sending = true;
|
|
16667
|
+
enqueuePublish(async () => {
|
|
16668
|
+
try {
|
|
16669
|
+
await client.sendMessage(roomId, codexSender, text);
|
|
16670
|
+
state.sent = true;
|
|
16671
|
+
} finally {
|
|
16672
|
+
state.sending = false;
|
|
16673
|
+
}
|
|
16674
|
+
});
|
|
16675
|
+
};
|
|
16676
|
+
const mergeEventText = (event) => {
|
|
16677
|
+
const key = makeMessageKey(event);
|
|
16678
|
+
const nextText = event.text.replace(/\r\n/g, `
|
|
16679
|
+
`);
|
|
16680
|
+
if (!nextText)
|
|
16681
|
+
return;
|
|
16682
|
+
const existing = messageState.get(key);
|
|
16683
|
+
if (!existing) {
|
|
16684
|
+
messageState.set(key, { turnId: event.turnId, text: nextText, sent: false, sending: false });
|
|
16685
|
+
return;
|
|
15731
16686
|
}
|
|
16687
|
+
existing.turnId = event.turnId ?? existing.turnId;
|
|
16688
|
+
if (event.type === "agent_message_completed") {
|
|
16689
|
+
existing.text = nextText;
|
|
16690
|
+
return;
|
|
16691
|
+
}
|
|
16692
|
+
existing.text += nextText;
|
|
16693
|
+
};
|
|
16694
|
+
codexBridge.setEventHandler((event) => {
|
|
16695
|
+
if (event.type === "agent_message_delta" || event.type === "agent_message_completed") {
|
|
16696
|
+
mergeEventText(event);
|
|
16697
|
+
if (event.type === "agent_message_completed") {
|
|
16698
|
+
publishBufferedMessage(makeMessageKey(event));
|
|
16699
|
+
}
|
|
16700
|
+
return;
|
|
16701
|
+
}
|
|
16702
|
+
if (event.type === "turn_completed") {
|
|
16703
|
+
for (const [key, state] of messageState.entries()) {
|
|
16704
|
+
if (state.turnId === event.turnId || !event.turnId && !state.sent) {
|
|
16705
|
+
publishBufferedMessage(key);
|
|
16706
|
+
}
|
|
16707
|
+
}
|
|
16708
|
+
}
|
|
16709
|
+
});
|
|
16710
|
+
const injectMessage = (message) => {
|
|
16711
|
+
codexBridge.injectText({
|
|
16712
|
+
sender: message.sender,
|
|
16713
|
+
content: message.content,
|
|
16714
|
+
timestamp: new Date().toISOString(),
|
|
16715
|
+
attachments: message.attachments
|
|
16716
|
+
}).then((result) => {
|
|
16717
|
+
appendCodexInboxEntry(result.threadId, {
|
|
16718
|
+
from: `meet-ai:${message.sender}`,
|
|
16719
|
+
text: message.content,
|
|
16720
|
+
timestamp: new Date().toISOString(),
|
|
16721
|
+
read: false,
|
|
16722
|
+
...message.attachments?.length ? { attachments: message.attachments } : {}
|
|
16723
|
+
});
|
|
16724
|
+
console.log(formatCodexInjectionOutput(result));
|
|
16725
|
+
}).catch((error48) => {
|
|
16726
|
+
console.error(describeCodexAppServerError(error48));
|
|
16727
|
+
});
|
|
16728
|
+
};
|
|
16729
|
+
const onMessage = (msg) => {
|
|
16730
|
+
if (terminal.handle(msg))
|
|
16731
|
+
return;
|
|
16732
|
+
if (msg.id && msg.room_id && (msg.attachment_count ?? 0) > 0) {
|
|
16733
|
+
downloadMessageAttachments(client, msg.room_id, msg.id).then((paths) => {
|
|
16734
|
+
const output = paths.length ? { ...msg, attachments: paths } : msg;
|
|
16735
|
+
console.log(formatCodexListenOutput(output));
|
|
16736
|
+
injectMessage({
|
|
16737
|
+
sender: msg.sender,
|
|
16738
|
+
content: msg.content,
|
|
16739
|
+
attachments: paths
|
|
16740
|
+
});
|
|
16741
|
+
});
|
|
16742
|
+
return;
|
|
16743
|
+
}
|
|
16744
|
+
console.log(formatCodexListenOutput(msg));
|
|
16745
|
+
injectMessage({
|
|
16746
|
+
sender: msg.sender,
|
|
16747
|
+
content: msg.content
|
|
16748
|
+
});
|
|
16749
|
+
};
|
|
16750
|
+
const ws = client.listen(roomId, { exclude, senderType, onMessage });
|
|
16751
|
+
if (bootstrapPrompt) {
|
|
16752
|
+
const bootstrapRequest = codexBridge.injectPrompt(bootstrapPrompt);
|
|
16753
|
+
bootstrapRequest.then((result) => {
|
|
16754
|
+
console.log(formatCodexInjectionOutput(result));
|
|
16755
|
+
}).catch((error48) => {
|
|
16756
|
+
console.error(describeCodexAppServerError(error48));
|
|
16757
|
+
});
|
|
16758
|
+
}
|
|
16759
|
+
function shutdown() {
|
|
16760
|
+
if (shutdownStarted)
|
|
16761
|
+
return;
|
|
16762
|
+
shutdownStarted = true;
|
|
16763
|
+
terminal.shutdown();
|
|
16764
|
+
codexBridge.setEventHandler(null);
|
|
16765
|
+
codexBridge.close();
|
|
15732
16766
|
if (ws.readyState === WebSocket.OPEN) {
|
|
15733
16767
|
ws.close(1000, "client shutdown");
|
|
15734
16768
|
}
|
|
@@ -15739,10 +16773,11 @@ function listen(client, input) {
|
|
|
15739
16773
|
process.on("SIGHUP", shutdown);
|
|
15740
16774
|
return ws;
|
|
15741
16775
|
}
|
|
15742
|
-
var
|
|
16776
|
+
var init_listen_codex = __esm(() => {
|
|
16777
|
+
init_codex();
|
|
16778
|
+
init_codex_app_server();
|
|
15743
16779
|
init_schema6();
|
|
15744
|
-
|
|
15745
|
-
init_tmux_client();
|
|
16780
|
+
init_shared();
|
|
15746
16781
|
});
|
|
15747
16782
|
|
|
15748
16783
|
// src/commands/listen/command.ts
|
|
@@ -15752,10 +16787,11 @@ __export(exports_command6, {
|
|
|
15752
16787
|
});
|
|
15753
16788
|
var command_default6;
|
|
15754
16789
|
var init_command6 = __esm(() => {
|
|
15755
|
-
|
|
15756
|
-
init_client_factory();
|
|
15757
|
-
init_usecase6();
|
|
16790
|
+
init_bootstrap();
|
|
15758
16791
|
init_output();
|
|
16792
|
+
init_dist();
|
|
16793
|
+
init_listen_claude();
|
|
16794
|
+
init_listen_codex();
|
|
15759
16795
|
command_default6 = defineCommand({
|
|
15760
16796
|
meta: {
|
|
15761
16797
|
name: "listen",
|
|
@@ -15786,24 +16822,24 @@ var init_command6 = __esm(() => {
|
|
|
15786
16822
|
type: "string",
|
|
15787
16823
|
alias: "i",
|
|
15788
16824
|
description: "Inbox name for routing (requires --team)"
|
|
15789
|
-
},
|
|
15790
|
-
"stdin-pane": {
|
|
15791
|
-
type: "string",
|
|
15792
|
-
alias: "s",
|
|
15793
|
-
description: "tmux pane ID to inject non-@mention messages into via send-keys"
|
|
15794
16825
|
}
|
|
15795
16826
|
},
|
|
15796
16827
|
run({ args }) {
|
|
15797
16828
|
try {
|
|
15798
16829
|
const client = getClient();
|
|
15799
|
-
|
|
16830
|
+
const container2 = getContainer();
|
|
16831
|
+
const input = {
|
|
15800
16832
|
roomId: args.roomId,
|
|
15801
16833
|
exclude: args.exclude,
|
|
15802
16834
|
senderType: args["sender-type"],
|
|
15803
16835
|
team: args.team,
|
|
15804
|
-
inbox: args.inbox
|
|
15805
|
-
|
|
15806
|
-
|
|
16836
|
+
inbox: args.inbox
|
|
16837
|
+
};
|
|
16838
|
+
if (getMeetAiRuntime() === "codex") {
|
|
16839
|
+
listenCodex(client, input);
|
|
16840
|
+
return;
|
|
16841
|
+
}
|
|
16842
|
+
listenClaude(client, input, container2.inboxRouter);
|
|
15807
16843
|
} catch (error48) {
|
|
15808
16844
|
err(error48 instanceof Error ? error48.message : String(error48));
|
|
15809
16845
|
process.exit(1);
|
|
@@ -15835,7 +16871,7 @@ async function sendTeamInfo(client, input) {
|
|
|
15835
16871
|
await client.sendTeamInfo(parsed.roomId, parsed.payload);
|
|
15836
16872
|
ok("Team info sent");
|
|
15837
16873
|
}
|
|
15838
|
-
var
|
|
16874
|
+
var init_usecase6 = __esm(() => {
|
|
15839
16875
|
init_schema7();
|
|
15840
16876
|
init_output();
|
|
15841
16877
|
});
|
|
@@ -15848,8 +16884,8 @@ __export(exports_command7, {
|
|
|
15848
16884
|
var command_default7;
|
|
15849
16885
|
var init_command7 = __esm(() => {
|
|
15850
16886
|
init_dist();
|
|
15851
|
-
|
|
15852
|
-
|
|
16887
|
+
init_bootstrap();
|
|
16888
|
+
init_usecase6();
|
|
15853
16889
|
init_output();
|
|
15854
16890
|
command_default7 = defineCommand({
|
|
15855
16891
|
meta: {
|
|
@@ -15903,7 +16939,7 @@ async function sendTasks(client, input) {
|
|
|
15903
16939
|
await client.sendTasks(parsed.roomId, parsed.payload);
|
|
15904
16940
|
ok("Tasks info sent");
|
|
15905
16941
|
}
|
|
15906
|
-
var
|
|
16942
|
+
var init_usecase7 = __esm(() => {
|
|
15907
16943
|
init_schema8();
|
|
15908
16944
|
init_output();
|
|
15909
16945
|
});
|
|
@@ -15916,8 +16952,8 @@ __export(exports_command8, {
|
|
|
15916
16952
|
var command_default8;
|
|
15917
16953
|
var init_command8 = __esm(() => {
|
|
15918
16954
|
init_dist();
|
|
15919
|
-
|
|
15920
|
-
|
|
16955
|
+
init_bootstrap();
|
|
16956
|
+
init_usecase7();
|
|
15921
16957
|
init_output();
|
|
15922
16958
|
command_default8 = defineCommand({
|
|
15923
16959
|
meta: {
|
|
@@ -15964,7 +17000,7 @@ async function downloadAttachment(client, input) {
|
|
|
15964
17000
|
ok(localPath);
|
|
15965
17001
|
return localPath;
|
|
15966
17002
|
}
|
|
15967
|
-
var
|
|
17003
|
+
var init_usecase8 = __esm(() => {
|
|
15968
17004
|
init_schema9();
|
|
15969
17005
|
init_output();
|
|
15970
17006
|
});
|
|
@@ -15977,8 +17013,8 @@ __export(exports_command9, {
|
|
|
15977
17013
|
var command_default9;
|
|
15978
17014
|
var init_command9 = __esm(() => {
|
|
15979
17015
|
init_dist();
|
|
15980
|
-
|
|
15981
|
-
|
|
17016
|
+
init_bootstrap();
|
|
17017
|
+
init_usecase8();
|
|
15982
17018
|
init_output();
|
|
15983
17019
|
command_default9 = defineCommand({
|
|
15984
17020
|
meta: {
|
|
@@ -16020,7 +17056,7 @@ __export(exports_command10, {
|
|
|
16020
17056
|
var command_default10;
|
|
16021
17057
|
var init_command10 = __esm(() => {
|
|
16022
17058
|
init_dist();
|
|
16023
|
-
|
|
17059
|
+
init_bootstrap();
|
|
16024
17060
|
init_output();
|
|
16025
17061
|
command_default10 = defineCommand({
|
|
16026
17062
|
meta: {
|
|
@@ -16041,12 +17077,12 @@ var init_command10 = __esm(() => {
|
|
|
16041
17077
|
});
|
|
16042
17078
|
|
|
16043
17079
|
// src/lib/hooks/find-room.ts
|
|
16044
|
-
import { readdirSync, readFileSync as
|
|
16045
|
-
import { join as
|
|
16046
|
-
import { createInterface } from "node:readline";
|
|
17080
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3, createReadStream } from "node:fs";
|
|
17081
|
+
import { join as join3 } from "node:path";
|
|
17082
|
+
import { createInterface as createInterface2 } from "node:readline";
|
|
16047
17083
|
async function extractTeamName(transcriptPath) {
|
|
16048
17084
|
try {
|
|
16049
|
-
const rl =
|
|
17085
|
+
const rl = createInterface2({
|
|
16050
17086
|
input: createReadStream(transcriptPath, "utf-8"),
|
|
16051
17087
|
crlfDelay: Infinity
|
|
16052
17088
|
});
|
|
@@ -16074,7 +17110,7 @@ function registerSession(filePath, data, sessionId) {
|
|
|
16074
17110
|
}
|
|
16075
17111
|
data.session_ids = ids;
|
|
16076
17112
|
try {
|
|
16077
|
-
|
|
17113
|
+
writeFileSync3(filePath, JSON.stringify(data));
|
|
16078
17114
|
} catch {}
|
|
16079
17115
|
}
|
|
16080
17116
|
async function findRoom(sessionId, teamsDir, transcriptPath) {
|
|
@@ -16082,9 +17118,9 @@ async function findRoom(sessionId, teamsDir, transcriptPath) {
|
|
|
16082
17118
|
if (transcriptPath) {
|
|
16083
17119
|
const teamName = await extractTeamName(transcriptPath);
|
|
16084
17120
|
if (teamName) {
|
|
16085
|
-
const filePath =
|
|
17121
|
+
const filePath = join3(dir, teamName, "meet-ai.json");
|
|
16086
17122
|
try {
|
|
16087
|
-
const raw =
|
|
17123
|
+
const raw = readFileSync4(filePath, "utf-8");
|
|
16088
17124
|
const data = JSON.parse(raw);
|
|
16089
17125
|
registerSession(filePath, data, sessionId);
|
|
16090
17126
|
if (data.room_id)
|
|
@@ -16094,14 +17130,14 @@ async function findRoom(sessionId, teamsDir, transcriptPath) {
|
|
|
16094
17130
|
}
|
|
16095
17131
|
let entries;
|
|
16096
17132
|
try {
|
|
16097
|
-
entries =
|
|
17133
|
+
entries = readdirSync2(dir);
|
|
16098
17134
|
} catch {
|
|
16099
17135
|
return null;
|
|
16100
17136
|
}
|
|
16101
17137
|
for (const entry of entries) {
|
|
16102
|
-
const filePath =
|
|
17138
|
+
const filePath = join3(dir, entry, "meet-ai.json");
|
|
16103
17139
|
try {
|
|
16104
|
-
const raw =
|
|
17140
|
+
const raw = readFileSync4(filePath, "utf-8");
|
|
16105
17141
|
const data = JSON.parse(raw);
|
|
16106
17142
|
const knownIds = data.session_ids ?? [data.session_id];
|
|
16107
17143
|
if (knownIds.includes(sessionId) || data.session_id === sessionId) {
|
|
@@ -16264,17 +17300,17 @@ var init_cookie = __esm(() => {
|
|
|
16264
17300
|
var init_fetch_result_please = () => {};
|
|
16265
17301
|
|
|
16266
17302
|
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/utils.js
|
|
16267
|
-
function
|
|
17303
|
+
function isObject3(item) {
|
|
16268
17304
|
return typeof item === "object" && item !== null && !Array.isArray(item);
|
|
16269
17305
|
}
|
|
16270
17306
|
function deepMerge(target, source) {
|
|
16271
|
-
if (!
|
|
17307
|
+
if (!isObject3(target) && !isObject3(source)) {
|
|
16272
17308
|
return source;
|
|
16273
17309
|
}
|
|
16274
17310
|
const merged = { ...target };
|
|
16275
17311
|
for (const key in source) {
|
|
16276
17312
|
const value = source[key];
|
|
16277
|
-
if (
|
|
17313
|
+
if (isObject3(merged[key]) && isObject3(value)) {
|
|
16278
17314
|
merged[key] = deepMerge(merged[key], value);
|
|
16279
17315
|
} else {
|
|
16280
17316
|
merged[key] = value;
|
|
@@ -16481,14 +17517,14 @@ var createProxy = (callback, path) => {
|
|
|
16481
17517
|
}
|
|
16482
17518
|
return req;
|
|
16483
17519
|
}, []);
|
|
16484
|
-
var
|
|
17520
|
+
var init_client = __esm(() => {
|
|
16485
17521
|
init_cookie();
|
|
16486
17522
|
init_utils();
|
|
16487
17523
|
});
|
|
16488
17524
|
|
|
16489
17525
|
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/index.js
|
|
16490
|
-
var
|
|
16491
|
-
|
|
17526
|
+
var init_client2 = __esm(() => {
|
|
17527
|
+
init_client();
|
|
16492
17528
|
init_utils();
|
|
16493
17529
|
});
|
|
16494
17530
|
|
|
@@ -16542,35 +17578,35 @@ async function sendLogEntry(client, roomId, summary, messageId) {
|
|
|
16542
17578
|
} catch {}
|
|
16543
17579
|
}
|
|
16544
17580
|
var HOOK_COLOR = "#6b7280", HOOK_SENDER = "hook";
|
|
16545
|
-
var
|
|
16546
|
-
|
|
17581
|
+
var init_client3 = __esm(() => {
|
|
17582
|
+
init_client2();
|
|
16547
17583
|
});
|
|
16548
17584
|
|
|
16549
17585
|
// src/lib/hooks/index.ts
|
|
16550
17586
|
var init_hooks = __esm(() => {
|
|
16551
17587
|
init_find_room();
|
|
16552
17588
|
init_summarize();
|
|
16553
|
-
|
|
17589
|
+
init_client3();
|
|
16554
17590
|
});
|
|
16555
17591
|
|
|
16556
17592
|
// src/commands/hook/log-tool-use/usecase.ts
|
|
16557
|
-
import { readFileSync as
|
|
17593
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, statSync as statSync3, rmSync } from "node:fs";
|
|
16558
17594
|
function getOrCreateParentId(sessionId) {
|
|
16559
17595
|
const path = `/tmp/meet-ai-hook-${sessionId}.msgid`;
|
|
16560
17596
|
try {
|
|
16561
|
-
const mtime =
|
|
17597
|
+
const mtime = statSync3(path).mtimeMs;
|
|
16562
17598
|
if (Date.now() - mtime > PARENT_MSG_TTL_SEC * 1000) {
|
|
16563
17599
|
rmSync(path, { force: true });
|
|
16564
17600
|
return null;
|
|
16565
17601
|
}
|
|
16566
|
-
return
|
|
17602
|
+
return readFileSync5(path, "utf-8").trim() || null;
|
|
16567
17603
|
} catch {
|
|
16568
17604
|
return null;
|
|
16569
17605
|
}
|
|
16570
17606
|
}
|
|
16571
17607
|
function saveParentId(sessionId, msgId) {
|
|
16572
17608
|
try {
|
|
16573
|
-
|
|
17609
|
+
writeFileSync4(`/tmp/meet-ai-hook-${sessionId}.msgid`, msgId);
|
|
16574
17610
|
} catch {}
|
|
16575
17611
|
}
|
|
16576
17612
|
async function processHookInput(rawInput, teamsDir) {
|
|
@@ -16674,7 +17710,7 @@ async function processHookInput(rawInput, teamsDir) {
|
|
|
16674
17710
|
return "sent";
|
|
16675
17711
|
}
|
|
16676
17712
|
var PARENT_MSG_TTL_SEC = 120;
|
|
16677
|
-
var
|
|
17713
|
+
var init_usecase9 = __esm(() => {
|
|
16678
17714
|
init_hooks();
|
|
16679
17715
|
});
|
|
16680
17716
|
|
|
@@ -16686,7 +17722,7 @@ __export(exports_command11, {
|
|
|
16686
17722
|
var command_default11;
|
|
16687
17723
|
var init_command11 = __esm(() => {
|
|
16688
17724
|
init_dist();
|
|
16689
|
-
|
|
17725
|
+
init_usecase9();
|
|
16690
17726
|
command_default11 = defineCommand({
|
|
16691
17727
|
meta: {
|
|
16692
17728
|
name: "log-tool-use",
|
|
@@ -16851,8 +17887,8 @@ async function processPlanReview(rawInput, teamsDir) {
|
|
|
16851
17887
|
}
|
|
16852
17888
|
}
|
|
16853
17889
|
var POLL_INTERVAL_MS = 2000, POLL_TIMEOUT_MS = 2592000000;
|
|
16854
|
-
var
|
|
16855
|
-
|
|
17890
|
+
var init_usecase10 = __esm(() => {
|
|
17891
|
+
init_client3();
|
|
16856
17892
|
init_find_room();
|
|
16857
17893
|
});
|
|
16858
17894
|
|
|
@@ -16875,7 +17911,7 @@ var init_command12 = __esm(() => {
|
|
|
16875
17911
|
for await (const chunk of process.stdin) {
|
|
16876
17912
|
input += chunk;
|
|
16877
17913
|
}
|
|
16878
|
-
const { processPlanReview: processPlanReview2 } = await Promise.resolve().then(() => (
|
|
17914
|
+
const { processPlanReview: processPlanReview2 } = await Promise.resolve().then(() => (init_usecase10(), exports_usecase));
|
|
16879
17915
|
await processPlanReview2(input);
|
|
16880
17916
|
} catch (error48) {
|
|
16881
17917
|
process.stderr.write(`[plan-review] fatal: ${error48}
|
|
@@ -16947,7 +17983,7 @@ async function pollForAnswer(client, roomId, reviewId, pollInterval = POLL_INTER
|
|
|
16947
17983
|
process.stderr.write(`[question-review] poll error: ${error48}
|
|
16948
17984
|
`);
|
|
16949
17985
|
}
|
|
16950
|
-
await new Promise((
|
|
17986
|
+
await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
|
|
16951
17987
|
}
|
|
16952
17988
|
return null;
|
|
16953
17989
|
}
|
|
@@ -17047,8 +18083,8 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
|
|
|
17047
18083
|
}
|
|
17048
18084
|
}
|
|
17049
18085
|
var POLL_INTERVAL_MS2 = 2000, POLL_TIMEOUT_MS2 = 1800000;
|
|
17050
|
-
var
|
|
17051
|
-
|
|
18086
|
+
var init_usecase11 = __esm(() => {
|
|
18087
|
+
init_client3();
|
|
17052
18088
|
init_find_room();
|
|
17053
18089
|
});
|
|
17054
18090
|
|
|
@@ -17060,7 +18096,7 @@ __export(exports_command13, {
|
|
|
17060
18096
|
var command_default13;
|
|
17061
18097
|
var init_command13 = __esm(() => {
|
|
17062
18098
|
init_dist();
|
|
17063
|
-
|
|
18099
|
+
init_usecase11();
|
|
17064
18100
|
command_default13 = defineCommand({
|
|
17065
18101
|
meta: {
|
|
17066
18102
|
name: "question-review",
|
|
@@ -17139,7 +18175,7 @@ async function pollForDecision2(client, roomId, reviewId, pollInterval = POLL_IN
|
|
|
17139
18175
|
process.stderr.write(`[permission-review] poll error: ${error48}
|
|
17140
18176
|
`);
|
|
17141
18177
|
}
|
|
17142
|
-
await new Promise((
|
|
18178
|
+
await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
|
|
17143
18179
|
}
|
|
17144
18180
|
return null;
|
|
17145
18181
|
}
|
|
@@ -17245,8 +18281,8 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
|
|
|
17245
18281
|
}
|
|
17246
18282
|
}
|
|
17247
18283
|
var POLL_INTERVAL_MS3 = 2000, POLL_TIMEOUT_MS3 = 1800000;
|
|
17248
|
-
var
|
|
17249
|
-
|
|
18284
|
+
var init_usecase12 = __esm(() => {
|
|
18285
|
+
init_client3();
|
|
17250
18286
|
init_find_room();
|
|
17251
18287
|
});
|
|
17252
18288
|
|
|
@@ -17258,7 +18294,7 @@ __export(exports_command14, {
|
|
|
17258
18294
|
var command_default14;
|
|
17259
18295
|
var init_command14 = __esm(() => {
|
|
17260
18296
|
init_dist();
|
|
17261
|
-
|
|
18297
|
+
init_usecase12();
|
|
17262
18298
|
command_default14 = defineCommand({
|
|
17263
18299
|
meta: {
|
|
17264
18300
|
name: "permission-review",
|
|
@@ -17303,21 +18339,21 @@ var init_command15 = __esm(() => {
|
|
|
17303
18339
|
});
|
|
17304
18340
|
|
|
17305
18341
|
// src/commands/setup-hooks/usecase.ts
|
|
17306
|
-
import { existsSync as
|
|
18342
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
17307
18343
|
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
17308
|
-
import { homedir as
|
|
17309
|
-
import { resolve as
|
|
18344
|
+
import { homedir as homedir3 } from "node:os";
|
|
18345
|
+
import { resolve as resolve3, dirname as dirname3 } from "node:path";
|
|
17310
18346
|
function isMeetAiHook(entry) {
|
|
17311
18347
|
return entry.hooks?.some((h) => typeof h.command === "string" && h.command.startsWith("meet-ai hook ")) ?? false;
|
|
17312
18348
|
}
|
|
17313
18349
|
function getSettingsPath(project) {
|
|
17314
18350
|
if (project) {
|
|
17315
|
-
return
|
|
18351
|
+
return resolve3(process.cwd(), ".claude", "settings.json");
|
|
17316
18352
|
}
|
|
17317
|
-
return
|
|
18353
|
+
return resolve3(homedir3(), ".claude", "settings.json");
|
|
17318
18354
|
}
|
|
17319
18355
|
async function readSettings(path) {
|
|
17320
|
-
if (!
|
|
18356
|
+
if (!existsSync4(path)) {
|
|
17321
18357
|
return {};
|
|
17322
18358
|
}
|
|
17323
18359
|
const raw = await readFile(path, "utf-8");
|
|
@@ -17399,7 +18435,7 @@ async function setupHooks(options) {
|
|
|
17399
18435
|
if (Object.keys(cleaned).length === 0) {
|
|
17400
18436
|
delete updated.hooks;
|
|
17401
18437
|
}
|
|
17402
|
-
await mkdir(
|
|
18438
|
+
await mkdir(dirname3(settingsPath), { recursive: true });
|
|
17403
18439
|
await writeFile(settingsPath, `${JSON.stringify(updated, null, 2)}
|
|
17404
18440
|
`);
|
|
17405
18441
|
for (const r of removed) {
|
|
@@ -17416,7 +18452,7 @@ async function setupHooks(options) {
|
|
|
17416
18452
|
return;
|
|
17417
18453
|
}
|
|
17418
18454
|
const updated = { ...settings, hooks: merged };
|
|
17419
|
-
await mkdir(
|
|
18455
|
+
await mkdir(dirname3(settingsPath), { recursive: true });
|
|
17420
18456
|
await writeFile(settingsPath, `${JSON.stringify(updated, null, 2)}
|
|
17421
18457
|
`);
|
|
17422
18458
|
for (const a of added) {
|
|
@@ -17426,7 +18462,7 @@ async function setupHooks(options) {
|
|
|
17426
18462
|
}
|
|
17427
18463
|
}
|
|
17428
18464
|
var import_picocolors2, MEET_AI_HOOKS;
|
|
17429
|
-
var
|
|
18465
|
+
var init_usecase13 = __esm(() => {
|
|
17430
18466
|
init_output();
|
|
17431
18467
|
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
17432
18468
|
MEET_AI_HOOKS = {
|
|
@@ -17485,7 +18521,7 @@ __export(exports_command16, {
|
|
|
17485
18521
|
var command_default16;
|
|
17486
18522
|
var init_command16 = __esm(() => {
|
|
17487
18523
|
init_dist();
|
|
17488
|
-
|
|
18524
|
+
init_usecase13();
|
|
17489
18525
|
init_output();
|
|
17490
18526
|
command_default16 = defineCommand({
|
|
17491
18527
|
meta: {
|
|
@@ -17525,10 +18561,10 @@ var init_command16 = __esm(() => {
|
|
|
17525
18561
|
});
|
|
17526
18562
|
|
|
17527
18563
|
// src/commands/list-commands/usecase.ts
|
|
17528
|
-
import { existsSync as
|
|
18564
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
17529
18565
|
import { readFile as readFile2, readdir } from "node:fs/promises";
|
|
17530
|
-
import { homedir as
|
|
17531
|
-
import { join as
|
|
18566
|
+
import { homedir as homedir4 } from "node:os";
|
|
18567
|
+
import { join as join4, resolve as resolve4 } from "node:path";
|
|
17532
18568
|
function parseYamlFrontmatter(content) {
|
|
17533
18569
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
17534
18570
|
if (!match)
|
|
@@ -17544,8 +18580,8 @@ function parseYamlFrontmatter(content) {
|
|
|
17544
18580
|
};
|
|
17545
18581
|
}
|
|
17546
18582
|
async function readSkillsFromDir(baseDir, source, scope) {
|
|
17547
|
-
const skillsDir =
|
|
17548
|
-
if (!
|
|
18583
|
+
const skillsDir = join4(baseDir, "skills");
|
|
18584
|
+
if (!existsSync5(skillsDir))
|
|
17549
18585
|
return [];
|
|
17550
18586
|
let entries;
|
|
17551
18587
|
try {
|
|
@@ -17555,8 +18591,8 @@ async function readSkillsFromDir(baseDir, source, scope) {
|
|
|
17555
18591
|
}
|
|
17556
18592
|
const results = [];
|
|
17557
18593
|
for (const entry of entries) {
|
|
17558
|
-
const skillFile =
|
|
17559
|
-
if (!
|
|
18594
|
+
const skillFile = join4(skillsDir, entry, "SKILL.md");
|
|
18595
|
+
if (!existsSync5(skillFile))
|
|
17560
18596
|
continue;
|
|
17561
18597
|
try {
|
|
17562
18598
|
const content = await readFile2(skillFile, "utf-8");
|
|
@@ -17579,7 +18615,7 @@ async function readSkillsFromDir(baseDir, source, scope) {
|
|
|
17579
18615
|
return results;
|
|
17580
18616
|
}
|
|
17581
18617
|
async function readCommandsFromDir(commandsDir, source, scope) {
|
|
17582
|
-
if (!
|
|
18618
|
+
if (!existsSync5(commandsDir))
|
|
17583
18619
|
return [];
|
|
17584
18620
|
const results = [];
|
|
17585
18621
|
async function scanDir(dir) {
|
|
@@ -17590,7 +18626,7 @@ async function readCommandsFromDir(commandsDir, source, scope) {
|
|
|
17590
18626
|
return;
|
|
17591
18627
|
}
|
|
17592
18628
|
for (const entry of entries) {
|
|
17593
|
-
const fullPath =
|
|
18629
|
+
const fullPath = join4(dir, entry.name);
|
|
17594
18630
|
if (entry.isDirectory()) {
|
|
17595
18631
|
await scanDir(fullPath);
|
|
17596
18632
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -17617,7 +18653,7 @@ async function readCommandsFromDir(commandsDir, source, scope) {
|
|
|
17617
18653
|
return results;
|
|
17618
18654
|
}
|
|
17619
18655
|
async function readSettings2(settingsPath) {
|
|
17620
|
-
if (!
|
|
18656
|
+
if (!existsSync5(settingsPath))
|
|
17621
18657
|
return {};
|
|
17622
18658
|
try {
|
|
17623
18659
|
const raw = await readFile2(settingsPath, "utf-8");
|
|
@@ -17627,7 +18663,7 @@ async function readSettings2(settingsPath) {
|
|
|
17627
18663
|
}
|
|
17628
18664
|
}
|
|
17629
18665
|
async function readInstalledPlugins(pluginsFile) {
|
|
17630
|
-
if (!
|
|
18666
|
+
if (!existsSync5(pluginsFile))
|
|
17631
18667
|
return {};
|
|
17632
18668
|
try {
|
|
17633
18669
|
const raw = await readFile2(pluginsFile, "utf-8");
|
|
@@ -17638,17 +18674,17 @@ async function readInstalledPlugins(pluginsFile) {
|
|
|
17638
18674
|
}
|
|
17639
18675
|
}
|
|
17640
18676
|
async function listCommands(options) {
|
|
17641
|
-
const projectPath =
|
|
17642
|
-
const userClaudeDir = options._userClaudeDir ??
|
|
17643
|
-
const pluginsFile = options._pluginsFile ??
|
|
18677
|
+
const projectPath = resolve4(options.projectPath ?? process.cwd());
|
|
18678
|
+
const userClaudeDir = options._userClaudeDir ?? join4(homedir4(), ".claude");
|
|
18679
|
+
const pluginsFile = options._pluginsFile ?? join4(homedir4(), ".claude", "plugins", "installed_plugins.json");
|
|
17644
18680
|
const results = [];
|
|
17645
18681
|
const userSkills = await readSkillsFromDir(userClaudeDir, "standalone", "user");
|
|
17646
18682
|
results.push(...userSkills);
|
|
17647
|
-
const projectClaudeDir =
|
|
18683
|
+
const projectClaudeDir = join4(projectPath, ".claude");
|
|
17648
18684
|
const projectSkills = await readSkillsFromDir(projectClaudeDir, "standalone", "project");
|
|
17649
18685
|
results.push(...projectSkills);
|
|
17650
|
-
const userSettings = await readSettings2(
|
|
17651
|
-
const projectSettings = await readSettings2(
|
|
18686
|
+
const userSettings = await readSettings2(join4(userClaudeDir, "settings.json"));
|
|
18687
|
+
const projectSettings = await readSettings2(join4(projectClaudeDir, "settings.json"));
|
|
17652
18688
|
const userEnabled = userSettings.enabledPlugins ?? {};
|
|
17653
18689
|
const projectEnabled = projectSettings.enabledPlugins ?? {};
|
|
17654
18690
|
const enabledPlugins = new Map;
|
|
@@ -17666,7 +18702,7 @@ async function listCommands(options) {
|
|
|
17666
18702
|
continue;
|
|
17667
18703
|
const { installPath } = installations[0];
|
|
17668
18704
|
const source = `plugin:${scopeName}`;
|
|
17669
|
-
const pluginCommands = await readCommandsFromDir(
|
|
18705
|
+
const pluginCommands = await readCommandsFromDir(join4(installPath, "commands"), source, pluginScope);
|
|
17670
18706
|
results.push(...pluginCommands);
|
|
17671
18707
|
const pluginSkills = await readSkillsFromDir(installPath, source, pluginScope);
|
|
17672
18708
|
results.push(...pluginSkills);
|
|
@@ -17674,7 +18710,7 @@ async function listCommands(options) {
|
|
|
17674
18710
|
}
|
|
17675
18711
|
return results;
|
|
17676
18712
|
}
|
|
17677
|
-
var
|
|
18713
|
+
var init_usecase14 = () => {};
|
|
17678
18714
|
|
|
17679
18715
|
// src/commands/list-commands/command.ts
|
|
17680
18716
|
var exports_command17 = {};
|
|
@@ -17684,7 +18720,7 @@ __export(exports_command17, {
|
|
|
17684
18720
|
var command_default17;
|
|
17685
18721
|
var init_command17 = __esm(() => {
|
|
17686
18722
|
init_dist();
|
|
17687
|
-
|
|
18723
|
+
init_usecase14();
|
|
17688
18724
|
init_output();
|
|
17689
18725
|
command_default17 = defineCommand({
|
|
17690
18726
|
meta: {
|
|
@@ -17718,8 +18754,8 @@ async function sendCommands(client, input) {
|
|
|
17718
18754
|
await client.sendCommands(input.roomId, payload);
|
|
17719
18755
|
ok("Commands sent");
|
|
17720
18756
|
}
|
|
17721
|
-
var
|
|
17722
|
-
|
|
18757
|
+
var init_usecase15 = __esm(() => {
|
|
18758
|
+
init_usecase14();
|
|
17723
18759
|
init_output();
|
|
17724
18760
|
});
|
|
17725
18761
|
|
|
@@ -17731,8 +18767,8 @@ __export(exports_command18, {
|
|
|
17731
18767
|
var command_default18;
|
|
17732
18768
|
var init_command18 = __esm(() => {
|
|
17733
18769
|
init_dist();
|
|
17734
|
-
|
|
17735
|
-
|
|
18770
|
+
init_bootstrap();
|
|
18771
|
+
init_usecase15();
|
|
17736
18772
|
init_output();
|
|
17737
18773
|
command_default18 = defineCommand({
|
|
17738
18774
|
meta: {
|
|
@@ -18123,14 +19159,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
18123
19159
|
prevActScopeDepth !== actScopeDepth - 1 && console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
|
|
18124
19160
|
actScopeDepth = prevActScopeDepth;
|
|
18125
19161
|
}
|
|
18126
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
19162
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve5, reject) {
|
|
18127
19163
|
var queue = ReactSharedInternals.actQueue;
|
|
18128
19164
|
if (queue !== null)
|
|
18129
19165
|
if (queue.length !== 0)
|
|
18130
19166
|
try {
|
|
18131
19167
|
flushActQueue(queue);
|
|
18132
19168
|
enqueueTask(function() {
|
|
18133
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
19169
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve5, reject);
|
|
18134
19170
|
});
|
|
18135
19171
|
return;
|
|
18136
19172
|
} catch (error48) {
|
|
@@ -18138,7 +19174,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
18138
19174
|
}
|
|
18139
19175
|
else
|
|
18140
19176
|
ReactSharedInternals.actQueue = null;
|
|
18141
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) :
|
|
19177
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve5(returnValue);
|
|
18142
19178
|
}
|
|
18143
19179
|
function flushActQueue(queue) {
|
|
18144
19180
|
if (!isFlushing) {
|
|
@@ -18314,14 +19350,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
18314
19350
|
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"));
|
|
18315
19351
|
});
|
|
18316
19352
|
return {
|
|
18317
|
-
then: function(
|
|
19353
|
+
then: function(resolve5, reject) {
|
|
18318
19354
|
didAwaitActCall = true;
|
|
18319
19355
|
thenable.then(function(returnValue) {
|
|
18320
19356
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
18321
19357
|
if (prevActScopeDepth === 0) {
|
|
18322
19358
|
try {
|
|
18323
19359
|
flushActQueue(queue), enqueueTask(function() {
|
|
18324
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
19360
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve5, reject);
|
|
18325
19361
|
});
|
|
18326
19362
|
} catch (error$0) {
|
|
18327
19363
|
ReactSharedInternals.thrownErrors.push(error$0);
|
|
@@ -18332,7 +19368,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
18332
19368
|
reject(_thrownError);
|
|
18333
19369
|
}
|
|
18334
19370
|
} else
|
|
18335
|
-
|
|
19371
|
+
resolve5(returnValue);
|
|
18336
19372
|
}, function(error48) {
|
|
18337
19373
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
18338
19374
|
0 < ReactSharedInternals.thrownErrors.length ? (error48 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error48)) : reject(error48);
|
|
@@ -18348,11 +19384,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
18348
19384
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
18349
19385
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
18350
19386
|
return {
|
|
18351
|
-
then: function(
|
|
19387
|
+
then: function(resolve5, reject) {
|
|
18352
19388
|
didAwaitActCall = true;
|
|
18353
19389
|
prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
18354
|
-
return recursivelyFlushAsyncActWork(returnValue$jscomp$0,
|
|
18355
|
-
})) :
|
|
19390
|
+
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve5, reject);
|
|
19391
|
+
})) : resolve5(returnValue$jscomp$0);
|
|
18356
19392
|
}
|
|
18357
19393
|
};
|
|
18358
19394
|
};
|
|
@@ -19135,14 +20171,14 @@ var require_signal_exit = __commonJS((exports, module) => {
|
|
|
19135
20171
|
import { PassThrough } from "node:stream";
|
|
19136
20172
|
var consoleMethods, originalMethods, patchConsole = (callback) => {
|
|
19137
20173
|
const stdout = new PassThrough;
|
|
19138
|
-
const
|
|
20174
|
+
const stderr2 = new PassThrough;
|
|
19139
20175
|
stdout.write = (data) => {
|
|
19140
20176
|
callback("stdout", data);
|
|
19141
20177
|
};
|
|
19142
|
-
|
|
20178
|
+
stderr2.write = (data) => {
|
|
19143
20179
|
callback("stderr", data);
|
|
19144
20180
|
};
|
|
19145
|
-
const internalConsole = new console.Console(stdout,
|
|
20181
|
+
const internalConsole = new console.Console(stdout, stderr2);
|
|
19146
20182
|
for (const method of consoleMethods) {
|
|
19147
20183
|
originalMethods[method] = console[method];
|
|
19148
20184
|
console[method] = internalConsole[method];
|
|
@@ -21339,12 +22375,12 @@ import { execFileSync as execFileSync2 } from "node:child_process";
|
|
|
21339
22375
|
import fs from "node:fs";
|
|
21340
22376
|
import tty from "node:tty";
|
|
21341
22377
|
function terminalSize() {
|
|
21342
|
-
const { env: env2, stdout, stderr } = process4;
|
|
22378
|
+
const { env: env2, stdout, stderr: stderr2 } = process4;
|
|
21343
22379
|
if (stdout?.columns && stdout?.rows) {
|
|
21344
22380
|
return create(stdout.columns, stdout.rows);
|
|
21345
22381
|
}
|
|
21346
|
-
if (
|
|
21347
|
-
return create(
|
|
22382
|
+
if (stderr2?.columns && stderr2?.rows) {
|
|
22383
|
+
return create(stderr2.columns, stderr2.rows);
|
|
21348
22384
|
}
|
|
21349
22385
|
if (env2.COLUMNS && env2.LINES) {
|
|
21350
22386
|
return create(env2.COLUMNS, env2.LINES);
|
|
@@ -23849,8 +24885,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
23849
24885
|
currentEntangledActionThenable = {
|
|
23850
24886
|
status: "pending",
|
|
23851
24887
|
value: undefined,
|
|
23852
|
-
then: function(
|
|
23853
|
-
entangledListeners.push(
|
|
24888
|
+
then: function(resolve5) {
|
|
24889
|
+
entangledListeners.push(resolve5);
|
|
23854
24890
|
}
|
|
23855
24891
|
};
|
|
23856
24892
|
}
|
|
@@ -23874,8 +24910,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
23874
24910
|
status: "pending",
|
|
23875
24911
|
value: null,
|
|
23876
24912
|
reason: null,
|
|
23877
|
-
then: function(
|
|
23878
|
-
listeners.push(
|
|
24913
|
+
then: function(resolve5) {
|
|
24914
|
+
listeners.push(resolve5);
|
|
23879
24915
|
}
|
|
23880
24916
|
};
|
|
23881
24917
|
thenable.then(function() {
|
|
@@ -27010,11 +28046,11 @@ https://react.dev/link/unsafe-component-lifecycles`, _instance, newApiName, stat
|
|
|
27010
28046
|
function updateHostContainer(current2, workInProgress2) {
|
|
27011
28047
|
if (supportsPersistence && doesRequireClone(current2, workInProgress2)) {
|
|
27012
28048
|
current2 = workInProgress2.stateNode;
|
|
27013
|
-
var
|
|
28049
|
+
var container2 = current2.containerInfo, newChildSet = createContainerChildSet();
|
|
27014
28050
|
appendAllChildrenToContainer(newChildSet, workInProgress2, false, false);
|
|
27015
28051
|
current2.pendingChildren = newChildSet;
|
|
27016
28052
|
markUpdate(workInProgress2);
|
|
27017
|
-
finalizeContainerChildren(
|
|
28053
|
+
finalizeContainerChildren(container2, newChildSet);
|
|
27018
28054
|
}
|
|
27019
28055
|
}
|
|
27020
28056
|
function updateHostComponent(current2, workInProgress2, type, newProps) {
|
|
@@ -30276,27 +31312,27 @@ Check the render method of \`` + fiberTag + "`.");
|
|
|
30276
31312
|
parentComponent = emptyContextObject;
|
|
30277
31313
|
return parentComponent;
|
|
30278
31314
|
}
|
|
30279
|
-
function updateContainerSync(element,
|
|
30280
|
-
updateContainerImpl(
|
|
31315
|
+
function updateContainerSync(element, container2, parentComponent, callback) {
|
|
31316
|
+
updateContainerImpl(container2.current, 2, element, container2, parentComponent, callback);
|
|
30281
31317
|
return 2;
|
|
30282
31318
|
}
|
|
30283
|
-
function updateContainerImpl(rootFiber, lane, element,
|
|
31319
|
+
function updateContainerImpl(rootFiber, lane, element, container2, parentComponent, callback) {
|
|
30284
31320
|
if (injectedHook && typeof injectedHook.onScheduleFiberRoot === "function")
|
|
30285
31321
|
try {
|
|
30286
|
-
injectedHook.onScheduleFiberRoot(rendererID,
|
|
31322
|
+
injectedHook.onScheduleFiberRoot(rendererID, container2, element);
|
|
30287
31323
|
} catch (err2) {
|
|
30288
31324
|
hasLoggedError || (hasLoggedError = true, console.error("React instrumentation encountered an error: %o", err2));
|
|
30289
31325
|
}
|
|
30290
31326
|
parentComponent = getContextForSubtree(parentComponent);
|
|
30291
|
-
|
|
31327
|
+
container2.context === null ? container2.context = parentComponent : container2.pendingContext = parentComponent;
|
|
30292
31328
|
isRendering && current !== null && !didWarnAboutNestedUpdates && (didWarnAboutNestedUpdates = true, console.error(`Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.
|
|
30293
31329
|
|
|
30294
31330
|
Check the render method of %s.`, getComponentNameFromFiber(current) || "Unknown"));
|
|
30295
|
-
|
|
30296
|
-
|
|
31331
|
+
container2 = createUpdate(lane);
|
|
31332
|
+
container2.payload = { element };
|
|
30297
31333
|
callback = callback === undefined ? null : callback;
|
|
30298
|
-
callback !== null && (typeof callback !== "function" && console.error("Expected the last optional `callback` argument to be a function. Instead received: %s.", callback),
|
|
30299
|
-
element = enqueueUpdate(rootFiber,
|
|
31334
|
+
callback !== null && (typeof callback !== "function" && console.error("Expected the last optional `callback` argument to be a function. Instead received: %s.", callback), container2.callback = callback);
|
|
31335
|
+
element = enqueueUpdate(rootFiber, container2, lane);
|
|
30300
31336
|
element !== null && (startUpdateTimerByLane(lane, "root.render()", null), scheduleUpdateOnFiber(element, rootFiber, lane), entangleTransitions(element, rootFiber, lane));
|
|
30301
31337
|
}
|
|
30302
31338
|
function markRetryLaneImpl(fiber, retryLane) {
|
|
@@ -32056,16 +33092,16 @@ No matching component was found for:
|
|
|
32056
33092
|
}
|
|
32057
33093
|
return null;
|
|
32058
33094
|
};
|
|
32059
|
-
exports2.getPublicRootInstance = function(
|
|
32060
|
-
|
|
32061
|
-
if (!
|
|
33095
|
+
exports2.getPublicRootInstance = function(container2) {
|
|
33096
|
+
container2 = container2.current;
|
|
33097
|
+
if (!container2.child)
|
|
32062
33098
|
return null;
|
|
32063
|
-
switch (
|
|
33099
|
+
switch (container2.child.tag) {
|
|
32064
33100
|
case 27:
|
|
32065
33101
|
case 5:
|
|
32066
|
-
return getPublicInstance(
|
|
33102
|
+
return getPublicInstance(container2.child.stateNode);
|
|
32067
33103
|
default:
|
|
32068
|
-
return
|
|
33104
|
+
return container2.child.stateNode;
|
|
32069
33105
|
}
|
|
32070
33106
|
};
|
|
32071
33107
|
exports2.injectIntoDevTools = function() {
|
|
@@ -32137,9 +33173,9 @@ No matching component was found for:
|
|
|
32137
33173
|
return action(formData);
|
|
32138
33174
|
});
|
|
32139
33175
|
};
|
|
32140
|
-
exports2.updateContainer = function(element,
|
|
32141
|
-
var current2 =
|
|
32142
|
-
updateContainerImpl(current2, lane, element,
|
|
33176
|
+
exports2.updateContainer = function(element, container2, parentComponent, callback) {
|
|
33177
|
+
var current2 = container2.current, lane = requestUpdateLane(current2);
|
|
33178
|
+
updateContainerImpl(current2, lane, element, container2, parentComponent, callback);
|
|
32143
33179
|
return lane;
|
|
32144
33180
|
};
|
|
32145
33181
|
exports2.updateContainerSync = updateContainerSync;
|
|
@@ -36562,7 +37598,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
36562
37598
|
socket.on("error", socketOnError);
|
|
36563
37599
|
const key = req.headers["sec-websocket-key"];
|
|
36564
37600
|
const upgrade = req.headers.upgrade;
|
|
36565
|
-
const
|
|
37601
|
+
const version3 = +req.headers["sec-websocket-version"];
|
|
36566
37602
|
if (req.method !== "GET") {
|
|
36567
37603
|
const message = "Invalid HTTP method";
|
|
36568
37604
|
abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);
|
|
@@ -36578,7 +37614,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
36578
37614
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
36579
37615
|
return;
|
|
36580
37616
|
}
|
|
36581
|
-
if (
|
|
37617
|
+
if (version3 !== 13 && version3 !== 8) {
|
|
36582
37618
|
const message = "Missing or invalid Sec-WebSocket-Version header";
|
|
36583
37619
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
|
|
36584
37620
|
"Sec-WebSocket-Version": "13, 8"
|
|
@@ -36618,7 +37654,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
36618
37654
|
}
|
|
36619
37655
|
if (this.options.verifyClient) {
|
|
36620
37656
|
const info2 = {
|
|
36621
|
-
origin: req.headers[`${
|
|
37657
|
+
origin: req.headers[`${version3 === 8 ? "sec-websocket-origin" : "origin"}`],
|
|
36622
37658
|
secure: !!(req.socket.authorized || req.socket.encrypted),
|
|
36623
37659
|
req
|
|
36624
37660
|
};
|
|
@@ -39453,20 +40489,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
39453
40489
|
}
|
|
39454
40490
|
return 0;
|
|
39455
40491
|
};
|
|
39456
|
-
var validate2 = function validate3(
|
|
39457
|
-
return typeof
|
|
40492
|
+
var validate2 = function validate3(version3) {
|
|
40493
|
+
return typeof version3 === "string" && /^[v\d]/.test(version3) && semver.test(version3);
|
|
39458
40494
|
};
|
|
39459
40495
|
var compare = function compare2(v1, v2, operator) {
|
|
39460
40496
|
assertValidOperator(operator);
|
|
39461
40497
|
var res = compareVersions(v1, v2);
|
|
39462
40498
|
return operatorResMap[operator].includes(res);
|
|
39463
40499
|
};
|
|
39464
|
-
var satisfies = function satisfies2(
|
|
40500
|
+
var satisfies = function satisfies2(version3, range) {
|
|
39465
40501
|
var m = range.match(/^([<>=~^]+)/);
|
|
39466
40502
|
var op = m ? m[1] : "=";
|
|
39467
40503
|
if (op !== "^" && op !== "~")
|
|
39468
|
-
return compare(
|
|
39469
|
-
var _validateAndParse = validateAndParse(
|
|
40504
|
+
return compare(version3, range, op);
|
|
40505
|
+
var _validateAndParse = validateAndParse(version3), _validateAndParse2 = _slicedToArray(_validateAndParse, 5), v1 = _validateAndParse2[0], v2 = _validateAndParse2[1], v3 = _validateAndParse2[2], vp = _validateAndParse2[4];
|
|
39470
40506
|
var _validateAndParse3 = validateAndParse(range), _validateAndParse4 = _slicedToArray(_validateAndParse3, 5), r1 = _validateAndParse4[0], r2 = _validateAndParse4[1], r3 = _validateAndParse4[2], rp = _validateAndParse4[4];
|
|
39471
40507
|
var v = [v1, v2, v3];
|
|
39472
40508
|
var r = [r1, r2 !== null && r2 !== undefined ? r2 : "x", r3 !== null && r3 !== undefined ? r3 : "x"];
|
|
@@ -39489,13 +40525,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
39489
40525
|
return true;
|
|
39490
40526
|
};
|
|
39491
40527
|
var semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
|
|
39492
|
-
var validateAndParse = function validateAndParse2(
|
|
39493
|
-
if (typeof
|
|
40528
|
+
var validateAndParse = function validateAndParse2(version3) {
|
|
40529
|
+
if (typeof version3 !== "string") {
|
|
39494
40530
|
throw new TypeError("Invalid argument expected string");
|
|
39495
40531
|
}
|
|
39496
|
-
var match =
|
|
40532
|
+
var match = version3.match(semver);
|
|
39497
40533
|
if (!match) {
|
|
39498
|
-
throw new Error("Invalid argument not valid semver ('".concat(
|
|
40534
|
+
throw new Error("Invalid argument not valid semver ('".concat(version3, "' received)"));
|
|
39499
40535
|
}
|
|
39500
40536
|
match.shift();
|
|
39501
40537
|
return match;
|
|
@@ -41129,11 +42165,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41129
42165
|
return obj;
|
|
41130
42166
|
}
|
|
41131
42167
|
var FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER = "999.9.9";
|
|
41132
|
-
function hasAssignedBackend(
|
|
41133
|
-
if (
|
|
42168
|
+
function hasAssignedBackend(version3) {
|
|
42169
|
+
if (version3 == null || version3 === "") {
|
|
41134
42170
|
return false;
|
|
41135
42171
|
}
|
|
41136
|
-
return gte(
|
|
42172
|
+
return gte(version3, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
|
|
41137
42173
|
}
|
|
41138
42174
|
function cleanForBridge(data, isPathAllowed) {
|
|
41139
42175
|
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
@@ -41612,7 +42648,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41612
42648
|
}
|
|
41613
42649
|
var Overlay_assign = Object.assign;
|
|
41614
42650
|
var OverlayRect = /* @__PURE__ */ function() {
|
|
41615
|
-
function OverlayRect2(doc2,
|
|
42651
|
+
function OverlayRect2(doc2, container2) {
|
|
41616
42652
|
Overlay_classCallCheck(this, OverlayRect2);
|
|
41617
42653
|
this.node = doc2.createElement("div");
|
|
41618
42654
|
this.border = doc2.createElement("div");
|
|
@@ -41630,7 +42666,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41630
42666
|
this.node.appendChild(this.border);
|
|
41631
42667
|
this.border.appendChild(this.padding);
|
|
41632
42668
|
this.padding.appendChild(this.content);
|
|
41633
|
-
|
|
42669
|
+
container2.appendChild(this.node);
|
|
41634
42670
|
}
|
|
41635
42671
|
return Overlay_createClass(OverlayRect2, [{
|
|
41636
42672
|
key: "remove",
|
|
@@ -41657,7 +42693,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41657
42693
|
}]);
|
|
41658
42694
|
}();
|
|
41659
42695
|
var OverlayTip = /* @__PURE__ */ function() {
|
|
41660
|
-
function OverlayTip2(doc2,
|
|
42696
|
+
function OverlayTip2(doc2, container2) {
|
|
41661
42697
|
Overlay_classCallCheck(this, OverlayTip2);
|
|
41662
42698
|
this.tip = doc2.createElement("div");
|
|
41663
42699
|
Overlay_assign(this.tip.style, {
|
|
@@ -41687,7 +42723,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41687
42723
|
color: "#d7d7d7"
|
|
41688
42724
|
});
|
|
41689
42725
|
this.tip.style.zIndex = "10000000";
|
|
41690
|
-
|
|
42726
|
+
container2.appendChild(this.tip);
|
|
41691
42727
|
}
|
|
41692
42728
|
return Overlay_createClass(OverlayTip2, [{
|
|
41693
42729
|
key: "remove",
|
|
@@ -42789,9 +43825,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
42789
43825
|
}
|
|
42790
43826
|
});
|
|
42791
43827
|
agent_defineProperty(_this2, "getBackendVersion", function() {
|
|
42792
|
-
var
|
|
42793
|
-
if (
|
|
42794
|
-
_this2._bridge.send("backendVersion",
|
|
43828
|
+
var version3 = "6.1.5-5d87cd2244";
|
|
43829
|
+
if (version3) {
|
|
43830
|
+
_this2._bridge.send("backendVersion", version3);
|
|
42795
43831
|
}
|
|
42796
43832
|
});
|
|
42797
43833
|
agent_defineProperty(_this2, "getBridgeProtocol", function() {
|
|
@@ -45319,7 +46355,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45319
46355
|
} : function() {
|
|
45320
46356
|
return Date.now();
|
|
45321
46357
|
};
|
|
45322
|
-
function getInternalReactConstants(
|
|
46358
|
+
function getInternalReactConstants(version3) {
|
|
45323
46359
|
var ReactPriorityLevels = {
|
|
45324
46360
|
ImmediatePriority: 99,
|
|
45325
46361
|
UserBlockingPriority: 98,
|
|
@@ -45328,7 +46364,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45328
46364
|
IdlePriority: 95,
|
|
45329
46365
|
NoPriority: 90
|
|
45330
46366
|
};
|
|
45331
|
-
if (gt(
|
|
46367
|
+
if (gt(version3, "17.0.2")) {
|
|
45332
46368
|
ReactPriorityLevels = {
|
|
45333
46369
|
ImmediatePriority: 1,
|
|
45334
46370
|
UserBlockingPriority: 2,
|
|
@@ -45339,15 +46375,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45339
46375
|
};
|
|
45340
46376
|
}
|
|
45341
46377
|
var StrictModeBits = 0;
|
|
45342
|
-
if (gte(
|
|
46378
|
+
if (gte(version3, "18.0.0-alpha")) {
|
|
45343
46379
|
StrictModeBits = 24;
|
|
45344
|
-
} else if (gte(
|
|
46380
|
+
} else if (gte(version3, "16.9.0")) {
|
|
45345
46381
|
StrictModeBits = 1;
|
|
45346
|
-
} else if (gte(
|
|
46382
|
+
} else if (gte(version3, "16.3.0")) {
|
|
45347
46383
|
StrictModeBits = 2;
|
|
45348
46384
|
}
|
|
45349
46385
|
var ReactTypeOfWork = null;
|
|
45350
|
-
if (gt(
|
|
46386
|
+
if (gt(version3, "17.0.1")) {
|
|
45351
46387
|
ReactTypeOfWork = {
|
|
45352
46388
|
CacheComponent: 24,
|
|
45353
46389
|
ClassComponent: 1,
|
|
@@ -45384,7 +46420,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45384
46420
|
ViewTransitionComponent: 30,
|
|
45385
46421
|
ActivityComponent: 31
|
|
45386
46422
|
};
|
|
45387
|
-
} else if (gte(
|
|
46423
|
+
} else if (gte(version3, "17.0.0-alpha")) {
|
|
45388
46424
|
ReactTypeOfWork = {
|
|
45389
46425
|
CacheComponent: -1,
|
|
45390
46426
|
ClassComponent: 1,
|
|
@@ -45421,7 +46457,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45421
46457
|
ViewTransitionComponent: -1,
|
|
45422
46458
|
ActivityComponent: -1
|
|
45423
46459
|
};
|
|
45424
|
-
} else if (gte(
|
|
46460
|
+
} else if (gte(version3, "16.6.0-beta.0")) {
|
|
45425
46461
|
ReactTypeOfWork = {
|
|
45426
46462
|
CacheComponent: -1,
|
|
45427
46463
|
ClassComponent: 1,
|
|
@@ -45458,7 +46494,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45458
46494
|
ViewTransitionComponent: -1,
|
|
45459
46495
|
ActivityComponent: -1
|
|
45460
46496
|
};
|
|
45461
|
-
} else if (gte(
|
|
46497
|
+
} else if (gte(version3, "16.4.3-alpha")) {
|
|
45462
46498
|
ReactTypeOfWork = {
|
|
45463
46499
|
CacheComponent: -1,
|
|
45464
46500
|
ClassComponent: 2,
|
|
@@ -45744,8 +46780,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45744
46780
|
}
|
|
45745
46781
|
}
|
|
45746
46782
|
function renderer_attach(hook, rendererID, renderer, global2, shouldStartProfilingNow, profilingSettings) {
|
|
45747
|
-
var
|
|
45748
|
-
var _getInternalReactCons = getInternalReactConstants(
|
|
46783
|
+
var version3 = renderer.reconcilerVersion || renderer.version;
|
|
46784
|
+
var _getInternalReactCons = getInternalReactConstants(version3), getDisplayNameForFiber = _getInternalReactCons.getDisplayNameForFiber, getTypeSymbol = _getInternalReactCons.getTypeSymbol, ReactPriorityLevels = _getInternalReactCons.ReactPriorityLevels, ReactTypeOfWork = _getInternalReactCons.ReactTypeOfWork, StrictModeBits = _getInternalReactCons.StrictModeBits;
|
|
45749
46785
|
var { ActivityComponent, CacheComponent, ClassComponent, ContextConsumer, DehydratedSuspenseComponent, ForwardRef, Fragment, FunctionComponent, HostRoot, HostHoistable, HostSingleton, HostPortal, HostComponent, HostText, IncompleteClassComponent, IncompleteFunctionComponent, IndeterminateComponent, LegacyHiddenComponent, MemoComponent, OffscreenComponent, SimpleMemoComponent, SuspenseComponent, SuspenseListComponent, TracingMarkerComponent, Throw, ViewTransitionComponent } = ReactTypeOfWork;
|
|
45750
46786
|
var { ImmediatePriority, UserBlockingPriority, NormalPriority, LowPriority, IdlePriority, NoPriority } = ReactPriorityLevels;
|
|
45751
46787
|
var { getLaneLabelMap, injectProfilingHooks, overrideHookState, overrideHookStateDeletePath, overrideHookStateRenamePath, overrideProps, overridePropsDeletePath, overridePropsRenamePath, scheduleRefresh, setErrorHandler, setSuspenseHandler, scheduleUpdate, getCurrentFiber } = renderer;
|
|
@@ -45771,7 +46807,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
45771
46807
|
getLaneLabelMap,
|
|
45772
46808
|
currentDispatcherRef: getDispatcherRef(renderer),
|
|
45773
46809
|
workTagMap: ReactTypeOfWork,
|
|
45774
|
-
reactVersion:
|
|
46810
|
+
reactVersion: version3
|
|
45775
46811
|
});
|
|
45776
46812
|
injectProfilingHooks(response.profilingHooks);
|
|
45777
46813
|
getTimelineData = response.getTimelineData;
|
|
@@ -49650,8 +50686,8 @@ The error thrown in the component is:
|
|
|
49650
50686
|
getEnvironmentNames
|
|
49651
50687
|
};
|
|
49652
50688
|
}
|
|
49653
|
-
function isMatchingRender(
|
|
49654
|
-
return !hasAssignedBackend(
|
|
50689
|
+
function isMatchingRender(version3) {
|
|
50690
|
+
return !hasAssignedBackend(version3);
|
|
49655
50691
|
}
|
|
49656
50692
|
function attachRenderer(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings) {
|
|
49657
50693
|
if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
|
|
@@ -50665,7 +51701,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
50665
51701
|
ws.onmessage = handleMessage;
|
|
50666
51702
|
ws.onopen = function() {
|
|
50667
51703
|
bridge = new src_bridge({
|
|
50668
|
-
listen: function
|
|
51704
|
+
listen: function listen(fn) {
|
|
50669
51705
|
messageListeners.push(fn);
|
|
50670
51706
|
return function() {
|
|
50671
51707
|
var index = messageListeners.indexOf(fn);
|
|
@@ -50798,7 +51834,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
50798
51834
|
return;
|
|
50799
51835
|
}
|
|
50800
51836
|
var wall = {
|
|
50801
|
-
listen: function
|
|
51837
|
+
listen: function listen(fn) {
|
|
50802
51838
|
onSubscribe(fn);
|
|
50803
51839
|
return function() {
|
|
50804
51840
|
onUnsubscribe(fn);
|
|
@@ -51504,10 +52540,10 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
51504
52540
|
return 3;
|
|
51505
52541
|
}
|
|
51506
52542
|
if ("TERM_PROGRAM" in env2) {
|
|
51507
|
-
const
|
|
52543
|
+
const version3 = Number.parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
51508
52544
|
switch (env2.TERM_PROGRAM) {
|
|
51509
52545
|
case "iTerm.app": {
|
|
51510
|
-
return
|
|
52546
|
+
return version3 >= 3 ? 3 : 2;
|
|
51511
52547
|
}
|
|
51512
52548
|
case "Apple_Terminal": {
|
|
51513
52549
|
return 2;
|
|
@@ -53554,7 +54590,7 @@ var init_ErrorBoundary = __esm(() => {
|
|
|
53554
54590
|
// ../../node_modules/.bun/ink@6.8.0+b7580ee3b5d80903/node_modules/ink/build/components/App.js
|
|
53555
54591
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
53556
54592
|
import process12 from "node:process";
|
|
53557
|
-
function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, exitOnCtrlC, onExit, setCursorPosition }) {
|
|
54593
|
+
function App({ children, stdin, stdout, stderr: stderr2, writeToStdout, writeToStderr, exitOnCtrlC, onExit, setCursorPosition }) {
|
|
53558
54594
|
const [isFocusEnabled, setIsFocusEnabled] = import_react14.useState(true);
|
|
53559
54595
|
const [activeFocusId, setActiveFocusId] = import_react14.useState(undefined);
|
|
53560
54596
|
const [, setFocusables] = import_react14.useState([]);
|
|
@@ -53826,9 +54862,9 @@ Read about how to prevent this error on https://github.com/vadimdemedes/ink/#isr
|
|
|
53826
54862
|
write: writeToStdout
|
|
53827
54863
|
}), [stdout, writeToStdout]);
|
|
53828
54864
|
const stderrContextValue = import_react14.useMemo(() => ({
|
|
53829
|
-
stderr,
|
|
54865
|
+
stderr: stderr2,
|
|
53830
54866
|
write: writeToStderr
|
|
53831
|
-
}), [
|
|
54867
|
+
}), [stderr2, writeToStderr]);
|
|
53832
54868
|
const cursorContextValue = import_react14.useMemo(() => ({
|
|
53833
54869
|
setCursorPosition
|
|
53834
54870
|
}), [setCursorPosition]);
|
|
@@ -54282,8 +55318,8 @@ class Ink {
|
|
|
54282
55318
|
}
|
|
54283
55319
|
}
|
|
54284
55320
|
async waitUntilExit() {
|
|
54285
|
-
this.exitPromise ||= new Promise((
|
|
54286
|
-
this.resolveExitPromise =
|
|
55321
|
+
this.exitPromise ||= new Promise((resolve5, reject) => {
|
|
55322
|
+
this.resolveExitPromise = resolve5;
|
|
54287
55323
|
this.rejectExitPromise = reject;
|
|
54288
55324
|
});
|
|
54289
55325
|
if (!this.beforeExitHandler) {
|
|
@@ -55119,13 +56155,88 @@ var init_build2 = __esm(async () => {
|
|
|
55119
56155
|
]);
|
|
55120
56156
|
});
|
|
55121
56157
|
|
|
56158
|
+
// src/spawner.ts
|
|
56159
|
+
import { execSync } from "node:child_process";
|
|
56160
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
56161
|
+
import { homedir as homedir5, platform as platform2 } from "node:os";
|
|
56162
|
+
import { join as join5 } from "node:path";
|
|
56163
|
+
function findBinary(binaryName, envVarName, commonPaths) {
|
|
56164
|
+
try {
|
|
56165
|
+
const command = platform2() === "win32" ? `where ${binaryName}` : `which ${binaryName}`;
|
|
56166
|
+
const result = execSync(command, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
|
|
56167
|
+
const binaryPath = result.split(`
|
|
56168
|
+
`)[0].trim();
|
|
56169
|
+
if (binaryPath && existsSync7(binaryPath)) {
|
|
56170
|
+
return binaryPath;
|
|
56171
|
+
}
|
|
56172
|
+
} catch {}
|
|
56173
|
+
const envPath = process.env[envVarName];
|
|
56174
|
+
if (envPath && existsSync7(envPath)) {
|
|
56175
|
+
return envPath;
|
|
56176
|
+
}
|
|
56177
|
+
for (const path of commonPaths) {
|
|
56178
|
+
if (existsSync7(path)) {
|
|
56179
|
+
return path;
|
|
56180
|
+
}
|
|
56181
|
+
}
|
|
56182
|
+
throw new Error(`${binaryName} is not installed`);
|
|
56183
|
+
}
|
|
56184
|
+
function findClaudeCli() {
|
|
56185
|
+
const home = homedir5();
|
|
56186
|
+
try {
|
|
56187
|
+
return findBinary("claude", "MEET_AI_CLAUDE_PATH", [
|
|
56188
|
+
join5(home, ".bun", "bin", "claude"),
|
|
56189
|
+
"/opt/homebrew/bin/claude",
|
|
56190
|
+
"/usr/local/bin/claude",
|
|
56191
|
+
join5(home, ".local", "bin", "claude")
|
|
56192
|
+
]);
|
|
56193
|
+
} catch {
|
|
56194
|
+
throw new Error(`
|
|
56195
|
+
Claude Code is not installed
|
|
56196
|
+
|
|
56197
|
+
Please install Claude Code:
|
|
56198
|
+
bun add -g @anthropic-ai/claude-code
|
|
56199
|
+
|
|
56200
|
+
Or set MEET_AI_CLAUDE_PATH to the Claude Code CLI path.
|
|
56201
|
+
`.trim());
|
|
56202
|
+
}
|
|
56203
|
+
}
|
|
56204
|
+
function findCodexCli() {
|
|
56205
|
+
const home = homedir5();
|
|
56206
|
+
try {
|
|
56207
|
+
return findBinary("codex", "MEET_AI_CODEX_PATH", [
|
|
56208
|
+
join5(home, ".bun", "bin", "codex"),
|
|
56209
|
+
"/opt/homebrew/bin/codex",
|
|
56210
|
+
"/usr/local/bin/codex",
|
|
56211
|
+
join5(home, ".local", "bin", "codex")
|
|
56212
|
+
]);
|
|
56213
|
+
} catch {
|
|
56214
|
+
throw new Error(`
|
|
56215
|
+
Codex CLI is not installed
|
|
56216
|
+
|
|
56217
|
+
Please install Codex:
|
|
56218
|
+
npm install -g @openai/codex
|
|
56219
|
+
|
|
56220
|
+
Or set MEET_AI_CODEX_PATH to the Codex CLI path.
|
|
56221
|
+
`.trim());
|
|
56222
|
+
}
|
|
56223
|
+
}
|
|
56224
|
+
var init_spawner = () => {};
|
|
56225
|
+
|
|
55122
56226
|
// src/lib/process-manager.ts
|
|
55123
|
-
import {
|
|
55124
|
-
import { homedir as
|
|
55125
|
-
import {
|
|
56227
|
+
import { existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync3, readFileSync as readFileSync7, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
56228
|
+
import { homedir as homedir6 } from "node:os";
|
|
56229
|
+
import { fileURLToPath } from "node:url";
|
|
56230
|
+
import { join as join6 } from "node:path";
|
|
56231
|
+
function getRegistryDir() {
|
|
56232
|
+
return join6(process.env.HOME ?? homedir6(), ".meet-ai");
|
|
56233
|
+
}
|
|
56234
|
+
function getRegistryPath() {
|
|
56235
|
+
return join6(getRegistryDir(), "sessions.json");
|
|
56236
|
+
}
|
|
55126
56237
|
function readRegistry() {
|
|
55127
56238
|
try {
|
|
55128
|
-
const data =
|
|
56239
|
+
const data = readFileSync7(getRegistryPath(), "utf8");
|
|
55129
56240
|
const parsed = exports_external.array(SessionEntrySchema).safeParse(JSON.parse(data));
|
|
55130
56241
|
return parsed.success ? parsed.data : [];
|
|
55131
56242
|
} catch {
|
|
@@ -55133,17 +56244,18 @@ function readRegistry() {
|
|
|
55133
56244
|
}
|
|
55134
56245
|
}
|
|
55135
56246
|
function writeRegistry(entries) {
|
|
55136
|
-
|
|
56247
|
+
const registryDir = getRegistryDir();
|
|
56248
|
+
mkdirSync3(registryDir, { recursive: true, mode: 448 });
|
|
55137
56249
|
try {
|
|
55138
|
-
const stat = lstatSync(
|
|
56250
|
+
const stat = lstatSync(registryDir);
|
|
55139
56251
|
if (!stat.isDirectory())
|
|
55140
56252
|
return;
|
|
55141
56253
|
} catch {
|
|
55142
56254
|
return;
|
|
55143
56255
|
}
|
|
55144
|
-
const tmpPath =
|
|
55145
|
-
|
|
55146
|
-
renameSync(tmpPath,
|
|
56256
|
+
const tmpPath = join6(registryDir, `sessions.${process.pid}.${Date.now()}.tmp`);
|
|
56257
|
+
writeFileSync5(tmpPath, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
56258
|
+
renameSync(tmpPath, getRegistryPath());
|
|
55147
56259
|
}
|
|
55148
56260
|
function addToRegistry(entry) {
|
|
55149
56261
|
const entries = readRegistry();
|
|
@@ -55158,6 +56270,17 @@ function removeFromRegistry(sessionName) {
|
|
|
55158
56270
|
const entries = readRegistry().filter((e) => e.sessionName !== sessionName);
|
|
55159
56271
|
writeRegistry(entries);
|
|
55160
56272
|
}
|
|
56273
|
+
function resolveSelfCliCommand() {
|
|
56274
|
+
const sourceEntry = fileURLToPath(new URL("../index.ts", import.meta.url));
|
|
56275
|
+
if (existsSync8(sourceEntry) && typeof Bun !== "undefined") {
|
|
56276
|
+
return [process.execPath, "run", sourceEntry];
|
|
56277
|
+
}
|
|
56278
|
+
const builtEntry = fileURLToPath(new URL("../index.js", import.meta.url));
|
|
56279
|
+
if (existsSync8(builtEntry)) {
|
|
56280
|
+
return [process.execPath, builtEntry];
|
|
56281
|
+
}
|
|
56282
|
+
return ["meet-ai"];
|
|
56283
|
+
}
|
|
55161
56284
|
|
|
55162
56285
|
class ProcessManager {
|
|
55163
56286
|
teams = new Map;
|
|
@@ -55171,11 +56294,12 @@ class ProcessManager {
|
|
|
55171
56294
|
sessionName(roomId) {
|
|
55172
56295
|
return `mai-${roomId}`;
|
|
55173
56296
|
}
|
|
55174
|
-
spawn(roomId, roomName) {
|
|
56297
|
+
spawn(roomId, roomName, codingAgent = "claude") {
|
|
55175
56298
|
const sessionName = this.sessionName(roomId);
|
|
55176
56299
|
const team = {
|
|
55177
56300
|
roomId,
|
|
55178
56301
|
roomName,
|
|
56302
|
+
codingAgent,
|
|
55179
56303
|
sessionName,
|
|
55180
56304
|
status: "starting",
|
|
55181
56305
|
exitCode: null,
|
|
@@ -55186,22 +56310,24 @@ class ProcessManager {
|
|
|
55186
56310
|
this.spawned++;
|
|
55187
56311
|
if (this.opts.dryRun)
|
|
55188
56312
|
return team;
|
|
55189
|
-
const fullPrompt = [
|
|
55190
|
-
`ROOM_ID: ${roomId}`,
|
|
55191
|
-
"",
|
|
55192
|
-
"You are a team lead. IMMEDIATELY:",
|
|
55193
|
-
"1. Start agent-team to start accepting commands from Meet AI",
|
|
55194
|
-
"2. Connect to the meet-ai room using the /meet-ai skill",
|
|
55195
|
-
"3. Just send a welcome message to the room, do not perform any work yet."
|
|
55196
|
-
].join(`
|
|
56313
|
+
const fullPrompt = [`ROOM_ID: ${roomId}`, "", ...this.buildPromptLines(codingAgent)].join(`
|
|
55197
56314
|
`);
|
|
55198
|
-
const
|
|
55199
|
-
|
|
55200
|
-
"
|
|
55201
|
-
|
|
55202
|
-
|
|
55203
|
-
|
|
55204
|
-
|
|
56315
|
+
const agentBinary = this.opts.agentBinaries[codingAgent];
|
|
56316
|
+
if (!agentBinary) {
|
|
56317
|
+
team.status = "error";
|
|
56318
|
+
team.lines.push(`[error] No CLI binary configured for coding agent: ${codingAgent}`);
|
|
56319
|
+
this.opts.onStatusChange?.(roomId, "error");
|
|
56320
|
+
return team;
|
|
56321
|
+
}
|
|
56322
|
+
const commandArgs = codingAgent === "codex" ? this.buildCodexListenCommandArgs(roomId) : [agentBinary, ...this.buildClaudeCommandArgs(fullPrompt)];
|
|
56323
|
+
const sessionEnv = {
|
|
56324
|
+
DISABLE_AUTOUPDATER: "1",
|
|
56325
|
+
MEET_AI_RUNTIME: codingAgent
|
|
56326
|
+
};
|
|
56327
|
+
if (codingAgent === "codex") {
|
|
56328
|
+
sessionEnv.MEET_AI_CODEX_PATH = agentBinary;
|
|
56329
|
+
sessionEnv.MEET_AI_CODEX_BOOTSTRAP_PROMPT = fullPrompt;
|
|
56330
|
+
}
|
|
55205
56331
|
for (const key of ENV_ALLOWLIST) {
|
|
55206
56332
|
const value = process.env[key];
|
|
55207
56333
|
if (value)
|
|
@@ -55210,15 +56336,21 @@ class ProcessManager {
|
|
|
55210
56336
|
if (this.opts.env)
|
|
55211
56337
|
Object.assign(sessionEnv, this.opts.env);
|
|
55212
56338
|
if (this.opts.debug) {
|
|
55213
|
-
team.lines.push(`[debug]
|
|
56339
|
+
team.lines.push(`[debug] AGENT: ${codingAgent}`);
|
|
56340
|
+
team.lines.push(`[debug] CMD: ${commandArgs.join(" ").slice(0, 200)}`);
|
|
55214
56341
|
team.lines.push(`[debug] ENV: ${Object.keys(sessionEnv).join(", ")}`);
|
|
55215
56342
|
}
|
|
55216
|
-
const commandArgs = [this.opts.claudePath, ...claudeArgs];
|
|
55217
56343
|
const result = this.tmux.newSession(sessionName, commandArgs, sessionEnv);
|
|
55218
56344
|
if (result.ok) {
|
|
55219
56345
|
team.status = "running";
|
|
55220
56346
|
this.opts.onStatusChange?.(roomId, "running");
|
|
55221
|
-
addToRegistry({
|
|
56347
|
+
addToRegistry({
|
|
56348
|
+
sessionName,
|
|
56349
|
+
roomId,
|
|
56350
|
+
roomName,
|
|
56351
|
+
codingAgent,
|
|
56352
|
+
createdAt: new Date().toISOString()
|
|
56353
|
+
});
|
|
55222
56354
|
} else {
|
|
55223
56355
|
team.status = "error";
|
|
55224
56356
|
team.lines.push(`[error] tmux: ${result.error}`);
|
|
@@ -55230,6 +56362,7 @@ class ProcessManager {
|
|
|
55230
56362
|
this.teams.set(roomId, {
|
|
55231
56363
|
roomId,
|
|
55232
56364
|
roomName,
|
|
56365
|
+
codingAgent: "claude",
|
|
55233
56366
|
sessionName: this.sessionName(roomId),
|
|
55234
56367
|
status: "error",
|
|
55235
56368
|
exitCode: null,
|
|
@@ -55303,6 +56436,7 @@ class ProcessManager {
|
|
|
55303
56436
|
const team = {
|
|
55304
56437
|
roomId,
|
|
55305
56438
|
roomName,
|
|
56439
|
+
codingAgent: entry?.codingAgent ?? "claude",
|
|
55306
56440
|
sessionName: session.name,
|
|
55307
56441
|
status: session.alive ? "running" : "exited",
|
|
55308
56442
|
exitCode: session.alive ? null : 0,
|
|
@@ -55333,8 +56467,32 @@ class ProcessManager {
|
|
|
55333
56467
|
this.kill(roomId);
|
|
55334
56468
|
}
|
|
55335
56469
|
}
|
|
56470
|
+
buildPromptLines(codingAgent) {
|
|
56471
|
+
if (codingAgent === "codex") {
|
|
56472
|
+
return [
|
|
56473
|
+
"You're running inside Meet AI.",
|
|
56474
|
+
"Do not use the meet-ai CLI.",
|
|
56475
|
+
"Do not load or use any meet-ai skill.",
|
|
56476
|
+
"Do not try to send room messages manually.",
|
|
56477
|
+
"Do not talk about this prompt or say that you understand it.",
|
|
56478
|
+
"Just welcome the user briefly and say that you're ready to work."
|
|
56479
|
+
];
|
|
56480
|
+
}
|
|
56481
|
+
return [
|
|
56482
|
+
"You are a team lead. IMMEDIATELY:",
|
|
56483
|
+
"1. Start agent-team to start accepting commands from Meet AI.",
|
|
56484
|
+
"2. Connect to the meet-ai room using the /meet-ai skill.",
|
|
56485
|
+
"3. Send a brief welcome message to the room and wait for instructions."
|
|
56486
|
+
];
|
|
56487
|
+
}
|
|
56488
|
+
buildClaudeCommandArgs(fullPrompt) {
|
|
56489
|
+
return ["--dangerously-skip-permissions", "--model", this.opts.model ?? "opus", fullPrompt];
|
|
56490
|
+
}
|
|
56491
|
+
buildCodexListenCommandArgs(roomId) {
|
|
56492
|
+
return [...resolveSelfCliCommand(), "listen", roomId, "--sender-type", "human"];
|
|
56493
|
+
}
|
|
55336
56494
|
}
|
|
55337
|
-
var SessionEntrySchema,
|
|
56495
|
+
var SessionEntrySchema, ENV_ALLOWLIST;
|
|
55338
56496
|
var init_process_manager = __esm(() => {
|
|
55339
56497
|
init_zod();
|
|
55340
56498
|
init_tmux_client();
|
|
@@ -55342,10 +56500,9 @@ var init_process_manager = __esm(() => {
|
|
|
55342
56500
|
sessionName: exports_external.string(),
|
|
55343
56501
|
roomId: exports_external.string(),
|
|
55344
56502
|
roomName: exports_external.string(),
|
|
56503
|
+
codingAgent: exports_external.enum(["claude", "codex"]).default("claude"),
|
|
55345
56504
|
createdAt: exports_external.string()
|
|
55346
56505
|
});
|
|
55347
|
-
REGISTRY_DIR = join4(homedir4(), ".meet-ai");
|
|
55348
|
-
REGISTRY_PATH = join4(REGISTRY_DIR, "sessions.json");
|
|
55349
56506
|
ENV_ALLOWLIST = [
|
|
55350
56507
|
"HOME",
|
|
55351
56508
|
"USER",
|
|
@@ -55359,48 +56516,6 @@ var init_process_manager = __esm(() => {
|
|
|
55359
56516
|
];
|
|
55360
56517
|
});
|
|
55361
56518
|
|
|
55362
|
-
// src/spawner.ts
|
|
55363
|
-
import { execSync } from "node:child_process";
|
|
55364
|
-
import { existsSync as existsSync5 } from "node:fs";
|
|
55365
|
-
import { homedir as homedir5, platform as platform2 } from "node:os";
|
|
55366
|
-
import { join as join5 } from "node:path";
|
|
55367
|
-
function findClaudeCli() {
|
|
55368
|
-
try {
|
|
55369
|
-
const command = platform2() === "win32" ? "where claude" : "which claude";
|
|
55370
|
-
const result = execSync(command, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
|
|
55371
|
-
const claudePath = result.split(`
|
|
55372
|
-
`)[0].trim();
|
|
55373
|
-
if (claudePath && existsSync5(claudePath)) {
|
|
55374
|
-
return claudePath;
|
|
55375
|
-
}
|
|
55376
|
-
} catch {}
|
|
55377
|
-
const envPath = process.env.MEET_AI_CLAUDE_PATH;
|
|
55378
|
-
if (envPath && existsSync5(envPath)) {
|
|
55379
|
-
return envPath;
|
|
55380
|
-
}
|
|
55381
|
-
const home = homedir5();
|
|
55382
|
-
const commonPaths = [
|
|
55383
|
-
join5(home, ".bun", "bin", "claude"),
|
|
55384
|
-
"/opt/homebrew/bin/claude",
|
|
55385
|
-
"/usr/local/bin/claude",
|
|
55386
|
-
join5(home, ".local", "bin", "claude")
|
|
55387
|
-
];
|
|
55388
|
-
for (const path of commonPaths) {
|
|
55389
|
-
if (existsSync5(path)) {
|
|
55390
|
-
return path;
|
|
55391
|
-
}
|
|
55392
|
-
}
|
|
55393
|
-
throw new Error(`
|
|
55394
|
-
Claude Code is not installed
|
|
55395
|
-
|
|
55396
|
-
Please install Claude Code:
|
|
55397
|
-
bun add -g @anthropic-ai/claude-code
|
|
55398
|
-
|
|
55399
|
-
Or set MEET_AI_CLAUDE_PATH to the Claude Code CLI path.
|
|
55400
|
-
`.trim());
|
|
55401
|
-
}
|
|
55402
|
-
var init_spawner = () => {};
|
|
55403
|
-
|
|
55404
56519
|
// ../../node_modules/.bun/react@19.2.4/node_modules/react/cjs/react-jsx-dev-runtime.development.js
|
|
55405
56520
|
var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
|
|
55406
56521
|
var React11 = __toESM(require_react());
|
|
@@ -56092,16 +57207,25 @@ var init_dashboard = __esm(async () => {
|
|
|
56092
57207
|
});
|
|
56093
57208
|
|
|
56094
57209
|
// src/tui/spawn-dialog.tsx
|
|
56095
|
-
function SpawnDialog({ onSubmit, onCancel }) {
|
|
57210
|
+
function SpawnDialog({ codingAgents, onSubmit, onCancel }) {
|
|
56096
57211
|
const [roomName, setRoomName] = import_react29.useState("");
|
|
56097
57212
|
const [cursor, setCursor] = import_react29.useState(0);
|
|
57213
|
+
const [selectedAgentIndex, setSelectedAgentIndex] = import_react29.useState(0);
|
|
56098
57214
|
use_input_default((input, key) => {
|
|
56099
57215
|
if (key.escape) {
|
|
56100
57216
|
onCancel();
|
|
56101
57217
|
return;
|
|
56102
57218
|
}
|
|
56103
57219
|
if (key.return && roomName.trim()) {
|
|
56104
|
-
onSubmit(roomName.trim());
|
|
57220
|
+
onSubmit(roomName.trim(), codingAgents[selectedAgentIndex]?.id ?? "claude");
|
|
57221
|
+
return;
|
|
57222
|
+
}
|
|
57223
|
+
if (key.upArrow) {
|
|
57224
|
+
setSelectedAgentIndex((current) => Math.max(0, current - 1));
|
|
57225
|
+
return;
|
|
57226
|
+
}
|
|
57227
|
+
if (key.downArrow) {
|
|
57228
|
+
setSelectedAgentIndex((current) => Math.min(codingAgents.length - 1, current + 1));
|
|
56105
57229
|
return;
|
|
56106
57230
|
}
|
|
56107
57231
|
if (key.leftArrow) {
|
|
@@ -56119,7 +57243,7 @@ function SpawnDialog({ onSubmit, onCancel }) {
|
|
|
56119
57243
|
}
|
|
56120
57244
|
return;
|
|
56121
57245
|
}
|
|
56122
|
-
if (input && !key.ctrl && !key.meta
|
|
57246
|
+
if (input && !key.ctrl && !key.meta) {
|
|
56123
57247
|
setRoomName((v) => v.slice(0, cursor) + input + v.slice(cursor));
|
|
56124
57248
|
setCursor((c) => c + input.length);
|
|
56125
57249
|
}
|
|
@@ -56157,7 +57281,21 @@ function SpawnDialog({ onSubmit, onCancel }) {
|
|
|
56157
57281
|
children: after
|
|
56158
57282
|
}, undefined, false, undefined, this)
|
|
56159
57283
|
]
|
|
56160
|
-
}, undefined, true, undefined, this)
|
|
57284
|
+
}, undefined, true, undefined, this),
|
|
57285
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
57286
|
+
children: [
|
|
57287
|
+
"Agent:",
|
|
57288
|
+
" ",
|
|
57289
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
57290
|
+
color: "yellow",
|
|
57291
|
+
children: codingAgents[selectedAgentIndex]?.label ?? "Claude Code"
|
|
57292
|
+
}, undefined, false, undefined, this)
|
|
57293
|
+
]
|
|
57294
|
+
}, undefined, true, undefined, this),
|
|
57295
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
57296
|
+
dimColor: true,
|
|
57297
|
+
children: "Use ←/→ to edit the room name, ↑/↓ to choose the coding agent, Enter to spawn."
|
|
57298
|
+
}, undefined, false, undefined, this)
|
|
56161
57299
|
]
|
|
56162
57300
|
}, undefined, true, undefined, this);
|
|
56163
57301
|
}
|
|
@@ -56305,7 +57443,7 @@ var init_status_bar = __esm(async () => {
|
|
|
56305
57443
|
});
|
|
56306
57444
|
|
|
56307
57445
|
// src/tui/app.tsx
|
|
56308
|
-
function AppInner({ processManager, client, onAttach, onDetach }) {
|
|
57446
|
+
function AppInner({ processManager, client, codingAgents, onAttach, onDetach }) {
|
|
56309
57447
|
const { exit } = use_app_default();
|
|
56310
57448
|
const { stdout } = use_stdout_default();
|
|
56311
57449
|
const { setRawMode } = use_stdin_default();
|
|
@@ -56315,7 +57453,7 @@ function AppInner({ processManager, client, onAttach, onDetach }) {
|
|
|
56315
57453
|
const [killTargetId, setKillTargetId] = import_react30.useState(null);
|
|
56316
57454
|
const [, setRenderTick] = import_react30.useState(0);
|
|
56317
57455
|
const terminalHeight = stdout?.rows ?? 24;
|
|
56318
|
-
const bottomHeight = showSpawn ?
|
|
57456
|
+
const bottomHeight = showSpawn ? 6 : killTargetId ? 1 : 1;
|
|
56319
57457
|
const dashboardHeight = terminalHeight - bottomHeight;
|
|
56320
57458
|
const focusedRoomRef = import_react30.useRef(null);
|
|
56321
57459
|
const focusedTeam = teams[focusedIndex];
|
|
@@ -56330,10 +57468,10 @@ function AppInner({ processManager, client, onAttach, onDetach }) {
|
|
|
56330
57468
|
return [...current];
|
|
56331
57469
|
});
|
|
56332
57470
|
}, [processManager]);
|
|
56333
|
-
const handleSpawn = import_react30.useCallback(async (roomName) => {
|
|
57471
|
+
const handleSpawn = import_react30.useCallback(async (roomName, codingAgent) => {
|
|
56334
57472
|
try {
|
|
56335
57473
|
const room = await client.createRoom(roomName);
|
|
56336
|
-
processManager.spawn(room.id, roomName);
|
|
57474
|
+
processManager.spawn(room.id, roomName, codingAgent);
|
|
56337
57475
|
refreshTeams();
|
|
56338
57476
|
} catch (error48) {
|
|
56339
57477
|
const msg = error48 instanceof Error ? error48.message : String(error48);
|
|
@@ -56451,9 +57589,10 @@ function AppInner({ processManager, client, onAttach, onDetach }) {
|
|
|
56451
57589
|
}, undefined, false, undefined, this)
|
|
56452
57590
|
]
|
|
56453
57591
|
}, undefined, true, undefined, this) : showSpawn ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(SpawnDialog, {
|
|
56454
|
-
|
|
57592
|
+
codingAgents: [...codingAgents],
|
|
57593
|
+
onSubmit: (roomName, codingAgent) => {
|
|
56455
57594
|
setShowSpawn(false);
|
|
56456
|
-
handleSpawn(
|
|
57595
|
+
handleSpawn(roomName, codingAgent);
|
|
56457
57596
|
},
|
|
56458
57597
|
onCancel: () => setShowSpawn(false)
|
|
56459
57598
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(StatusBar, {
|
|
@@ -56529,9 +57668,21 @@ async function startDashboard(client, config2, options) {
|
|
|
56529
57668
|
console.error(`tmux >= 3.2 required, found ${check3.version}`);
|
|
56530
57669
|
process.exit(1);
|
|
56531
57670
|
}
|
|
56532
|
-
const
|
|
57671
|
+
const agentBinaries = {};
|
|
57672
|
+
try {
|
|
57673
|
+
agentBinaries.claude = findClaudeCli();
|
|
57674
|
+
} catch {}
|
|
57675
|
+
try {
|
|
57676
|
+
agentBinaries.codex = findCodexCli();
|
|
57677
|
+
} catch {}
|
|
57678
|
+
const availableCodingAgents = CODING_AGENT_DEFINITIONS.filter((agent) => Boolean(agentBinaries[agent.id]));
|
|
57679
|
+
if (availableCodingAgents.length === 0) {
|
|
57680
|
+
console.error("No supported coding agent CLI was found.");
|
|
57681
|
+
console.error("Install Claude Code or Codex, or set MEET_AI_CLAUDE_PATH / MEET_AI_CODEX_PATH.");
|
|
57682
|
+
process.exit(1);
|
|
57683
|
+
}
|
|
56533
57684
|
const processManager = new ProcessManager({
|
|
56534
|
-
|
|
57685
|
+
agentBinaries,
|
|
56535
57686
|
debug: options?.debug,
|
|
56536
57687
|
tmux,
|
|
56537
57688
|
env: {
|
|
@@ -56555,15 +57706,16 @@ async function startDashboard(client, config2, options) {
|
|
|
56555
57706
|
try {
|
|
56556
57707
|
lobbyWs = client.listenLobby({
|
|
56557
57708
|
silent: true,
|
|
56558
|
-
onSpawnRequest: async (roomName) => {
|
|
56559
|
-
|
|
57709
|
+
onSpawnRequest: async ({ roomName, codingAgent }) => {
|
|
57710
|
+
const key = `${roomName}:${codingAgent}`;
|
|
57711
|
+
if (pendingSpawns.has(key))
|
|
56560
57712
|
return;
|
|
56561
|
-
pendingSpawns.add(
|
|
57713
|
+
pendingSpawns.add(key);
|
|
56562
57714
|
try {
|
|
56563
57715
|
const room = await client.createRoom(roomName);
|
|
56564
|
-
processManager.spawn(room.id, roomName);
|
|
57716
|
+
processManager.spawn(room.id, roomName, codingAgent);
|
|
56565
57717
|
} finally {
|
|
56566
|
-
pendingSpawns.delete(
|
|
57718
|
+
pendingSpawns.delete(key);
|
|
56567
57719
|
}
|
|
56568
57720
|
}
|
|
56569
57721
|
});
|
|
@@ -56579,6 +57731,7 @@ async function startDashboard(client, config2, options) {
|
|
|
56579
57731
|
const element = import_react31.default.createElement(App2, {
|
|
56580
57732
|
processManager,
|
|
56581
57733
|
client,
|
|
57734
|
+
codingAgents: availableCodingAgents,
|
|
56582
57735
|
onAttach: () => {
|
|
56583
57736
|
lobbyWs?.close();
|
|
56584
57737
|
lobbyWs = null;
|
|
@@ -56592,10 +57745,11 @@ async function startDashboard(client, config2, options) {
|
|
|
56592
57745
|
cleanup();
|
|
56593
57746
|
}
|
|
56594
57747
|
var import_react31;
|
|
56595
|
-
var
|
|
57748
|
+
var init_usecase16 = __esm(async () => {
|
|
57749
|
+
init_coding_agents();
|
|
57750
|
+
init_spawner();
|
|
56596
57751
|
init_process_manager();
|
|
56597
57752
|
init_tmux_client();
|
|
56598
|
-
init_spawner();
|
|
56599
57753
|
await __promiseAll([
|
|
56600
57754
|
init_build2(),
|
|
56601
57755
|
init_app()
|
|
@@ -56605,11 +57759,15 @@ var init_usecase17 = __esm(async () => {
|
|
|
56605
57759
|
|
|
56606
57760
|
// src/index.ts
|
|
56607
57761
|
init_dist();
|
|
57762
|
+
// package.json
|
|
57763
|
+
var version = "0.0.36";
|
|
57764
|
+
|
|
57765
|
+
// src/index.ts
|
|
56608
57766
|
init_output();
|
|
56609
57767
|
var main = defineCommand({
|
|
56610
57768
|
meta: {
|
|
56611
57769
|
name: "meet-ai",
|
|
56612
|
-
version
|
|
57770
|
+
version,
|
|
56613
57771
|
description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
|
|
56614
57772
|
},
|
|
56615
57773
|
args: {
|
|
@@ -56640,9 +57798,9 @@ var main = defineCommand({
|
|
|
56640
57798
|
if (hasSubcommand)
|
|
56641
57799
|
return;
|
|
56642
57800
|
try {
|
|
56643
|
-
const { getClient: getClient2 } = await Promise.resolve().then(() => (
|
|
57801
|
+
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
56644
57802
|
const { getMeetAiConfig: getMeetAiConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
56645
|
-
const { startDashboard: startDashboard2 } = await
|
|
57803
|
+
const { startDashboard: startDashboard2 } = await init_usecase16().then(() => exports_usecase2);
|
|
56646
57804
|
const client = getClient2();
|
|
56647
57805
|
const config2 = getMeetAiConfig2();
|
|
56648
57806
|
await startDashboard2(client, config2, { debug: args.debug });
|