@meet-ai/cli 0.0.34 → 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 +827 -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
  };
@@ -15753,7 +16027,7 @@ __export(exports_command6, {
15753
16027
  var command_default6;
15754
16028
  var init_command6 = __esm(() => {
15755
16029
  init_dist();
15756
- init_client_factory();
16030
+ init_bootstrap();
15757
16031
  init_usecase6();
15758
16032
  init_output();
15759
16033
  command_default6 = defineCommand({
@@ -15796,6 +16070,7 @@ var init_command6 = __esm(() => {
15796
16070
  run({ args }) {
15797
16071
  try {
15798
16072
  const client = getClient();
16073
+ const container2 = getContainer();
15799
16074
  listen(client, {
15800
16075
  roomId: args.roomId,
15801
16076
  exclude: args.exclude,
@@ -15803,7 +16078,7 @@ var init_command6 = __esm(() => {
15803
16078
  team: args.team,
15804
16079
  inbox: args.inbox,
15805
16080
  stdinPane: args["stdin-pane"]
15806
- });
16081
+ }, container2.inboxRouter);
15807
16082
  } catch (error48) {
15808
16083
  err(error48 instanceof Error ? error48.message : String(error48));
15809
16084
  process.exit(1);
@@ -15848,7 +16123,7 @@ __export(exports_command7, {
15848
16123
  var command_default7;
15849
16124
  var init_command7 = __esm(() => {
15850
16125
  init_dist();
15851
- init_client_factory();
16126
+ init_bootstrap();
15852
16127
  init_usecase7();
15853
16128
  init_output();
15854
16129
  command_default7 = defineCommand({
@@ -15916,7 +16191,7 @@ __export(exports_command8, {
15916
16191
  var command_default8;
15917
16192
  var init_command8 = __esm(() => {
15918
16193
  init_dist();
15919
- init_client_factory();
16194
+ init_bootstrap();
15920
16195
  init_usecase8();
15921
16196
  init_output();
15922
16197
  command_default8 = defineCommand({
@@ -15977,7 +16252,7 @@ __export(exports_command9, {
15977
16252
  var command_default9;
15978
16253
  var init_command9 = __esm(() => {
15979
16254
  init_dist();
15980
- init_client_factory();
16255
+ init_bootstrap();
15981
16256
  init_usecase9();
15982
16257
  init_output();
15983
16258
  command_default9 = defineCommand({
@@ -16020,7 +16295,7 @@ __export(exports_command10, {
16020
16295
  var command_default10;
16021
16296
  var init_command10 = __esm(() => {
16022
16297
  init_dist();
16023
- init_client_factory();
16298
+ init_bootstrap();
16024
16299
  init_output();
16025
16300
  command_default10 = defineCommand({
16026
16301
  meta: {
@@ -16481,14 +16756,14 @@ var createProxy = (callback, path) => {
16481
16756
  }
16482
16757
  return req;
16483
16758
  }, []);
16484
- var init_client2 = __esm(() => {
16759
+ var init_client = __esm(() => {
16485
16760
  init_cookie();
16486
16761
  init_utils();
16487
16762
  });
16488
16763
 
16489
16764
  // ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/index.js
16490
- var init_client3 = __esm(() => {
16491
- init_client2();
16765
+ var init_client2 = __esm(() => {
16766
+ init_client();
16492
16767
  init_utils();
16493
16768
  });
16494
16769
 
@@ -16542,15 +16817,15 @@ async function sendLogEntry(client, roomId, summary, messageId) {
16542
16817
  } catch {}
16543
16818
  }
16544
16819
  var HOOK_COLOR = "#6b7280", HOOK_SENDER = "hook";
16545
- var init_client4 = __esm(() => {
16546
- init_client3();
16820
+ var init_client3 = __esm(() => {
16821
+ init_client2();
16547
16822
  });
16548
16823
 
16549
16824
  // src/lib/hooks/index.ts
16550
16825
  var init_hooks = __esm(() => {
16551
16826
  init_find_room();
16552
16827
  init_summarize();
16553
- init_client4();
16828
+ init_client3();
16554
16829
  });
16555
16830
 
16556
16831
  // src/commands/hook/log-tool-use/usecase.ts
@@ -16852,7 +17127,7 @@ async function processPlanReview(rawInput, teamsDir) {
16852
17127
  }
16853
17128
  var POLL_INTERVAL_MS = 2000, POLL_TIMEOUT_MS = 2592000000;
16854
17129
  var init_usecase11 = __esm(() => {
16855
- init_client4();
17130
+ init_client3();
16856
17131
  init_find_room();
16857
17132
  });
16858
17133
 
@@ -17048,7 +17323,7 @@ async function processQuestionReview(rawInput, teamsDir, opts) {
17048
17323
  }
17049
17324
  var POLL_INTERVAL_MS2 = 2000, POLL_TIMEOUT_MS2 = 1800000;
17050
17325
  var init_usecase12 = __esm(() => {
17051
- init_client4();
17326
+ init_client3();
17052
17327
  init_find_room();
17053
17328
  });
17054
17329
 
@@ -17246,7 +17521,7 @@ async function processPermissionReview(rawInput, teamsDir, opts) {
17246
17521
  }
17247
17522
  var POLL_INTERVAL_MS3 = 2000, POLL_TIMEOUT_MS3 = 1800000;
17248
17523
  var init_usecase13 = __esm(() => {
17249
- init_client4();
17524
+ init_client3();
17250
17525
  init_find_room();
17251
17526
  });
17252
17527
 
@@ -17303,7 +17578,7 @@ var init_command15 = __esm(() => {
17303
17578
  });
17304
17579
 
17305
17580
  // src/commands/setup-hooks/usecase.ts
17306
- import { existsSync as existsSync2 } from "node:fs";
17581
+ import { existsSync as existsSync3 } from "node:fs";
17307
17582
  import { readFile, writeFile, mkdir } from "node:fs/promises";
17308
17583
  import { homedir as homedir2 } from "node:os";
17309
17584
  import { resolve as resolve2, dirname as dirname2 } from "node:path";
@@ -17317,7 +17592,7 @@ function getSettingsPath(project) {
17317
17592
  return resolve2(homedir2(), ".claude", "settings.json");
17318
17593
  }
17319
17594
  async function readSettings(path) {
17320
- if (!existsSync2(path)) {
17595
+ if (!existsSync3(path)) {
17321
17596
  return {};
17322
17597
  }
17323
17598
  const raw = await readFile(path, "utf-8");
@@ -17525,7 +17800,7 @@ var init_command16 = __esm(() => {
17525
17800
  });
17526
17801
 
17527
17802
  // src/commands/list-commands/usecase.ts
17528
- import { existsSync as existsSync3 } from "node:fs";
17803
+ import { existsSync as existsSync4 } from "node:fs";
17529
17804
  import { readFile as readFile2, readdir } from "node:fs/promises";
17530
17805
  import { homedir as homedir3 } from "node:os";
17531
17806
  import { join as join3, resolve as resolve3 } from "node:path";
@@ -17545,7 +17820,7 @@ function parseYamlFrontmatter(content) {
17545
17820
  }
17546
17821
  async function readSkillsFromDir(baseDir, source, scope) {
17547
17822
  const skillsDir = join3(baseDir, "skills");
17548
- if (!existsSync3(skillsDir))
17823
+ if (!existsSync4(skillsDir))
17549
17824
  return [];
17550
17825
  let entries;
17551
17826
  try {
@@ -17556,7 +17831,7 @@ async function readSkillsFromDir(baseDir, source, scope) {
17556
17831
  const results = [];
17557
17832
  for (const entry of entries) {
17558
17833
  const skillFile = join3(skillsDir, entry, "SKILL.md");
17559
- if (!existsSync3(skillFile))
17834
+ if (!existsSync4(skillFile))
17560
17835
  continue;
17561
17836
  try {
17562
17837
  const content = await readFile2(skillFile, "utf-8");
@@ -17579,7 +17854,7 @@ async function readSkillsFromDir(baseDir, source, scope) {
17579
17854
  return results;
17580
17855
  }
17581
17856
  async function readCommandsFromDir(commandsDir, source, scope) {
17582
- if (!existsSync3(commandsDir))
17857
+ if (!existsSync4(commandsDir))
17583
17858
  return [];
17584
17859
  const results = [];
17585
17860
  async function scanDir(dir) {
@@ -17617,7 +17892,7 @@ async function readCommandsFromDir(commandsDir, source, scope) {
17617
17892
  return results;
17618
17893
  }
17619
17894
  async function readSettings2(settingsPath) {
17620
- if (!existsSync3(settingsPath))
17895
+ if (!existsSync4(settingsPath))
17621
17896
  return {};
17622
17897
  try {
17623
17898
  const raw = await readFile2(settingsPath, "utf-8");
@@ -17627,7 +17902,7 @@ async function readSettings2(settingsPath) {
17627
17902
  }
17628
17903
  }
17629
17904
  async function readInstalledPlugins(pluginsFile) {
17630
- if (!existsSync3(pluginsFile))
17905
+ if (!existsSync4(pluginsFile))
17631
17906
  return {};
17632
17907
  try {
17633
17908
  const raw = await readFile2(pluginsFile, "utf-8");
@@ -17731,7 +18006,7 @@ __export(exports_command18, {
17731
18006
  var command_default18;
17732
18007
  var init_command18 = __esm(() => {
17733
18008
  init_dist();
17734
- init_client_factory();
18009
+ init_bootstrap();
17735
18010
  init_usecase16();
17736
18011
  init_output();
17737
18012
  command_default18 = defineCommand({
@@ -27010,11 +27285,11 @@ https://react.dev/link/unsafe-component-lifecycles`, _instance, newApiName, stat
27010
27285
  function updateHostContainer(current2, workInProgress2) {
27011
27286
  if (supportsPersistence && doesRequireClone(current2, workInProgress2)) {
27012
27287
  current2 = workInProgress2.stateNode;
27013
- var container = current2.containerInfo, newChildSet = createContainerChildSet();
27288
+ var container2 = current2.containerInfo, newChildSet = createContainerChildSet();
27014
27289
  appendAllChildrenToContainer(newChildSet, workInProgress2, false, false);
27015
27290
  current2.pendingChildren = newChildSet;
27016
27291
  markUpdate(workInProgress2);
27017
- finalizeContainerChildren(container, newChildSet);
27292
+ finalizeContainerChildren(container2, newChildSet);
27018
27293
  }
27019
27294
  }
27020
27295
  function updateHostComponent(current2, workInProgress2, type, newProps) {
@@ -30276,27 +30551,27 @@ Check the render method of \`` + fiberTag + "`.");
30276
30551
  parentComponent = emptyContextObject;
30277
30552
  return parentComponent;
30278
30553
  }
30279
- function updateContainerSync(element, container, parentComponent, callback) {
30280
- updateContainerImpl(container.current, 2, element, container, parentComponent, callback);
30554
+ function updateContainerSync(element, container2, parentComponent, callback) {
30555
+ updateContainerImpl(container2.current, 2, element, container2, parentComponent, callback);
30281
30556
  return 2;
30282
30557
  }
30283
- function updateContainerImpl(rootFiber, lane, element, container, parentComponent, callback) {
30558
+ function updateContainerImpl(rootFiber, lane, element, container2, parentComponent, callback) {
30284
30559
  if (injectedHook && typeof injectedHook.onScheduleFiberRoot === "function")
30285
30560
  try {
30286
- injectedHook.onScheduleFiberRoot(rendererID, container, element);
30561
+ injectedHook.onScheduleFiberRoot(rendererID, container2, element);
30287
30562
  } catch (err2) {
30288
30563
  hasLoggedError || (hasLoggedError = true, console.error("React instrumentation encountered an error: %o", err2));
30289
30564
  }
30290
30565
  parentComponent = getContextForSubtree(parentComponent);
30291
- container.context === null ? container.context = parentComponent : container.pendingContext = parentComponent;
30566
+ container2.context === null ? container2.context = parentComponent : container2.pendingContext = parentComponent;
30292
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.
30293
30568
 
30294
30569
  Check the render method of %s.`, getComponentNameFromFiber(current) || "Unknown"));
30295
- container = createUpdate(lane);
30296
- container.payload = { element };
30570
+ container2 = createUpdate(lane);
30571
+ container2.payload = { element };
30297
30572
  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), container.callback = callback);
30299
- 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);
30300
30575
  element !== null && (startUpdateTimerByLane(lane, "root.render()", null), scheduleUpdateOnFiber(element, rootFiber, lane), entangleTransitions(element, rootFiber, lane));
30301
30576
  }
30302
30577
  function markRetryLaneImpl(fiber, retryLane) {
@@ -32056,16 +32331,16 @@ No matching component was found for:
32056
32331
  }
32057
32332
  return null;
32058
32333
  };
32059
- exports2.getPublicRootInstance = function(container) {
32060
- container = container.current;
32061
- if (!container.child)
32334
+ exports2.getPublicRootInstance = function(container2) {
32335
+ container2 = container2.current;
32336
+ if (!container2.child)
32062
32337
  return null;
32063
- switch (container.child.tag) {
32338
+ switch (container2.child.tag) {
32064
32339
  case 27:
32065
32340
  case 5:
32066
- return getPublicInstance(container.child.stateNode);
32341
+ return getPublicInstance(container2.child.stateNode);
32067
32342
  default:
32068
- return container.child.stateNode;
32343
+ return container2.child.stateNode;
32069
32344
  }
32070
32345
  };
32071
32346
  exports2.injectIntoDevTools = function() {
@@ -32137,9 +32412,9 @@ No matching component was found for:
32137
32412
  return action(formData);
32138
32413
  });
32139
32414
  };
32140
- exports2.updateContainer = function(element, container, parentComponent, callback) {
32141
- var current2 = container.current, lane = requestUpdateLane(current2);
32142
- 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);
32143
32418
  return lane;
32144
32419
  };
32145
32420
  exports2.updateContainerSync = updateContainerSync;
@@ -36562,7 +36837,7 @@ var require_websocket_server = __commonJS((exports, module) => {
36562
36837
  socket.on("error", socketOnError);
36563
36838
  const key = req.headers["sec-websocket-key"];
36564
36839
  const upgrade = req.headers.upgrade;
36565
- const version2 = +req.headers["sec-websocket-version"];
36840
+ const version3 = +req.headers["sec-websocket-version"];
36566
36841
  if (req.method !== "GET") {
36567
36842
  const message = "Invalid HTTP method";
36568
36843
  abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);
@@ -36578,7 +36853,7 @@ var require_websocket_server = __commonJS((exports, module) => {
36578
36853
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
36579
36854
  return;
36580
36855
  }
36581
- if (version2 !== 13 && version2 !== 8) {
36856
+ if (version3 !== 13 && version3 !== 8) {
36582
36857
  const message = "Missing or invalid Sec-WebSocket-Version header";
36583
36858
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
36584
36859
  "Sec-WebSocket-Version": "13, 8"
@@ -36618,7 +36893,7 @@ var require_websocket_server = __commonJS((exports, module) => {
36618
36893
  }
36619
36894
  if (this.options.verifyClient) {
36620
36895
  const info2 = {
36621
- origin: req.headers[`${version2 === 8 ? "sec-websocket-origin" : "origin"}`],
36896
+ origin: req.headers[`${version3 === 8 ? "sec-websocket-origin" : "origin"}`],
36622
36897
  secure: !!(req.socket.authorized || req.socket.encrypted),
36623
36898
  req
36624
36899
  };
@@ -39453,20 +39728,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
39453
39728
  }
39454
39729
  return 0;
39455
39730
  };
39456
- var validate2 = function validate3(version2) {
39457
- 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);
39458
39733
  };
39459
39734
  var compare = function compare2(v1, v2, operator) {
39460
39735
  assertValidOperator(operator);
39461
39736
  var res = compareVersions(v1, v2);
39462
39737
  return operatorResMap[operator].includes(res);
39463
39738
  };
39464
- var satisfies = function satisfies2(version2, range) {
39739
+ var satisfies = function satisfies2(version3, range) {
39465
39740
  var m = range.match(/^([<>=~^]+)/);
39466
39741
  var op = m ? m[1] : "=";
39467
39742
  if (op !== "^" && op !== "~")
39468
- return compare(version2, range, op);
39469
- 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];
39470
39745
  var _validateAndParse3 = validateAndParse(range), _validateAndParse4 = _slicedToArray(_validateAndParse3, 5), r1 = _validateAndParse4[0], r2 = _validateAndParse4[1], r3 = _validateAndParse4[2], rp = _validateAndParse4[4];
39471
39746
  var v = [v1, v2, v3];
39472
39747
  var r = [r1, r2 !== null && r2 !== undefined ? r2 : "x", r3 !== null && r3 !== undefined ? r3 : "x"];
@@ -39489,13 +39764,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
39489
39764
  return true;
39490
39765
  };
39491
39766
  var semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
39492
- var validateAndParse = function validateAndParse2(version2) {
39493
- if (typeof version2 !== "string") {
39767
+ var validateAndParse = function validateAndParse2(version3) {
39768
+ if (typeof version3 !== "string") {
39494
39769
  throw new TypeError("Invalid argument expected string");
39495
39770
  }
39496
- var match = version2.match(semver);
39771
+ var match = version3.match(semver);
39497
39772
  if (!match) {
39498
- throw new Error("Invalid argument not valid semver ('".concat(version2, "' received)"));
39773
+ throw new Error("Invalid argument not valid semver ('".concat(version3, "' received)"));
39499
39774
  }
39500
39775
  match.shift();
39501
39776
  return match;
@@ -41129,11 +41404,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41129
41404
  return obj;
41130
41405
  }
41131
41406
  var FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER = "999.9.9";
41132
- function hasAssignedBackend(version2) {
41133
- if (version2 == null || version2 === "") {
41407
+ function hasAssignedBackend(version3) {
41408
+ if (version3 == null || version3 === "") {
41134
41409
  return false;
41135
41410
  }
41136
- return gte(version2, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
41411
+ return gte(version3, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
41137
41412
  }
41138
41413
  function cleanForBridge(data, isPathAllowed) {
41139
41414
  var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
@@ -41612,7 +41887,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41612
41887
  }
41613
41888
  var Overlay_assign = Object.assign;
41614
41889
  var OverlayRect = /* @__PURE__ */ function() {
41615
- function OverlayRect2(doc2, container) {
41890
+ function OverlayRect2(doc2, container2) {
41616
41891
  Overlay_classCallCheck(this, OverlayRect2);
41617
41892
  this.node = doc2.createElement("div");
41618
41893
  this.border = doc2.createElement("div");
@@ -41630,7 +41905,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41630
41905
  this.node.appendChild(this.border);
41631
41906
  this.border.appendChild(this.padding);
41632
41907
  this.padding.appendChild(this.content);
41633
- container.appendChild(this.node);
41908
+ container2.appendChild(this.node);
41634
41909
  }
41635
41910
  return Overlay_createClass(OverlayRect2, [{
41636
41911
  key: "remove",
@@ -41657,7 +41932,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41657
41932
  }]);
41658
41933
  }();
41659
41934
  var OverlayTip = /* @__PURE__ */ function() {
41660
- function OverlayTip2(doc2, container) {
41935
+ function OverlayTip2(doc2, container2) {
41661
41936
  Overlay_classCallCheck(this, OverlayTip2);
41662
41937
  this.tip = doc2.createElement("div");
41663
41938
  Overlay_assign(this.tip.style, {
@@ -41687,7 +41962,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
41687
41962
  color: "#d7d7d7"
41688
41963
  });
41689
41964
  this.tip.style.zIndex = "10000000";
41690
- container.appendChild(this.tip);
41965
+ container2.appendChild(this.tip);
41691
41966
  }
41692
41967
  return Overlay_createClass(OverlayTip2, [{
41693
41968
  key: "remove",
@@ -42789,9 +43064,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
42789
43064
  }
42790
43065
  });
42791
43066
  agent_defineProperty(_this2, "getBackendVersion", function() {
42792
- var version2 = "6.1.5-5d87cd2244";
42793
- if (version2) {
42794
- _this2._bridge.send("backendVersion", version2);
43067
+ var version3 = "6.1.5-5d87cd2244";
43068
+ if (version3) {
43069
+ _this2._bridge.send("backendVersion", version3);
42795
43070
  }
42796
43071
  });
42797
43072
  agent_defineProperty(_this2, "getBridgeProtocol", function() {
@@ -45319,7 +45594,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45319
45594
  } : function() {
45320
45595
  return Date.now();
45321
45596
  };
45322
- function getInternalReactConstants(version2) {
45597
+ function getInternalReactConstants(version3) {
45323
45598
  var ReactPriorityLevels = {
45324
45599
  ImmediatePriority: 99,
45325
45600
  UserBlockingPriority: 98,
@@ -45328,7 +45603,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45328
45603
  IdlePriority: 95,
45329
45604
  NoPriority: 90
45330
45605
  };
45331
- if (gt(version2, "17.0.2")) {
45606
+ if (gt(version3, "17.0.2")) {
45332
45607
  ReactPriorityLevels = {
45333
45608
  ImmediatePriority: 1,
45334
45609
  UserBlockingPriority: 2,
@@ -45339,15 +45614,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45339
45614
  };
45340
45615
  }
45341
45616
  var StrictModeBits = 0;
45342
- if (gte(version2, "18.0.0-alpha")) {
45617
+ if (gte(version3, "18.0.0-alpha")) {
45343
45618
  StrictModeBits = 24;
45344
- } else if (gte(version2, "16.9.0")) {
45619
+ } else if (gte(version3, "16.9.0")) {
45345
45620
  StrictModeBits = 1;
45346
- } else if (gte(version2, "16.3.0")) {
45621
+ } else if (gte(version3, "16.3.0")) {
45347
45622
  StrictModeBits = 2;
45348
45623
  }
45349
45624
  var ReactTypeOfWork = null;
45350
- if (gt(version2, "17.0.1")) {
45625
+ if (gt(version3, "17.0.1")) {
45351
45626
  ReactTypeOfWork = {
45352
45627
  CacheComponent: 24,
45353
45628
  ClassComponent: 1,
@@ -45384,7 +45659,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45384
45659
  ViewTransitionComponent: 30,
45385
45660
  ActivityComponent: 31
45386
45661
  };
45387
- } else if (gte(version2, "17.0.0-alpha")) {
45662
+ } else if (gte(version3, "17.0.0-alpha")) {
45388
45663
  ReactTypeOfWork = {
45389
45664
  CacheComponent: -1,
45390
45665
  ClassComponent: 1,
@@ -45421,7 +45696,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45421
45696
  ViewTransitionComponent: -1,
45422
45697
  ActivityComponent: -1
45423
45698
  };
45424
- } else if (gte(version2, "16.6.0-beta.0")) {
45699
+ } else if (gte(version3, "16.6.0-beta.0")) {
45425
45700
  ReactTypeOfWork = {
45426
45701
  CacheComponent: -1,
45427
45702
  ClassComponent: 1,
@@ -45458,7 +45733,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45458
45733
  ViewTransitionComponent: -1,
45459
45734
  ActivityComponent: -1
45460
45735
  };
45461
- } else if (gte(version2, "16.4.3-alpha")) {
45736
+ } else if (gte(version3, "16.4.3-alpha")) {
45462
45737
  ReactTypeOfWork = {
45463
45738
  CacheComponent: -1,
45464
45739
  ClassComponent: 2,
@@ -45744,8 +46019,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45744
46019
  }
45745
46020
  }
45746
46021
  function renderer_attach(hook, rendererID, renderer, global2, shouldStartProfilingNow, profilingSettings) {
45747
- var version2 = renderer.reconcilerVersion || renderer.version;
45748
- 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;
45749
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;
45750
46025
  var { ImmediatePriority, UserBlockingPriority, NormalPriority, LowPriority, IdlePriority, NoPriority } = ReactPriorityLevels;
45751
46026
  var { getLaneLabelMap, injectProfilingHooks, overrideHookState, overrideHookStateDeletePath, overrideHookStateRenamePath, overrideProps, overridePropsDeletePath, overridePropsRenamePath, scheduleRefresh, setErrorHandler, setSuspenseHandler, scheduleUpdate, getCurrentFiber } = renderer;
@@ -45771,7 +46046,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
45771
46046
  getLaneLabelMap,
45772
46047
  currentDispatcherRef: getDispatcherRef(renderer),
45773
46048
  workTagMap: ReactTypeOfWork,
45774
- reactVersion: version2
46049
+ reactVersion: version3
45775
46050
  });
45776
46051
  injectProfilingHooks(response.profilingHooks);
45777
46052
  getTimelineData = response.getTimelineData;
@@ -49650,8 +49925,8 @@ The error thrown in the component is:
49650
49925
  getEnvironmentNames
49651
49926
  };
49652
49927
  }
49653
- function isMatchingRender(version2) {
49654
- return !hasAssignedBackend(version2);
49928
+ function isMatchingRender(version3) {
49929
+ return !hasAssignedBackend(version3);
49655
49930
  }
49656
49931
  function attachRenderer(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings) {
49657
49932
  if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
@@ -51504,10 +51779,10 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
51504
51779
  return 3;
51505
51780
  }
51506
51781
  if ("TERM_PROGRAM" in env2) {
51507
- const version2 = Number.parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
51782
+ const version3 = Number.parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
51508
51783
  switch (env2.TERM_PROGRAM) {
51509
51784
  case "iTerm.app": {
51510
- return version2 >= 3 ? 3 : 2;
51785
+ return version3 >= 3 ? 3 : 2;
51511
51786
  }
51512
51787
  case "Apple_Terminal": {
51513
51788
  return 2;
@@ -55361,7 +55636,7 @@ var init_process_manager = __esm(() => {
55361
55636
 
55362
55637
  // src/spawner.ts
55363
55638
  import { execSync } from "node:child_process";
55364
- import { existsSync as existsSync5 } from "node:fs";
55639
+ import { existsSync as existsSync6 } from "node:fs";
55365
55640
  import { homedir as homedir5, platform as platform2 } from "node:os";
55366
55641
  import { join as join5 } from "node:path";
55367
55642
  function findClaudeCli() {
@@ -55370,12 +55645,12 @@ function findClaudeCli() {
55370
55645
  const result = execSync(command, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
55371
55646
  const claudePath = result.split(`
55372
55647
  `)[0].trim();
55373
- if (claudePath && existsSync5(claudePath)) {
55648
+ if (claudePath && existsSync6(claudePath)) {
55374
55649
  return claudePath;
55375
55650
  }
55376
55651
  } catch {}
55377
55652
  const envPath = process.env.MEET_AI_CLAUDE_PATH;
55378
- if (envPath && existsSync5(envPath)) {
55653
+ if (envPath && existsSync6(envPath)) {
55379
55654
  return envPath;
55380
55655
  }
55381
55656
  const home = homedir5();
@@ -55386,7 +55661,7 @@ function findClaudeCli() {
55386
55661
  join5(home, ".local", "bin", "claude")
55387
55662
  ];
55388
55663
  for (const path of commonPaths) {
55389
- if (existsSync5(path)) {
55664
+ if (existsSync6(path)) {
55390
55665
  return path;
55391
55666
  }
55392
55667
  }
@@ -56605,11 +56880,15 @@ var init_usecase17 = __esm(async () => {
56605
56880
 
56606
56881
  // src/index.ts
56607
56882
  init_dist();
56883
+ // package.json
56884
+ var version = "0.0.35";
56885
+
56886
+ // src/index.ts
56608
56887
  init_output();
56609
56888
  var main = defineCommand({
56610
56889
  meta: {
56611
56890
  name: "meet-ai",
56612
- version: "0.0.34",
56891
+ version,
56613
56892
  description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
56614
56893
  },
56615
56894
  args: {
@@ -56640,7 +56919,7 @@ var main = defineCommand({
56640
56919
  if (hasSubcommand)
56641
56920
  return;
56642
56921
  try {
56643
- 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));
56644
56923
  const { getMeetAiConfig: getMeetAiConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
56645
56924
  const { startDashboard: startDashboard2 } = await init_usecase17().then(() => exports_usecase2);
56646
56925
  const client = getClient2();