@meet-ai/cli 0.0.33 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +828 -548
  2. package/package.json +1 -1
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 = (version) => {
1594
- if (!version)
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}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
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 version;
2252
+ var version2;
2253
2253
  var init_versions = __esm(() => {
2254
- version = {
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 = 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: () => 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 version2 = detectVersion(schema, params?.defaultTarget);
14015
+ const version3 = detectVersion(schema, params?.defaultTarget);
14016
14016
  const defs = schema.$defs || schema.definitions || {};
14017
14017
  const ctx = {
14018
- version: version2,
14018
+ version: version3,
14019
14019
  defs,
14020
14020
  refs: new Map,
14021
14021
  processing: new Set,
@@ -14456,12 +14456,7 @@ var init_config = __esm(() => {
14456
14456
  });
14457
14457
  });
14458
14458
 
14459
- // src/client.ts
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
- }
14459
+ // src/domain/adapters/HttpTransport.ts
14465
14460
  function isRetryable(error48) {
14466
14461
  if (error48 instanceof TypeError)
14467
14462
  return true;
@@ -14493,391 +14488,751 @@ async function withRetry(fn, options) {
14493
14488
  }
14494
14489
  throw lastError;
14495
14490
  }
14496
- function cleanupOldAttachments() {
14491
+ async function parseErrorMessage(res) {
14497
14492
  try {
14498
- const { readdirSync, statSync, unlinkSync } = __require("node:fs");
14499
- const now = Date.now();
14500
- for (const entry of readdirSync(ATTACHMENTS_DIR)) {
14501
- try {
14502
- const filePath = `${ATTACHMENTS_DIR}/${entry}`;
14503
- const mtime = statSync(filePath).mtimeMs;
14504
- if (now - mtime > MAX_AGE_MS) {
14505
- unlinkSync(filePath);
14506
- }
14507
- } catch {}
14508
- }
14493
+ const err2 = await res.json();
14494
+ const msg = err2.error;
14495
+ if (typeof msg === "string")
14496
+ return msg;
14497
+ if (msg)
14498
+ return JSON.stringify(msg);
14509
14499
  } catch {}
14500
+ return `HTTP ${res.status}`;
14510
14501
  }
14511
- function createClient(baseUrl, apiKey) {
14512
- function headers(extra) {
14502
+
14503
+ class HttpTransport {
14504
+ baseUrl;
14505
+ apiKey;
14506
+ constructor(baseUrl, apiKey) {
14507
+ this.baseUrl = baseUrl;
14508
+ this.apiKey = apiKey;
14509
+ }
14510
+ headers(extra) {
14513
14511
  const h = { "Content-Type": "application/json", ...extra };
14514
- if (apiKey) {
14515
- h["Authorization"] = `Bearer ${apiKey}`;
14512
+ if (this.apiKey) {
14513
+ h["Authorization"] = `Bearer ${this.apiKey}`;
14516
14514
  }
14517
14515
  return h;
14518
14516
  }
14519
- return {
14520
- async createRoom(name) {
14521
- const res = await fetch(`${baseUrl}/api/rooms`, {
14517
+ authHeaders() {
14518
+ return this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : undefined;
14519
+ }
14520
+ buildUrl(path, query) {
14521
+ const params = new URLSearchParams;
14522
+ if (query) {
14523
+ for (const [key, value] of Object.entries(query)) {
14524
+ if (value)
14525
+ params.set(key, value);
14526
+ }
14527
+ }
14528
+ const qs = params.toString();
14529
+ return `${this.baseUrl}${path}${qs ? `?${qs}` : ""}`;
14530
+ }
14531
+ async postJson(path, body, opts) {
14532
+ const doRequest = async () => {
14533
+ const res = await fetch(this.buildUrl(path, opts?.query), {
14522
14534
  method: "POST",
14523
- headers: headers(),
14524
- body: JSON.stringify({ name })
14535
+ headers: this.headers(),
14536
+ body: body !== undefined ? JSON.stringify(body) : undefined
14525
14537
  });
14526
- if (!res.ok) {
14527
- const err2 = await res.json();
14528
- throw new Error(err2.error ?? `HTTP ${res.status}`);
14529
- }
14538
+ if (!res.ok)
14539
+ throw new Error(await parseErrorMessage(res));
14530
14540
  return res.json();
14531
- },
14532
- async sendMessage(roomId, sender, content, color) {
14533
- return withRetry(async () => {
14534
- const res = await fetch(`${baseUrl}/api/rooms/${roomId}/messages`, {
14535
- method: "POST",
14536
- headers: headers(),
14537
- body: JSON.stringify({ sender, content, sender_type: "agent", ...color && { color } })
14538
- });
14539
- if (!res.ok) {
14540
- const err2 = await res.json().catch(() => ({}));
14541
- throw new Error(err2.error ?? `HTTP ${res.status}`);
14542
- }
14543
- return res.json();
14541
+ };
14542
+ return opts?.retry ? withRetry(doRequest, opts.retry) : doRequest();
14543
+ }
14544
+ async postText(path, body, opts) {
14545
+ const doRequest = async () => {
14546
+ const res = await fetch(this.buildUrl(path, opts?.query), {
14547
+ method: "POST",
14548
+ headers: this.headers(),
14549
+ body: body !== undefined ? JSON.stringify(body) : undefined
14544
14550
  });
14545
- },
14546
- async getMessages(roomId, options) {
14547
- const params = new URLSearchParams;
14548
- if (options?.after)
14549
- params.set("after", options.after);
14550
- if (options?.exclude)
14551
- params.set("exclude", options.exclude);
14552
- if (options?.senderType)
14553
- params.set("sender_type", options.senderType);
14554
- const qs = params.toString();
14555
- const url2 = `${baseUrl}/api/rooms/${roomId}/messages${qs ? `?${qs}` : ""}`;
14556
- const res = await fetch(url2, {
14557
- headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined
14551
+ if (!res.ok)
14552
+ throw new Error(await parseErrorMessage(res));
14553
+ return res.text();
14554
+ };
14555
+ return opts?.retry ? withRetry(doRequest, opts.retry) : doRequest();
14556
+ }
14557
+ async getJson(path, opts) {
14558
+ const doRequest = async () => {
14559
+ const res = await fetch(this.buildUrl(path, opts?.query), {
14560
+ headers: this.authHeaders()
14558
14561
  });
14559
- if (!res.ok) {
14560
- const err2 = await res.json();
14561
- throw new Error(err2.error ?? `HTTP ${res.status}`);
14562
- }
14562
+ if (!res.ok)
14563
+ throw new Error(await parseErrorMessage(res));
14563
14564
  return res.json();
14564
- },
14565
- listen(roomId, options) {
14566
- const wsUrl = baseUrl.replace(/^http/, "ws");
14567
- const tokenParam = apiKey ? `?token=${apiKey}` : "";
14568
- let pingInterval = null;
14569
- let reconnectAttempt = 0;
14570
- const seen = new Set;
14571
- let lastSeenId = null;
14572
- function deliver(msg) {
14573
- if (seen.has(msg.id))
14574
- return;
14575
- seen.add(msg.id);
14576
- if (seen.size > 200) {
14577
- const first = seen.values().next().value;
14578
- seen.delete(first);
14579
- }
14580
- lastSeenId = msg.id;
14581
- if (options?.exclude && msg.sender === options.exclude)
14582
- return;
14583
- if (options?.senderType && msg.sender_type !== options.senderType)
14584
- return;
14585
- if (options?.onMessage) {
14586
- options.onMessage(msg);
14587
- } else {
14588
- console.log(JSON.stringify(msg));
14589
- }
14565
+ };
14566
+ return opts?.retry ? withRetry(doRequest, opts.retry) : doRequest();
14567
+ }
14568
+ async getRaw(path) {
14569
+ const res = await fetch(this.buildUrl(path), {
14570
+ headers: this.authHeaders()
14571
+ });
14572
+ if (!res.ok)
14573
+ throw new Error(await parseErrorMessage(res));
14574
+ return res;
14575
+ }
14576
+ async del(path) {
14577
+ const res = await fetch(this.buildUrl(path), {
14578
+ method: "DELETE",
14579
+ headers: this.headers()
14580
+ });
14581
+ if (!res.ok)
14582
+ throw new Error(await parseErrorMessage(res));
14583
+ }
14584
+ }
14585
+
14586
+ // src/domain/adapters/ConnectionAdapter.ts
14587
+ function wsLog(data) {
14588
+ const json2 = JSON.stringify({ ...data, ts: new Date().toISOString() });
14589
+ const isSuccess = data.event === "connected" || data.event === "reconnected" || data.event === "catchup";
14590
+ console.error(isSuccess ? `\x1B[32m${json2}\x1B[0m` : json2);
14591
+ }
14592
+
14593
+ class ConnectionAdapter {
14594
+ transport;
14595
+ baseUrl;
14596
+ apiKey;
14597
+ constructor(transport, baseUrl, apiKey) {
14598
+ this.transport = transport;
14599
+ this.baseUrl = baseUrl;
14600
+ this.apiKey = apiKey;
14601
+ }
14602
+ listen(roomId, options) {
14603
+ const wsUrl = this.baseUrl.replace(/^http/, "ws");
14604
+ const wsHeaders = this.apiKey ? { headers: { Authorization: `Bearer ${this.apiKey}` } } : undefined;
14605
+ let pingInterval = null;
14606
+ let reconnectAttempt = 0;
14607
+ const seen = new Set;
14608
+ let lastSeenId = null;
14609
+ const transport = this.transport;
14610
+ function deliver(msg) {
14611
+ if (seen.has(msg.id))
14612
+ return;
14613
+ seen.add(msg.id);
14614
+ if (seen.size > 200) {
14615
+ const first = seen.values().next().value;
14616
+ seen.delete(first);
14590
14617
  }
14591
- function getReconnectDelay() {
14592
- const delay = Math.min(1000 * 2 ** Math.min(reconnectAttempt, 4), 15000);
14593
- reconnectAttempt++;
14594
- return delay + delay * 0.5 * Math.random();
14618
+ lastSeenId = msg.id;
14619
+ if (options?.exclude && msg.sender === options.exclude)
14620
+ return;
14621
+ if (options?.senderType && msg.sender_type !== options.senderType)
14622
+ return;
14623
+ if (options?.onMessage) {
14624
+ options.onMessage(msg);
14625
+ } else {
14626
+ console.log(JSON.stringify(msg));
14595
14627
  }
14596
- const fetchMessages = this.getMessages.bind(this);
14597
- function connect() {
14598
- const ws = new WebSocket(`${wsUrl}/api/rooms/${roomId}/ws${tokenParam}`);
14599
- const connectTimeout = setTimeout(() => {
14600
- if (ws.readyState !== WebSocket.OPEN) {
14601
- wsLog({ event: "timeout", after_ms: 30000 });
14602
- try {
14603
- ws.close(4000, "connect timeout");
14604
- } catch {}
14605
- const delay = getReconnectDelay();
14606
- wsLog({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
14607
- setTimeout(connect, delay);
14608
- }
14609
- }, 30000);
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}`;
14628
+ }
14629
+ function getReconnectDelay() {
14630
+ const delay = Math.min(1000 * 2 ** Math.min(reconnectAttempt, 4), 15000);
14631
+ reconnectAttempt++;
14632
+ return delay + delay * 0.5 * Math.random();
14633
+ }
14634
+ function connect() {
14635
+ const ws = new WebSocket(`${wsUrl}/api/rooms/${roomId}/ws`, wsHeaders);
14636
+ const connectTimeout = setTimeout(() => {
14637
+ if (ws.readyState !== WebSocket.OPEN) {
14638
+ wsLog({ event: "timeout", after_ms: 30000 });
14639
+ try {
14640
+ ws.close(4000, "connect timeout");
14641
+ } catch {}
14655
14642
  const delay = getReconnectDelay();
14656
- wsLog({ event: "disconnected", code, reason });
14657
14643
  wsLog({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
14658
14644
  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
14645
  }
14681
- return res.json();
14682
- });
14683
- },
14684
- async sendTeamInfo(roomId, payload) {
14685
- return withRetry(async () => {
14686
- const res = await fetch(`${baseUrl}/api/rooms/${roomId}/team-info`, {
14687
- method: "POST",
14688
- headers: headers(),
14689
- body: payload
14690
- });
14691
- if (!res.ok) {
14692
- const err2 = await res.json().catch(() => ({}));
14693
- const msg = err2.error;
14694
- throw new Error(typeof msg === "string" ? msg : msg ? JSON.stringify(msg) : `HTTP ${res.status}`);
14695
- }
14696
- return res.text();
14697
- });
14698
- },
14699
- async sendCommands(roomId, payload) {
14700
- return withRetry(async () => {
14701
- const res = await fetch(`${baseUrl}/api/rooms/${roomId}/commands`, {
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}`);
14646
+ }, 30000);
14647
+ ws.onopen = async () => {
14648
+ clearTimeout(connectTimeout);
14649
+ const wasReconnect = reconnectAttempt > 0;
14650
+ reconnectAttempt = 0;
14651
+ wsLog({ event: wasReconnect ? "reconnected" : "connected" });
14652
+ if (pingInterval)
14653
+ clearInterval(pingInterval);
14654
+ pingInterval = setInterval(() => {
14655
+ if (ws.readyState === WebSocket.OPEN) {
14656
+ ws.send(JSON.stringify({ type: "ping" }));
14657
+ }
14658
+ }, 30000);
14659
+ if (lastSeenId) {
14660
+ try {
14661
+ const missed = await transport.getJson(`/api/rooms/${roomId}/messages`, { query: { after: lastSeenId } });
14662
+ if (missed.length)
14663
+ wsLog({ event: "catchup", count: missed.length });
14664
+ for (const msg of missed)
14665
+ deliver(msg);
14666
+ } catch {}
14710
14667
  }
14711
- return res.text();
14712
- });
14713
- },
14714
- async sendTasks(roomId, payload) {
14715
- return withRetry(async () => {
14716
- const res = await fetch(`${baseUrl}/api/rooms/${roomId}/tasks`, {
14717
- method: "POST",
14718
- headers: headers(),
14719
- body: payload
14720
- });
14721
- if (!res.ok) {
14722
- const err2 = await res.json().catch(() => ({}));
14723
- throw new Error(err2.error ?? `HTTP ${res.status}`);
14668
+ };
14669
+ ws.onmessage = (event) => {
14670
+ const text = typeof event.data === "string" ? event.data : new TextDecoder().decode(event.data);
14671
+ const data = JSON.parse(text);
14672
+ if (data.type === "pong")
14673
+ return;
14674
+ if (data.type === "terminal_subscribe" || data.type === "terminal_unsubscribe") {
14675
+ options?.onMessage?.(data);
14676
+ return;
14724
14677
  }
14725
- return res.text();
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)
14678
+ if (data.type === "terminal_data")
14679
+ return;
14680
+ deliver(data);
14681
+ };
14682
+ ws.onclose = (event) => {
14683
+ clearTimeout(connectTimeout);
14684
+ if (pingInterval)
14685
+ clearInterval(pingInterval);
14686
+ const code = event.code;
14687
+ if (code === 1000) {
14688
+ wsLog({ event: "closed", code: 1000 });
14770
14689
  return;
14771
- reconnectScheduled = true;
14690
+ }
14691
+ const reason = code === 1006 ? "network drop" : code === 1012 ? "service restart" : code === 1013 ? "server back-off" : `code ${code}`;
14772
14692
  const delay = getReconnectDelay();
14773
- log({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
14774
- setTimeout(() => {
14775
- reconnectScheduled = false;
14776
- connect();
14777
- }, delay);
14778
- }
14779
- function connect() {
14780
- const ws = new WebSocket(`${wsUrl}/api/lobby/ws${tokenParam}`);
14781
- const connectTimeout = setTimeout(() => {
14782
- if (ws.readyState !== WebSocket.OPEN) {
14783
- try {
14784
- ws.close(4000, "connect timeout");
14785
- } catch {}
14786
- scheduleReconnect();
14787
- }
14788
- }, 30000);
14789
- ws.onopen = () => {
14790
- clearTimeout(connectTimeout);
14791
- reconnectAttempt = 0;
14792
- log({ event: "lobby_connected" });
14793
- if (pingInterval)
14794
- clearInterval(pingInterval);
14795
- pingInterval = setInterval(() => {
14796
- if (ws.readyState === WebSocket.OPEN) {
14797
- ws.send(JSON.stringify({ type: "ping" }));
14798
- }
14799
- }, 30000);
14800
- };
14801
- ws.onmessage = (event) => {
14802
- const text = typeof event.data === "string" ? event.data : new TextDecoder().decode(event.data);
14693
+ wsLog({ event: "disconnected", code, reason });
14694
+ wsLog({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
14695
+ setTimeout(connect, delay);
14696
+ };
14697
+ ws.onerror = () => {};
14698
+ return ws;
14699
+ }
14700
+ return connect();
14701
+ }
14702
+ listenLobby(options) {
14703
+ const wsUrl = this.baseUrl.replace(/^http/, "ws");
14704
+ const wsHeaders = this.apiKey ? { headers: { Authorization: `Bearer ${this.apiKey}` } } : undefined;
14705
+ let pingInterval = null;
14706
+ let reconnectAttempt = 0;
14707
+ let reconnectScheduled = false;
14708
+ const log = options?.silent ? () => {} : wsLog;
14709
+ function getReconnectDelay() {
14710
+ const delay = Math.min(1000 * 2 ** Math.min(reconnectAttempt, 4), 15000);
14711
+ reconnectAttempt++;
14712
+ return delay + delay * 0.5 * Math.random();
14713
+ }
14714
+ function scheduleReconnect() {
14715
+ if (reconnectScheduled)
14716
+ return;
14717
+ reconnectScheduled = true;
14718
+ const delay = getReconnectDelay();
14719
+ log({ event: "reconnecting", attempt: reconnectAttempt, delay_ms: Math.round(delay) });
14720
+ setTimeout(() => {
14721
+ reconnectScheduled = false;
14722
+ connect();
14723
+ }, delay);
14724
+ }
14725
+ function connect() {
14726
+ const ws = new WebSocket(`${wsUrl}/api/lobby/ws`, wsHeaders);
14727
+ const connectTimeout = setTimeout(() => {
14728
+ if (ws.readyState !== WebSocket.OPEN) {
14803
14729
  try {
14804
- const data = JSON.parse(text);
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
- }
14730
+ ws.close(4000, "connect timeout");
14813
14731
  } catch {}
14814
- };
14815
- ws.onclose = (event) => {
14816
- clearTimeout(connectTimeout);
14817
- if (pingInterval)
14818
- clearInterval(pingInterval);
14819
- if (event.code === 1000)
14820
- return;
14821
14732
  scheduleReconnect();
14822
- };
14823
- ws.onerror = () => {};
14824
- return ws;
14733
+ }
14734
+ }, 30000);
14735
+ ws.onopen = () => {
14736
+ clearTimeout(connectTimeout);
14737
+ reconnectAttempt = 0;
14738
+ log({ event: "lobby_connected" });
14739
+ if (pingInterval)
14740
+ clearInterval(pingInterval);
14741
+ pingInterval = setInterval(() => {
14742
+ if (ws.readyState === WebSocket.OPEN) {
14743
+ ws.send(JSON.stringify({ type: "ping" }));
14744
+ }
14745
+ }, 30000);
14746
+ };
14747
+ ws.onmessage = (event) => {
14748
+ const text = typeof event.data === "string" ? event.data : new TextDecoder().decode(event.data);
14749
+ try {
14750
+ const data = JSON.parse(text);
14751
+ if (data.type === "pong")
14752
+ return;
14753
+ if (data.type === "room_created" && data.id && data.name) {
14754
+ options?.onRoomCreated?.(data.id, data.name);
14755
+ }
14756
+ if (data.type === "spawn_request" && data.room_name) {
14757
+ options?.onSpawnRequest?.(data.room_name);
14758
+ }
14759
+ } catch {}
14760
+ };
14761
+ ws.onclose = (event) => {
14762
+ clearTimeout(connectTimeout);
14763
+ if (pingInterval)
14764
+ clearInterval(pingInterval);
14765
+ if (event.code === 1000)
14766
+ return;
14767
+ scheduleReconnect();
14768
+ };
14769
+ ws.onerror = () => {};
14770
+ return ws;
14771
+ }
14772
+ return connect();
14773
+ }
14774
+ async generateKey() {
14775
+ return this.transport.postJson("/api/keys");
14776
+ }
14777
+ }
14778
+
14779
+ // src/domain/adapters/FileSystemAdapter.ts
14780
+ import {
14781
+ readFileSync as readFileSync2,
14782
+ writeFileSync,
14783
+ mkdirSync,
14784
+ existsSync as existsSync2,
14785
+ statSync
14786
+ } from "node:fs";
14787
+
14788
+ class FileSystemAdapter {
14789
+ readFileSync(path, encoding) {
14790
+ return readFileSync2(path, encoding);
14791
+ }
14792
+ writeFileSync(path, data, encoding) {
14793
+ writeFileSync(path, data, encoding);
14794
+ }
14795
+ mkdirSync(path, opts) {
14796
+ mkdirSync(path, opts);
14797
+ }
14798
+ existsSync(path) {
14799
+ return existsSync2(path);
14800
+ }
14801
+ statSync(path) {
14802
+ const stat = statSync(path);
14803
+ return { mtimeMs: stat.mtimeMs, size: stat.size };
14804
+ }
14805
+ }
14806
+ var init_FileSystemAdapter = () => {};
14807
+
14808
+ // src/domain/repositories/MessageRepository.ts
14809
+ class MessageRepository {
14810
+ transport;
14811
+ constructor(transport) {
14812
+ this.transport = transport;
14813
+ }
14814
+ async send(roomId, sender, content, color) {
14815
+ return this.transport.postJson(`/api/rooms/${roomId}/messages`, { sender, content, sender_type: "agent", ...color && { color } }, RETRY);
14816
+ }
14817
+ async list(roomId, opts) {
14818
+ const query = {};
14819
+ if (opts?.after)
14820
+ query.after = opts.after;
14821
+ if (opts?.exclude)
14822
+ query.exclude = opts.exclude;
14823
+ if (opts?.senderType)
14824
+ query.sender_type = opts.senderType;
14825
+ return this.transport.getJson(`/api/rooms/${roomId}/messages`, { query });
14826
+ }
14827
+ async sendLog(roomId, sender, content, opts) {
14828
+ return this.transport.postJson(`/api/rooms/${roomId}/logs`, {
14829
+ sender,
14830
+ content,
14831
+ ...opts?.color && { color: opts.color },
14832
+ ...opts?.messageId && { message_id: opts.messageId }
14833
+ }, RETRY);
14834
+ }
14835
+ }
14836
+ var RETRY;
14837
+ var init_MessageRepository = __esm(() => {
14838
+ RETRY = { retry: { maxRetries: 3, baseDelay: 1000 } };
14839
+ });
14840
+
14841
+ // src/domain/repositories/RoomRepository.ts
14842
+ class RoomRepository {
14843
+ transport;
14844
+ constructor(transport) {
14845
+ this.transport = transport;
14846
+ }
14847
+ async create(name) {
14848
+ return this.transport.postJson("/api/rooms", { name });
14849
+ }
14850
+ async delete(roomId) {
14851
+ return this.transport.del(`/api/rooms/${roomId}`);
14852
+ }
14853
+ async sendTeamInfo(roomId, payload) {
14854
+ return this.transport.postText(`/api/rooms/${roomId}/team-info`, JSON.parse(payload), {
14855
+ retry: RETRY2
14856
+ });
14857
+ }
14858
+ async sendCommands(roomId, payload) {
14859
+ return this.transport.postText(`/api/rooms/${roomId}/commands`, JSON.parse(payload), {
14860
+ retry: RETRY2
14861
+ });
14862
+ }
14863
+ async sendTasks(roomId, payload) {
14864
+ return this.transport.postText(`/api/rooms/${roomId}/tasks`, JSON.parse(payload), {
14865
+ retry: RETRY2
14866
+ });
14867
+ }
14868
+ async sendTerminalData(roomId, data) {
14869
+ try {
14870
+ await this.transport.postJson(`/api/rooms/${roomId}/terminal`, { data });
14871
+ } catch {}
14872
+ }
14873
+ }
14874
+ var RETRY2;
14875
+ var init_RoomRepository = __esm(() => {
14876
+ RETRY2 = { maxRetries: 3, baseDelay: 1000 };
14877
+ });
14878
+
14879
+ // src/domain/repositories/AttachmentRepository.ts
14880
+ class AttachmentRepository {
14881
+ transport;
14882
+ constructor(transport) {
14883
+ this.transport = transport;
14884
+ }
14885
+ async listForMessage(roomId, messageId) {
14886
+ return this.transport.getJson(`/api/rooms/${roomId}/messages/${messageId}/attachments`);
14887
+ }
14888
+ async download(attachmentId) {
14889
+ return this.transport.getRaw(`/api/attachments/${attachmentId}`);
14890
+ }
14891
+ }
14892
+
14893
+ // src/domain/usecases/SendMessage.ts
14894
+ class SendMessage {
14895
+ messageRepository;
14896
+ constructor(messageRepository) {
14897
+ this.messageRepository = messageRepository;
14898
+ }
14899
+ async execute(roomId, sender, content, color) {
14900
+ return this.messageRepository.send(roomId, sender, content, color);
14901
+ }
14902
+ }
14903
+
14904
+ // src/domain/usecases/CreateRoom.ts
14905
+ class CreateRoom {
14906
+ roomRepository;
14907
+ constructor(roomRepository) {
14908
+ this.roomRepository = roomRepository;
14909
+ }
14910
+ async execute(name) {
14911
+ return this.roomRepository.create(name);
14912
+ }
14913
+ }
14914
+
14915
+ // src/domain/usecases/DeleteRoom.ts
14916
+ class DeleteRoom {
14917
+ roomRepository;
14918
+ constructor(roomRepository) {
14919
+ this.roomRepository = roomRepository;
14920
+ }
14921
+ async execute(roomId) {
14922
+ return this.roomRepository.delete(roomId);
14923
+ }
14924
+ }
14925
+
14926
+ // src/domain/usecases/SendLog.ts
14927
+ class SendLog {
14928
+ messageRepository;
14929
+ constructor(messageRepository) {
14930
+ this.messageRepository = messageRepository;
14931
+ }
14932
+ async execute(roomId, sender, content, opts) {
14933
+ return this.messageRepository.sendLog(roomId, sender, content, opts);
14934
+ }
14935
+ }
14936
+
14937
+ // src/domain/usecases/SendTeamInfo.ts
14938
+ class SendTeamInfo {
14939
+ roomRepository;
14940
+ constructor(roomRepository) {
14941
+ this.roomRepository = roomRepository;
14942
+ }
14943
+ async execute(roomId, payload) {
14944
+ return this.roomRepository.sendTeamInfo(roomId, payload);
14945
+ }
14946
+ }
14947
+
14948
+ // src/domain/usecases/SendCommands.ts
14949
+ class SendCommands {
14950
+ roomRepository;
14951
+ constructor(roomRepository) {
14952
+ this.roomRepository = roomRepository;
14953
+ }
14954
+ async execute(roomId, payload) {
14955
+ return this.roomRepository.sendCommands(roomId, payload);
14956
+ }
14957
+ }
14958
+
14959
+ // src/domain/usecases/SendTasks.ts
14960
+ class SendTasks {
14961
+ roomRepository;
14962
+ constructor(roomRepository) {
14963
+ this.roomRepository = roomRepository;
14964
+ }
14965
+ async execute(roomId, payload) {
14966
+ return this.roomRepository.sendTasks(roomId, payload);
14967
+ }
14968
+ }
14969
+
14970
+ // src/domain/usecases/SendTerminalData.ts
14971
+ class SendTerminalData {
14972
+ roomRepository;
14973
+ constructor(roomRepository) {
14974
+ this.roomRepository = roomRepository;
14975
+ }
14976
+ async execute(roomId, data) {
14977
+ return this.roomRepository.sendTerminalData(roomId, data);
14978
+ }
14979
+ }
14980
+
14981
+ // src/domain/services/InboxRouter.ts
14982
+ import { dirname } from "node:path";
14983
+
14984
+ class InboxRouter {
14985
+ fs;
14986
+ constructor(fs) {
14987
+ this.fs = fs;
14988
+ }
14989
+ route(msg, opts) {
14990
+ const entry = {
14991
+ from: `meet-ai:${msg.sender}`,
14992
+ text: msg.content,
14993
+ timestamp: new Date().toISOString(),
14994
+ read: false
14995
+ };
14996
+ if (opts.attachmentPaths?.length) {
14997
+ entry.attachments = opts.attachmentPaths;
14998
+ }
14999
+ const members = this.getTeamMembers(opts.teamDir);
15000
+ const targets = this.resolveInboxTargets(msg.content, members);
15001
+ if (targets) {
15002
+ for (const target of targets) {
15003
+ this.appendToInbox(`${opts.inboxDir}/${target}.json`, entry);
15004
+ }
15005
+ } else if (opts.stdinPane) {} else if (opts.defaultInboxPath) {
15006
+ this.appendToInbox(opts.defaultInboxPath, entry);
15007
+ }
15008
+ }
15009
+ checkIdle(opts) {
15010
+ const members = this.getTeamMembers(opts.teamDir);
15011
+ const newlyIdle = this.checkIdleAgents(opts.inboxDir, members, opts.inbox, opts.notified);
15012
+ for (const agent of newlyIdle) {
15013
+ opts.notified.add(agent);
15014
+ if (opts.defaultInboxPath) {
15015
+ this.appendToInbox(opts.defaultInboxPath, {
15016
+ from: "meet-ai:idle-check",
15017
+ text: `${agent} idle for 5+ minutes`,
15018
+ timestamp: new Date().toISOString(),
15019
+ read: false
15020
+ });
14825
15021
  }
14826
- return connect();
14827
- },
14828
- async generateKey() {
14829
- const res = await fetch(`${baseUrl}/api/keys`, {
14830
- method: "POST",
14831
- headers: headers()
14832
- });
14833
- if (!res.ok) {
14834
- const err2 = await res.json();
14835
- throw new Error(err2.error ?? `HTTP ${res.status}`);
15022
+ }
15023
+ }
15024
+ appendToInbox(path, entry) {
15025
+ this.fs.mkdirSync(dirname(path), { recursive: true });
15026
+ let messages = [];
15027
+ try {
15028
+ messages = JSON.parse(this.fs.readFileSync(path, "utf-8"));
15029
+ } catch {}
15030
+ messages.push(entry);
15031
+ this.fs.writeFileSync(path, JSON.stringify(messages, null, 2));
15032
+ }
15033
+ getTeamMembers(teamDir) {
15034
+ try {
15035
+ const config2 = JSON.parse(this.fs.readFileSync(`${teamDir}/config.json`, "utf-8"));
15036
+ return new Set(config2.members?.map((m) => m.name) || []);
15037
+ } catch {
15038
+ return new Set;
15039
+ }
15040
+ }
15041
+ resolveInboxTargets(content, members) {
15042
+ const mentions = content.match(/@([\w-]+)/g);
15043
+ if (!mentions)
15044
+ return null;
15045
+ const valid = [...new Set(mentions.map((m) => m.slice(1)))].filter((name) => members.has(name));
15046
+ return valid.length > 0 ? valid : null;
15047
+ }
15048
+ checkIdleAgents(inboxDir, members, excludeAgent, notified, now = Date.now()) {
15049
+ const newlyIdle = [];
15050
+ for (const member of members) {
15051
+ if (member === excludeAgent)
15052
+ continue;
15053
+ const inboxPath = `${inboxDir}/${member}.json`;
15054
+ let mtime;
15055
+ try {
15056
+ mtime = this.fs.statSync(inboxPath).mtimeMs;
15057
+ } catch {
15058
+ continue;
14836
15059
  }
14837
- return res.json();
14838
- },
14839
- async deleteRoom(roomId) {
14840
- const res = await fetch(`${baseUrl}/api/rooms/${roomId}`, {
14841
- method: "DELETE",
14842
- headers: headers()
14843
- });
14844
- if (!res.ok) {
14845
- const err2 = await res.json().catch(() => ({}));
14846
- throw new Error(err2.error ?? `HTTP ${res.status}`);
15060
+ const idleMs = now - mtime;
15061
+ if (idleMs >= IDLE_THRESHOLD_MS) {
15062
+ if (!notified.has(member)) {
15063
+ newlyIdle.push(member);
15064
+ }
15065
+ } else {
15066
+ notified.delete(member);
14847
15067
  }
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
15068
  }
14858
- };
15069
+ return newlyIdle;
15070
+ }
14859
15071
  }
14860
- var ATTACHMENTS_DIR = "/tmp/meet-ai-attachments", MAX_AGE_MS;
14861
- var init_client = __esm(() => {
14862
- MAX_AGE_MS = 5 * 60 * 1000;
15072
+ var IDLE_THRESHOLD_MS;
15073
+ var init_InboxRouter = __esm(() => {
15074
+ IDLE_THRESHOLD_MS = 5 * 60 * 1000;
14863
15075
  });
14864
15076
 
14865
- // src/lib/client-factory.ts
14866
- var exports_client_factory = {};
14867
- __export(exports_client_factory, {
15077
+ // src/domain/usecases/Listen.ts
15078
+ class Listen {
15079
+ connectionAdapter;
15080
+ messageRepository;
15081
+ constructor(connectionAdapter, messageRepository) {
15082
+ this.connectionAdapter = connectionAdapter;
15083
+ this.messageRepository = messageRepository;
15084
+ }
15085
+ execute(roomId, opts) {
15086
+ return this.connectionAdapter.listen(roomId, opts);
15087
+ }
15088
+ }
15089
+
15090
+ // src/domain/usecases/ListenLobby.ts
15091
+ class ListenLobby {
15092
+ connectionAdapter;
15093
+ constructor(connectionAdapter) {
15094
+ this.connectionAdapter = connectionAdapter;
15095
+ }
15096
+ execute(opts) {
15097
+ return this.connectionAdapter.listenLobby(opts);
15098
+ }
15099
+ }
15100
+
15101
+ // src/domain/usecases/Poll.ts
15102
+ class Poll {
15103
+ messageRepository;
15104
+ constructor(messageRepository) {
15105
+ this.messageRepository = messageRepository;
15106
+ }
15107
+ async execute(roomId, opts) {
15108
+ return this.messageRepository.list(roomId, opts);
15109
+ }
15110
+ }
15111
+
15112
+ // src/domain/usecases/GenerateKey.ts
15113
+ class GenerateKey {
15114
+ connectionAdapter;
15115
+ constructor(connectionAdapter) {
15116
+ this.connectionAdapter = connectionAdapter;
15117
+ }
15118
+ async execute() {
15119
+ return this.connectionAdapter.generateKey();
15120
+ }
15121
+ }
15122
+
15123
+ // src/domain/usecases/GetAttachments.ts
15124
+ class GetAttachments {
15125
+ attachmentRepository;
15126
+ constructor(attachmentRepository) {
15127
+ this.attachmentRepository = attachmentRepository;
15128
+ }
15129
+ async execute(roomId, messageId) {
15130
+ return this.attachmentRepository.listForMessage(roomId, messageId);
15131
+ }
15132
+ }
15133
+
15134
+ // src/domain/usecases/DownloadAttachment.ts
15135
+ class DownloadAttachment {
15136
+ attachmentRepository;
15137
+ constructor(attachmentRepository) {
15138
+ this.attachmentRepository = attachmentRepository;
15139
+ }
15140
+ async execute(attachmentId) {
15141
+ return this.attachmentRepository.download(attachmentId);
15142
+ }
15143
+ }
15144
+
15145
+ // src/domain/bootstrap.ts
15146
+ var exports_bootstrap = {};
15147
+ __export(exports_bootstrap, {
15148
+ getContainer: () => getContainer,
14868
15149
  getClient: () => getClient
14869
15150
  });
15151
+ function cleanupOldAttachments() {
15152
+ try {
15153
+ const { readdirSync, statSync: statSync2, unlinkSync } = __require("node:fs");
15154
+ const now = Date.now();
15155
+ for (const entry of readdirSync(ATTACHMENTS_DIR)) {
15156
+ try {
15157
+ const filePath = `${ATTACHMENTS_DIR}/${entry}`;
15158
+ const mtime = statSync2(filePath).mtimeMs;
15159
+ if (now - mtime > MAX_AGE_MS) {
15160
+ unlinkSync(filePath);
15161
+ }
15162
+ } catch {}
15163
+ }
15164
+ } catch {}
15165
+ }
15166
+ function createContainer() {
15167
+ const config2 = getMeetAiConfig();
15168
+ const transport = new HttpTransport(config2.url, config2.key);
15169
+ const messageRepository = new MessageRepository(transport);
15170
+ const roomRepository = new RoomRepository(transport);
15171
+ const attachmentRepository = new AttachmentRepository(transport);
15172
+ const connectionAdapter = new ConnectionAdapter(transport, config2.url, config2.key);
15173
+ const fileSystem = new FileSystemAdapter;
15174
+ const inboxRouter = new InboxRouter(fileSystem);
15175
+ return {
15176
+ sendMessage: new SendMessage(messageRepository),
15177
+ createRoom: new CreateRoom(roomRepository),
15178
+ deleteRoom: new DeleteRoom(roomRepository),
15179
+ sendLog: new SendLog(messageRepository),
15180
+ sendTeamInfo: new SendTeamInfo(roomRepository),
15181
+ sendCommands: new SendCommands(roomRepository),
15182
+ sendTasks: new SendTasks(roomRepository),
15183
+ sendTerminalData: new SendTerminalData(roomRepository),
15184
+ listen: new Listen(connectionAdapter, messageRepository),
15185
+ listenLobby: new ListenLobby(connectionAdapter),
15186
+ poll: new Poll(messageRepository),
15187
+ generateKey: new GenerateKey(connectionAdapter),
15188
+ getAttachments: new GetAttachments(attachmentRepository),
15189
+ downloadAttachment: new DownloadAttachment(attachmentRepository),
15190
+ inboxRouter
15191
+ };
15192
+ }
15193
+ function getContainer() {
15194
+ if (!container) {
15195
+ container = createContainer();
15196
+ }
15197
+ return container;
15198
+ }
14870
15199
  function getClient() {
14871
- if (!_client) {
14872
- const config2 = getMeetAiConfig();
14873
- _client = createClient(config2.url, config2.key);
14874
- }
14875
- return _client;
15200
+ const c = getContainer();
15201
+ return {
15202
+ createRoom: (name) => c.createRoom.execute(name),
15203
+ sendMessage: (roomId, sender, content, color) => c.sendMessage.execute(roomId, sender, content, color),
15204
+ getMessages: (roomId, options) => c.poll.execute(roomId, options),
15205
+ listen: (roomId, options) => c.listen.execute(roomId, options),
15206
+ sendLog: (roomId, sender, content, color, messageId) => c.sendLog.execute(roomId, sender, content, { color, messageId }),
15207
+ sendTeamInfo: (roomId, payload) => c.sendTeamInfo.execute(roomId, payload),
15208
+ sendCommands: (roomId, payload) => c.sendCommands.execute(roomId, payload),
15209
+ sendTasks: (roomId, payload) => c.sendTasks.execute(roomId, payload),
15210
+ getMessageAttachments: (roomId, messageId) => c.getAttachments.execute(roomId, messageId),
15211
+ downloadAttachment: async (attachmentId) => {
15212
+ cleanupOldAttachments();
15213
+ const response = await c.downloadAttachment.execute(attachmentId);
15214
+ const { mkdirSync: mkdirSync2, writeFileSync: writeFileSync2 } = await import("node:fs");
15215
+ mkdirSync2(ATTACHMENTS_DIR, { recursive: true });
15216
+ const safeId = attachmentId.replace(/[^a-zA-Z0-9_-]/g, "") || "unknown";
15217
+ const localPath = `${ATTACHMENTS_DIR}/${safeId}.bin`;
15218
+ const buffer = Buffer.from(await response.arrayBuffer());
15219
+ writeFileSync2(localPath, buffer);
15220
+ return localPath;
15221
+ },
15222
+ listenLobby: (options) => c.listenLobby.execute(options),
15223
+ generateKey: () => c.generateKey.execute(),
15224
+ deleteRoom: (roomId) => c.deleteRoom.execute(roomId),
15225
+ sendTerminalData: (roomId, data) => c.sendTerminalData.execute(roomId, data)
15226
+ };
14876
15227
  }
14877
- var _client = null;
14878
- var init_client_factory = __esm(() => {
15228
+ var ATTACHMENTS_DIR = "/tmp/meet-ai-attachments", MAX_AGE_MS, container = null;
15229
+ var init_bootstrap = __esm(() => {
14879
15230
  init_config();
14880
- init_client();
15231
+ init_FileSystemAdapter();
15232
+ init_MessageRepository();
15233
+ init_RoomRepository();
15234
+ init_InboxRouter();
15235
+ MAX_AGE_MS = 5 * 60 * 1000;
14881
15236
  });
14882
15237
 
14883
15238
  // src/commands/create-room/schema.ts
@@ -14909,7 +15264,7 @@ __export(exports_command, {
14909
15264
  var command_default;
14910
15265
  var init_command = __esm(() => {
14911
15266
  init_dist();
14912
- init_client_factory();
15267
+ init_bootstrap();
14913
15268
  init_usecase();
14914
15269
  init_output();
14915
15270
  command_default = defineCommand({
@@ -14964,7 +15319,7 @@ __export(exports_command2, {
14964
15319
  var command_default2;
14965
15320
  var init_command2 = __esm(() => {
14966
15321
  init_dist();
14967
- init_client_factory();
15322
+ init_bootstrap();
14968
15323
  init_usecase2();
14969
15324
  init_output();
14970
15325
  command_default2 = defineCommand({
@@ -15040,7 +15395,7 @@ __export(exports_command3, {
15040
15395
  var command_default3;
15041
15396
  var init_command3 = __esm(() => {
15042
15397
  init_dist();
15043
- init_client_factory();
15398
+ init_bootstrap();
15044
15399
  init_usecase3();
15045
15400
  init_output();
15046
15401
  command_default3 = defineCommand({
@@ -15123,7 +15478,7 @@ __export(exports_command4, {
15123
15478
  var command_default4;
15124
15479
  var init_command4 = __esm(() => {
15125
15480
  init_dist();
15126
- init_client_factory();
15481
+ init_bootstrap();
15127
15482
  init_usecase4();
15128
15483
  init_output();
15129
15484
  command_default4 = defineCommand({
@@ -15241,7 +15596,7 @@ __export(exports_command5, {
15241
15596
  var command_default5;
15242
15597
  var init_command5 = __esm(() => {
15243
15598
  init_dist();
15244
- init_client_factory();
15599
+ init_bootstrap();
15245
15600
  init_usecase5();
15246
15601
  init_output();
15247
15602
  command_default5 = defineCommand({
@@ -15306,58 +15661,9 @@ var init_schema6 = __esm(() => {
15306
15661
  });
15307
15662
 
15308
15663
  // 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;
15664
+ var IDLE_CHECK_INTERVAL_MS = 60000, IDLE_THRESHOLD_MS2;
15359
15665
  var init_inbox_router = __esm(() => {
15360
- IDLE_THRESHOLD_MS = 5 * 60 * 1000;
15666
+ IDLE_THRESHOLD_MS2 = 5 * 60 * 1000;
15361
15667
  });
15362
15668
 
15363
15669
  // src/lib/tmux-client.ts
@@ -15367,10 +15673,10 @@ function validateSessionName(name) {
15367
15673
  throw new Error(`Invalid tmux session name: ${name}`);
15368
15674
  }
15369
15675
  }
15370
- function parseVersion(version2) {
15371
- if (!version2)
15676
+ function parseVersion(version3) {
15677
+ if (!version3)
15372
15678
  return [0, 0];
15373
- const match = version2.match(/(\d+)\.(\d+)/);
15679
+ const match = version3.match(/(\d+)\.(\d+)/);
15374
15680
  if (!match)
15375
15681
  return [0, 0];
15376
15682
  return [Number(match[1]), Number(match[2])];
@@ -15580,27 +15886,7 @@ var init_tmux_client = __esm(() => {
15580
15886
  });
15581
15887
 
15582
15888
  // src/commands/listen/usecase.ts
15583
- function routeToInbox(msg, inboxDir, defaultInboxPath, teamDir, stdinPane, attachmentPaths) {
15584
- const entry = {
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) {
15889
+ function listen(client, input, inboxRouter) {
15604
15890
  const parsed = ListenInput.parse(input);
15605
15891
  const { roomId, exclude, senderType, team, inbox, stdinPane } = parsed;
15606
15892
  const inboxDir = team ? `${process.env.HOME}/.claude/teams/${team}/inboxes` : null;
@@ -15689,34 +15975,22 @@ function listen(client, input) {
15689
15975
  downloadMessageAttachments(client, msg.room_id, msg.id).then((paths) => {
15690
15976
  const output = paths.length ? { ...msg, attachments: paths } : msg;
15691
15977
  console.log(JSON.stringify(output));
15692
- if (inboxDir && teamDir)
15693
- routeToInbox(msg, inboxDir, defaultInboxPath, teamDir, stdinPane, paths);
15978
+ if (inboxDir && teamDir && inboxRouter)
15979
+ inboxRouter.route(msg, { inboxDir, defaultInboxPath, teamDir, stdinPane, attachmentPaths: paths });
15694
15980
  });
15695
15981
  } else {
15696
15982
  console.log(JSON.stringify(msg));
15697
- if (inboxDir && teamDir)
15698
- routeToInbox(msg, inboxDir, defaultInboxPath, teamDir, stdinPane);
15983
+ if (inboxDir && teamDir && inboxRouter)
15984
+ inboxRouter.route(msg, { inboxDir, defaultInboxPath, teamDir, stdinPane });
15699
15985
  }
15700
15986
  };
15701
15987
  const ws = client.listen(roomId, { exclude, senderType, onMessage });
15702
15988
  let idleCheckTimeout = null;
15703
15989
  const idleNotified = new Set;
15704
- if (inboxDir && inbox && teamDir) {
15990
+ if (inboxDir && inbox && teamDir && inboxRouter) {
15705
15991
  let scheduleIdleCheck = function() {
15706
15992
  idleCheckTimeout = setTimeout(() => {
15707
- const members = getTeamMembers(teamDir);
15708
- const newlyIdle = checkIdleAgents(inboxDir, members, inbox, idleNotified);
15709
- for (const agent of newlyIdle) {
15710
- idleNotified.add(agent);
15711
- if (defaultInboxPath) {
15712
- appendToInbox(defaultInboxPath, {
15713
- from: "meet-ai:idle-check",
15714
- text: `${agent} idle for 5+ minutes`,
15715
- timestamp: new Date().toISOString(),
15716
- read: false
15717
- });
15718
- }
15719
- }
15993
+ inboxRouter.checkIdle({ inboxDir, teamDir, inbox, defaultInboxPath, notified: idleNotified });
15720
15994
  scheduleIdleCheck();
15721
15995
  }, IDLE_CHECK_INTERVAL_MS);
15722
15996
  };
@@ -15736,6 +16010,7 @@ function listen(client, input) {
15736
16010
  }
15737
16011
  process.on("SIGINT", shutdown);
15738
16012
  process.on("SIGTERM", shutdown);
16013
+ process.on("SIGHUP", shutdown);
15739
16014
  return ws;
15740
16015
  }
15741
16016
  var init_usecase6 = __esm(() => {
@@ -15752,7 +16027,7 @@ __export(exports_command6, {
15752
16027
  var command_default6;
15753
16028
  var init_command6 = __esm(() => {
15754
16029
  init_dist();
15755
- init_client_factory();
16030
+ init_bootstrap();
15756
16031
  init_usecase6();
15757
16032
  init_output();
15758
16033
  command_default6 = defineCommand({
@@ -15795,6 +16070,7 @@ var init_command6 = __esm(() => {
15795
16070
  run({ args }) {
15796
16071
  try {
15797
16072
  const client = getClient();
16073
+ const container2 = getContainer();
15798
16074
  listen(client, {
15799
16075
  roomId: args.roomId,
15800
16076
  exclude: args.exclude,
@@ -15802,7 +16078,7 @@ var init_command6 = __esm(() => {
15802
16078
  team: args.team,
15803
16079
  inbox: args.inbox,
15804
16080
  stdinPane: args["stdin-pane"]
15805
- });
16081
+ }, container2.inboxRouter);
15806
16082
  } catch (error48) {
15807
16083
  err(error48 instanceof Error ? error48.message : String(error48));
15808
16084
  process.exit(1);
@@ -15847,7 +16123,7 @@ __export(exports_command7, {
15847
16123
  var command_default7;
15848
16124
  var init_command7 = __esm(() => {
15849
16125
  init_dist();
15850
- init_client_factory();
16126
+ init_bootstrap();
15851
16127
  init_usecase7();
15852
16128
  init_output();
15853
16129
  command_default7 = defineCommand({
@@ -15915,7 +16191,7 @@ __export(exports_command8, {
15915
16191
  var command_default8;
15916
16192
  var init_command8 = __esm(() => {
15917
16193
  init_dist();
15918
- init_client_factory();
16194
+ init_bootstrap();
15919
16195
  init_usecase8();
15920
16196
  init_output();
15921
16197
  command_default8 = defineCommand({
@@ -15976,7 +16252,7 @@ __export(exports_command9, {
15976
16252
  var command_default9;
15977
16253
  var init_command9 = __esm(() => {
15978
16254
  init_dist();
15979
- init_client_factory();
16255
+ init_bootstrap();
15980
16256
  init_usecase9();
15981
16257
  init_output();
15982
16258
  command_default9 = defineCommand({
@@ -16019,7 +16295,7 @@ __export(exports_command10, {
16019
16295
  var command_default10;
16020
16296
  var init_command10 = __esm(() => {
16021
16297
  init_dist();
16022
- init_client_factory();
16298
+ init_bootstrap();
16023
16299
  init_output();
16024
16300
  command_default10 = defineCommand({
16025
16301
  meta: {
@@ -16480,14 +16756,14 @@ var createProxy = (callback, path) => {
16480
16756
  }
16481
16757
  return req;
16482
16758
  }, []);
16483
- var init_client2 = __esm(() => {
16759
+ var init_client = __esm(() => {
16484
16760
  init_cookie();
16485
16761
  init_utils();
16486
16762
  });
16487
16763
 
16488
16764
  // ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/index.js
16489
- var init_client3 = __esm(() => {
16490
- init_client2();
16765
+ var init_client2 = __esm(() => {
16766
+ init_client();
16491
16767
  init_utils();
16492
16768
  });
16493
16769
 
@@ -16541,15 +16817,15 @@ async function sendLogEntry(client, roomId, summary, messageId) {
16541
16817
  } catch {}
16542
16818
  }
16543
16819
  var HOOK_COLOR = "#6b7280", HOOK_SENDER = "hook";
16544
- var init_client4 = __esm(() => {
16545
- init_client3();
16820
+ var init_client3 = __esm(() => {
16821
+ init_client2();
16546
16822
  });
16547
16823
 
16548
16824
  // src/lib/hooks/index.ts
16549
16825
  var init_hooks = __esm(() => {
16550
16826
  init_find_room();
16551
16827
  init_summarize();
16552
- init_client4();
16828
+ init_client3();
16553
16829
  });
16554
16830
 
16555
16831
  // src/commands/hook/log-tool-use/usecase.ts
@@ -16851,7 +17127,7 @@ async function processPlanReview(rawInput, teamsDir) {
16851
17127
  }
16852
17128
  var POLL_INTERVAL_MS = 2000, POLL_TIMEOUT_MS = 2592000000;
16853
17129
  var init_usecase11 = __esm(() => {
16854
- init_client4();
17130
+ init_client3();
16855
17131
  init_find_room();
16856
17132
  });
16857
17133
 
@@ -17047,7 +17323,7 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
17047
17323
  }
17048
17324
  var POLL_INTERVAL_MS2 = 2000, POLL_TIMEOUT_MS2 = 1800000;
17049
17325
  var init_usecase12 = __esm(() => {
17050
- init_client4();
17326
+ init_client3();
17051
17327
  init_find_room();
17052
17328
  });
17053
17329
 
@@ -17245,7 +17521,7 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
17245
17521
  }
17246
17522
  var POLL_INTERVAL_MS3 = 2000, POLL_TIMEOUT_MS3 = 1800000;
17247
17523
  var init_usecase13 = __esm(() => {
17248
- init_client4();
17524
+ init_client3();
17249
17525
  init_find_room();
17250
17526
  });
17251
17527
 
@@ -17302,7 +17578,7 @@ var init_command15 = __esm(() => {
17302
17578
  });
17303
17579
 
17304
17580
  // src/commands/setup-hooks/usecase.ts
17305
- import { existsSync as existsSync2 } from "node:fs";
17581
+ import { existsSync as existsSync3 } from "node:fs";
17306
17582
  import { readFile, writeFile, mkdir } from "node:fs/promises";
17307
17583
  import { homedir as homedir2 } from "node:os";
17308
17584
  import { resolve as resolve2, dirname as dirname2 } from "node:path";
@@ -17316,7 +17592,7 @@ function getSettingsPath(project) {
17316
17592
  return resolve2(homedir2(), ".claude", "settings.json");
17317
17593
  }
17318
17594
  async function readSettings(path) {
17319
- if (!existsSync2(path)) {
17595
+ if (!existsSync3(path)) {
17320
17596
  return {};
17321
17597
  }
17322
17598
  const raw = await readFile(path, "utf-8");
@@ -17524,7 +17800,7 @@ var init_command16 = __esm(() => {
17524
17800
  });
17525
17801
 
17526
17802
  // src/commands/list-commands/usecase.ts
17527
- import { existsSync as existsSync3 } from "node:fs";
17803
+ import { existsSync as existsSync4 } from "node:fs";
17528
17804
  import { readFile as readFile2, readdir } from "node:fs/promises";
17529
17805
  import { homedir as homedir3 } from "node:os";
17530
17806
  import { join as join3, resolve as resolve3 } from "node:path";
@@ -17544,7 +17820,7 @@ function parseYamlFrontmatter(content) {
17544
17820
  }
17545
17821
  async function readSkillsFromDir(baseDir, source, scope) {
17546
17822
  const skillsDir = join3(baseDir, "skills");
17547
- if (!existsSync3(skillsDir))
17823
+ if (!existsSync4(skillsDir))
17548
17824
  return [];
17549
17825
  let entries;
17550
17826
  try {
@@ -17555,7 +17831,7 @@ async function readSkillsFromDir(baseDir, source, scope) {
17555
17831
  const results = [];
17556
17832
  for (const entry of entries) {
17557
17833
  const skillFile = join3(skillsDir, entry, "SKILL.md");
17558
- if (!existsSync3(skillFile))
17834
+ if (!existsSync4(skillFile))
17559
17835
  continue;
17560
17836
  try {
17561
17837
  const content = await readFile2(skillFile, "utf-8");
@@ -17578,7 +17854,7 @@ async function readSkillsFromDir(baseDir, source, scope) {
17578
17854
  return results;
17579
17855
  }
17580
17856
  async function readCommandsFromDir(commandsDir, source, scope) {
17581
- if (!existsSync3(commandsDir))
17857
+ if (!existsSync4(commandsDir))
17582
17858
  return [];
17583
17859
  const results = [];
17584
17860
  async function scanDir(dir) {
@@ -17616,7 +17892,7 @@ async function readCommandsFromDir(commandsDir, source, scope) {
17616
17892
  return results;
17617
17893
  }
17618
17894
  async function readSettings2(settingsPath) {
17619
- if (!existsSync3(settingsPath))
17895
+ if (!existsSync4(settingsPath))
17620
17896
  return {};
17621
17897
  try {
17622
17898
  const raw = await readFile2(settingsPath, "utf-8");
@@ -17626,7 +17902,7 @@ async function readSettings2(settingsPath) {
17626
17902
  }
17627
17903
  }
17628
17904
  async function readInstalledPlugins(pluginsFile) {
17629
- if (!existsSync3(pluginsFile))
17905
+ if (!existsSync4(pluginsFile))
17630
17906
  return {};
17631
17907
  try {
17632
17908
  const raw = await readFile2(pluginsFile, "utf-8");
@@ -17730,7 +18006,7 @@ __export(exports_command18, {
17730
18006
  var command_default18;
17731
18007
  var init_command18 = __esm(() => {
17732
18008
  init_dist();
17733
- init_client_factory();
18009
+ init_bootstrap();
17734
18010
  init_usecase16();
17735
18011
  init_output();
17736
18012
  command_default18 = defineCommand({
@@ -27009,11 +27285,11 @@ https://react.dev/link/unsafe-component-lifecycles`, _instance, newApiName, stat
27009
27285
  function updateHostContainer(current2, workInProgress2) {
27010
27286
  if (supportsPersistence && doesRequireClone(current2, workInProgress2)) {
27011
27287
  current2 = workInProgress2.stateNode;
27012
- var container = current2.containerInfo, newChildSet = createContainerChildSet();
27288
+ var container2 = current2.containerInfo, newChildSet = createContainerChildSet();
27013
27289
  appendAllChildrenToContainer(newChildSet, workInProgress2, false, false);
27014
27290
  current2.pendingChildren = newChildSet;
27015
27291
  markUpdate(workInProgress2);
27016
- finalizeContainerChildren(container, newChildSet);
27292
+ finalizeContainerChildren(container2, newChildSet);
27017
27293
  }
27018
27294
  }
27019
27295
  function updateHostComponent(current2, workInProgress2, type, newProps) {
@@ -30275,27 +30551,27 @@ Check the render method of \`` + fiberTag + "`.");
30275
30551
  parentComponent = emptyContextObject;
30276
30552
  return parentComponent;
30277
30553
  }
30278
- function updateContainerSync(element, container, parentComponent, callback) {
30279
- updateContainerImpl(container.current, 2, element, container, parentComponent, callback);
30554
+ function updateContainerSync(element, container2, parentComponent, callback) {
30555
+ updateContainerImpl(container2.current, 2, element, container2, parentComponent, callback);
30280
30556
  return 2;
30281
30557
  }
30282
- function updateContainerImpl(rootFiber, lane, element, container, parentComponent, callback) {
30558
+ function updateContainerImpl(rootFiber, lane, element, container2, parentComponent, callback) {
30283
30559
  if (injectedHook && typeof injectedHook.onScheduleFiberRoot === "function")
30284
30560
  try {
30285
- injectedHook.onScheduleFiberRoot(rendererID, container, element);
30561
+ injectedHook.onScheduleFiberRoot(rendererID, container2, element);
30286
30562
  } catch (err2) {
30287
30563
  hasLoggedError || (hasLoggedError = true, console.error("React instrumentation encountered an error: %o", err2));
30288
30564
  }
30289
30565
  parentComponent = getContextForSubtree(parentComponent);
30290
- container.context === null ? container.context = parentComponent : container.pendingContext = parentComponent;
30566
+ container2.context === null ? container2.context = parentComponent : container2.pendingContext = parentComponent;
30291
30567
  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.
30292
30568
 
30293
30569
  Check the render method of %s.`, getComponentNameFromFiber(current) || "Unknown"));
30294
- container = createUpdate(lane);
30295
- container.payload = { element };
30570
+ container2 = createUpdate(lane);
30571
+ container2.payload = { element };
30296
30572
  callback = callback === undefined ? null : callback;
30297
- callback !== null && (typeof callback !== "function" && console.error("Expected the last optional `callback` argument to be a function. Instead received: %s.", callback), container.callback = callback);
30298
- element = enqueueUpdate(rootFiber, container, lane);
30573
+ callback !== null && (typeof callback !== "function" && console.error("Expected the last optional `callback` argument to be a function. Instead received: %s.", callback), container2.callback = callback);
30574
+ element = enqueueUpdate(rootFiber, container2, lane);
30299
30575
  element !== null && (startUpdateTimerByLane(lane, "root.render()", null), scheduleUpdateOnFiber(element, rootFiber, lane), entangleTransitions(element, rootFiber, lane));
30300
30576
  }
30301
30577
  function markRetryLaneImpl(fiber, retryLane) {
@@ -32055,16 +32331,16 @@ No matching component was found for:
32055
32331
  }
32056
32332
  return null;
32057
32333
  };
32058
- exports2.getPublicRootInstance = function(container) {
32059
- container = container.current;
32060
- if (!container.child)
32334
+ exports2.getPublicRootInstance = function(container2) {
32335
+ container2 = container2.current;
32336
+ if (!container2.child)
32061
32337
  return null;
32062
- switch (container.child.tag) {
32338
+ switch (container2.child.tag) {
32063
32339
  case 27:
32064
32340
  case 5:
32065
- return getPublicInstance(container.child.stateNode);
32341
+ return getPublicInstance(container2.child.stateNode);
32066
32342
  default:
32067
- return container.child.stateNode;
32343
+ return container2.child.stateNode;
32068
32344
  }
32069
32345
  };
32070
32346
  exports2.injectIntoDevTools = function() {
@@ -32136,9 +32412,9 @@ No matching component was found for:
32136
32412
  return action(formData);
32137
32413
  });
32138
32414
  };
32139
- exports2.updateContainer = function(element, container, parentComponent, callback) {
32140
- var current2 = container.current, lane = requestUpdateLane(current2);
32141
- updateContainerImpl(current2, lane, element, container, parentComponent, callback);
32415
+ exports2.updateContainer = function(element, container2, parentComponent, callback) {
32416
+ var current2 = container2.current, lane = requestUpdateLane(current2);
32417
+ updateContainerImpl(current2, lane, element, container2, parentComponent, callback);
32142
32418
  return lane;
32143
32419
  };
32144
32420
  exports2.updateContainerSync = updateContainerSync;
@@ -36561,7 +36837,7 @@ var require_websocket_server = __commonJS((exports, module) => {
36561
36837
  socket.on("error", socketOnError);
36562
36838
  const key = req.headers["sec-websocket-key"];
36563
36839
  const upgrade = req.headers.upgrade;
36564
- const version2 = +req.headers["sec-websocket-version"];
36840
+ const version3 = +req.headers["sec-websocket-version"];
36565
36841
  if (req.method !== "GET") {
36566
36842
  const message = "Invalid HTTP method";
36567
36843
  abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);
@@ -36577,7 +36853,7 @@ var require_websocket_server = __commonJS((exports, module) => {
36577
36853
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
36578
36854
  return;
36579
36855
  }
36580
- if (version2 !== 13 && version2 !== 8) {
36856
+ if (version3 !== 13 && version3 !== 8) {
36581
36857
  const message = "Missing or invalid Sec-WebSocket-Version header";
36582
36858
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
36583
36859
  "Sec-WebSocket-Version": "13, 8"
@@ -36617,7 +36893,7 @@ var require_websocket_server = __commonJS((exports, module) => {
36617
36893
  }
36618
36894
  if (this.options.verifyClient) {
36619
36895
  const info2 = {
36620
- origin: req.headers[`${version2 === 8 ? "sec-websocket-origin" : "origin"}`],
36896
+ origin: req.headers[`${version3 === 8 ? "sec-websocket-origin" : "origin"}`],
36621
36897
  secure: !!(req.socket.authorized || req.socket.encrypted),
36622
36898
  req
36623
36899
  };
@@ -39452,20 +39728,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
39452
39728
  }
39453
39729
  return 0;
39454
39730
  };
39455
- var validate2 = function validate3(version2) {
39456
- return typeof version2 === "string" && /^[v\d]/.test(version2) && semver.test(version2);
39731
+ var validate2 = function validate3(version3) {
39732
+ return typeof version3 === "string" && /^[v\d]/.test(version3) && semver.test(version3);
39457
39733
  };
39458
39734
  var compare = function compare2(v1, v2, operator) {
39459
39735
  assertValidOperator(operator);
39460
39736
  var res = compareVersions(v1, v2);
39461
39737
  return operatorResMap[operator].includes(res);
39462
39738
  };
39463
- var satisfies = function satisfies2(version2, range) {
39739
+ var satisfies = function satisfies2(version3, range) {
39464
39740
  var m = range.match(/^([<>=~^]+)/);
39465
39741
  var op = m ? m[1] : "=";
39466
39742
  if (op !== "^" && op !== "~")
39467
- return compare(version2, range, op);
39468
- var _validateAndParse = validateAndParse(version2), _validateAndParse2 = _slicedToArray(_validateAndParse, 5), v1 = _validateAndParse2[0], v2 = _validateAndParse2[1], v3 = _validateAndParse2[2], vp = _validateAndParse2[4];
39743
+ return compare(version3, range, op);
39744
+ var _validateAndParse = validateAndParse(version3), _validateAndParse2 = _slicedToArray(_validateAndParse, 5), v1 = _validateAndParse2[0], v2 = _validateAndParse2[1], v3 = _validateAndParse2[2], vp = _validateAndParse2[4];
39469
39745
  var _validateAndParse3 = validateAndParse(range), _validateAndParse4 = _slicedToArray(_validateAndParse3, 5), r1 = _validateAndParse4[0], r2 = _validateAndParse4[1], r3 = _validateAndParse4[2], rp = _validateAndParse4[4];
39470
39746
  var v = [v1, v2, v3];
39471
39747
  var r = [r1, r2 !== null && r2 !== undefined ? r2 : "x", r3 !== null && r3 !== undefined ? r3 : "x"];
@@ -39488,13 +39764,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
39488
39764
  return true;
39489
39765
  };
39490
39766
  var semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
39491
- var validateAndParse = function validateAndParse2(version2) {
39492
- if (typeof version2 !== "string") {
39767
+ var validateAndParse = function validateAndParse2(version3) {
39768
+ if (typeof version3 !== "string") {
39493
39769
  throw new TypeError("Invalid argument expected string");
39494
39770
  }
39495
- var match = version2.match(semver);
39771
+ var match = version3.match(semver);
39496
39772
  if (!match) {
39497
- throw new Error("Invalid argument not valid semver ('".concat(version2, "' received)"));
39773
+ throw new Error("Invalid argument not valid semver ('".concat(version3, "' received)"));
39498
39774
  }
39499
39775
  match.shift();
39500
39776
  return match;
@@ -41128,11 +41404,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41128
41404
  return obj;
41129
41405
  }
41130
41406
  var FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER = "999.9.9";
41131
- function hasAssignedBackend(version2) {
41132
- if (version2 == null || version2 === "") {
41407
+ function hasAssignedBackend(version3) {
41408
+ if (version3 == null || version3 === "") {
41133
41409
  return false;
41134
41410
  }
41135
- return gte(version2, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
41411
+ return gte(version3, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
41136
41412
  }
41137
41413
  function cleanForBridge(data, isPathAllowed) {
41138
41414
  var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
@@ -41611,7 +41887,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41611
41887
  }
41612
41888
  var Overlay_assign = Object.assign;
41613
41889
  var OverlayRect = /* @__PURE__ */ function() {
41614
- function OverlayRect2(doc2, container) {
41890
+ function OverlayRect2(doc2, container2) {
41615
41891
  Overlay_classCallCheck(this, OverlayRect2);
41616
41892
  this.node = doc2.createElement("div");
41617
41893
  this.border = doc2.createElement("div");
@@ -41629,7 +41905,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41629
41905
  this.node.appendChild(this.border);
41630
41906
  this.border.appendChild(this.padding);
41631
41907
  this.padding.appendChild(this.content);
41632
- container.appendChild(this.node);
41908
+ container2.appendChild(this.node);
41633
41909
  }
41634
41910
  return Overlay_createClass(OverlayRect2, [{
41635
41911
  key: "remove",
@@ -41656,7 +41932,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41656
41932
  }]);
41657
41933
  }();
41658
41934
  var OverlayTip = /* @__PURE__ */ function() {
41659
- function OverlayTip2(doc2, container) {
41935
+ function OverlayTip2(doc2, container2) {
41660
41936
  Overlay_classCallCheck(this, OverlayTip2);
41661
41937
  this.tip = doc2.createElement("div");
41662
41938
  Overlay_assign(this.tip.style, {
@@ -41686,7 +41962,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41686
41962
  color: "#d7d7d7"
41687
41963
  });
41688
41964
  this.tip.style.zIndex = "10000000";
41689
- container.appendChild(this.tip);
41965
+ container2.appendChild(this.tip);
41690
41966
  }
41691
41967
  return Overlay_createClass(OverlayTip2, [{
41692
41968
  key: "remove",
@@ -42788,9 +43064,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
42788
43064
  }
42789
43065
  });
42790
43066
  agent_defineProperty(_this2, "getBackendVersion", function() {
42791
- var version2 = "6.1.5-5d87cd2244";
42792
- if (version2) {
42793
- _this2._bridge.send("backendVersion", version2);
43067
+ var version3 = "6.1.5-5d87cd2244";
43068
+ if (version3) {
43069
+ _this2._bridge.send("backendVersion", version3);
42794
43070
  }
42795
43071
  });
42796
43072
  agent_defineProperty(_this2, "getBridgeProtocol", function() {
@@ -45318,7 +45594,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45318
45594
  } : function() {
45319
45595
  return Date.now();
45320
45596
  };
45321
- function getInternalReactConstants(version2) {
45597
+ function getInternalReactConstants(version3) {
45322
45598
  var ReactPriorityLevels = {
45323
45599
  ImmediatePriority: 99,
45324
45600
  UserBlockingPriority: 98,
@@ -45327,7 +45603,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45327
45603
  IdlePriority: 95,
45328
45604
  NoPriority: 90
45329
45605
  };
45330
- if (gt(version2, "17.0.2")) {
45606
+ if (gt(version3, "17.0.2")) {
45331
45607
  ReactPriorityLevels = {
45332
45608
  ImmediatePriority: 1,
45333
45609
  UserBlockingPriority: 2,
@@ -45338,15 +45614,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45338
45614
  };
45339
45615
  }
45340
45616
  var StrictModeBits = 0;
45341
- if (gte(version2, "18.0.0-alpha")) {
45617
+ if (gte(version3, "18.0.0-alpha")) {
45342
45618
  StrictModeBits = 24;
45343
- } else if (gte(version2, "16.9.0")) {
45619
+ } else if (gte(version3, "16.9.0")) {
45344
45620
  StrictModeBits = 1;
45345
- } else if (gte(version2, "16.3.0")) {
45621
+ } else if (gte(version3, "16.3.0")) {
45346
45622
  StrictModeBits = 2;
45347
45623
  }
45348
45624
  var ReactTypeOfWork = null;
45349
- if (gt(version2, "17.0.1")) {
45625
+ if (gt(version3, "17.0.1")) {
45350
45626
  ReactTypeOfWork = {
45351
45627
  CacheComponent: 24,
45352
45628
  ClassComponent: 1,
@@ -45383,7 +45659,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45383
45659
  ViewTransitionComponent: 30,
45384
45660
  ActivityComponent: 31
45385
45661
  };
45386
- } else if (gte(version2, "17.0.0-alpha")) {
45662
+ } else if (gte(version3, "17.0.0-alpha")) {
45387
45663
  ReactTypeOfWork = {
45388
45664
  CacheComponent: -1,
45389
45665
  ClassComponent: 1,
@@ -45420,7 +45696,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45420
45696
  ViewTransitionComponent: -1,
45421
45697
  ActivityComponent: -1
45422
45698
  };
45423
- } else if (gte(version2, "16.6.0-beta.0")) {
45699
+ } else if (gte(version3, "16.6.0-beta.0")) {
45424
45700
  ReactTypeOfWork = {
45425
45701
  CacheComponent: -1,
45426
45702
  ClassComponent: 1,
@@ -45457,7 +45733,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45457
45733
  ViewTransitionComponent: -1,
45458
45734
  ActivityComponent: -1
45459
45735
  };
45460
- } else if (gte(version2, "16.4.3-alpha")) {
45736
+ } else if (gte(version3, "16.4.3-alpha")) {
45461
45737
  ReactTypeOfWork = {
45462
45738
  CacheComponent: -1,
45463
45739
  ClassComponent: 2,
@@ -45743,8 +46019,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45743
46019
  }
45744
46020
  }
45745
46021
  function renderer_attach(hook, rendererID, renderer, global2, shouldStartProfilingNow, profilingSettings) {
45746
- var version2 = renderer.reconcilerVersion || renderer.version;
45747
- var _getInternalReactCons = getInternalReactConstants(version2), getDisplayNameForFiber = _getInternalReactCons.getDisplayNameForFiber, getTypeSymbol = _getInternalReactCons.getTypeSymbol, ReactPriorityLevels = _getInternalReactCons.ReactPriorityLevels, ReactTypeOfWork = _getInternalReactCons.ReactTypeOfWork, StrictModeBits = _getInternalReactCons.StrictModeBits;
46022
+ var version3 = renderer.reconcilerVersion || renderer.version;
46023
+ var _getInternalReactCons = getInternalReactConstants(version3), getDisplayNameForFiber = _getInternalReactCons.getDisplayNameForFiber, getTypeSymbol = _getInternalReactCons.getTypeSymbol, ReactPriorityLevels = _getInternalReactCons.ReactPriorityLevels, ReactTypeOfWork = _getInternalReactCons.ReactTypeOfWork, StrictModeBits = _getInternalReactCons.StrictModeBits;
45748
46024
  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;
45749
46025
  var { ImmediatePriority, UserBlockingPriority, NormalPriority, LowPriority, IdlePriority, NoPriority } = ReactPriorityLevels;
45750
46026
  var { getLaneLabelMap, injectProfilingHooks, overrideHookState, overrideHookStateDeletePath, overrideHookStateRenamePath, overrideProps, overridePropsDeletePath, overridePropsRenamePath, scheduleRefresh, setErrorHandler, setSuspenseHandler, scheduleUpdate, getCurrentFiber } = renderer;
@@ -45770,7 +46046,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45770
46046
  getLaneLabelMap,
45771
46047
  currentDispatcherRef: getDispatcherRef(renderer),
45772
46048
  workTagMap: ReactTypeOfWork,
45773
- reactVersion: version2
46049
+ reactVersion: version3
45774
46050
  });
45775
46051
  injectProfilingHooks(response.profilingHooks);
45776
46052
  getTimelineData = response.getTimelineData;
@@ -49649,8 +49925,8 @@ The error thrown in the component is:
49649
49925
  getEnvironmentNames
49650
49926
  };
49651
49927
  }
49652
- function isMatchingRender(version2) {
49653
- return !hasAssignedBackend(version2);
49928
+ function isMatchingRender(version3) {
49929
+ return !hasAssignedBackend(version3);
49654
49930
  }
49655
49931
  function attachRenderer(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings) {
49656
49932
  if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
@@ -51503,10 +51779,10 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
51503
51779
  return 3;
51504
51780
  }
51505
51781
  if ("TERM_PROGRAM" in env2) {
51506
- const version2 = Number.parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
51782
+ const version3 = Number.parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
51507
51783
  switch (env2.TERM_PROGRAM) {
51508
51784
  case "iTerm.app": {
51509
- return version2 >= 3 ? 3 : 2;
51785
+ return version3 >= 3 ? 3 : 2;
51510
51786
  }
51511
51787
  case "Apple_Terminal": {
51512
51788
  return 2;
@@ -55360,7 +55636,7 @@ var init_process_manager = __esm(() => {
55360
55636
 
55361
55637
  // src/spawner.ts
55362
55638
  import { execSync } from "node:child_process";
55363
- import { existsSync as existsSync5 } from "node:fs";
55639
+ import { existsSync as existsSync6 } from "node:fs";
55364
55640
  import { homedir as homedir5, platform as platform2 } from "node:os";
55365
55641
  import { join as join5 } from "node:path";
55366
55642
  function findClaudeCli() {
@@ -55369,12 +55645,12 @@ function findClaudeCli() {
55369
55645
  const result = execSync(command, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
55370
55646
  const claudePath = result.split(`
55371
55647
  `)[0].trim();
55372
- if (claudePath && existsSync5(claudePath)) {
55648
+ if (claudePath && existsSync6(claudePath)) {
55373
55649
  return claudePath;
55374
55650
  }
55375
55651
  } catch {}
55376
55652
  const envPath = process.env.MEET_AI_CLAUDE_PATH;
55377
- if (envPath && existsSync5(envPath)) {
55653
+ if (envPath && existsSync6(envPath)) {
55378
55654
  return envPath;
55379
55655
  }
55380
55656
  const home = homedir5();
@@ -55385,7 +55661,7 @@ function findClaudeCli() {
55385
55661
  join5(home, ".local", "bin", "claude")
55386
55662
  ];
55387
55663
  for (const path of commonPaths) {
55388
- if (existsSync5(path)) {
55664
+ if (existsSync6(path)) {
55389
55665
  return path;
55390
55666
  }
55391
55667
  }
@@ -56604,11 +56880,15 @@ var init_usecase17 = __esm(async () => {
56604
56880
 
56605
56881
  // src/index.ts
56606
56882
  init_dist();
56883
+ // package.json
56884
+ var version = "0.0.35";
56885
+
56886
+ // src/index.ts
56607
56887
  init_output();
56608
56888
  var main = defineCommand({
56609
56889
  meta: {
56610
56890
  name: "meet-ai",
56611
- version: "0.0.33",
56891
+ version,
56612
56892
  description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
56613
56893
  },
56614
56894
  args: {
@@ -56639,7 +56919,7 @@ var main = defineCommand({
56639
56919
  if (hasSubcommand)
56640
56920
  return;
56641
56921
  try {
56642
- const { getClient: getClient2 } = await Promise.resolve().then(() => (init_client_factory(), exports_client_factory));
56922
+ const { getClient: getClient2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
56643
56923
  const { getMeetAiConfig: getMeetAiConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
56644
56924
  const { startDashboard: startDashboard2 } = await init_usecase17().then(() => exports_usecase2);
56645
56925
  const client = getClient2();