@rubytech/create-maxy-code 0.1.378 → 0.1.379

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 (40) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3 -3
  3. package/payload/platform/plugins/docs/references/admin-ui.md +2 -2
  4. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +13 -0
  5. package/payload/server/{chunk-AQO6KLIH.js → chunk-ZYS5V5QG.js} +0 -21
  6. package/payload/server/maxy-edge.js +1 -1
  7. package/payload/server/public/assets/{AdminLoginScreens-B9u1V35g.js → AdminLoginScreens-BHo8w_9J.js} +1 -1
  8. package/payload/server/public/assets/AdminShell-DbTijFVA.js +1 -0
  9. package/payload/server/public/assets/{Checkbox-B2g2SCpw.js → Checkbox-LmjNFccS.js} +1 -1
  10. package/payload/server/public/assets/admin-BBWILfl8.js +1 -0
  11. package/payload/server/public/assets/{browser-B8omhYsK.js → browser-DtLvD_ES.js} +1 -1
  12. package/payload/server/public/assets/calendar-D3i4IqOV.js +1 -0
  13. package/payload/server/public/assets/chat-DU-T6blN.js +1 -0
  14. package/payload/server/public/assets/data-B_vDxQrO.js +1 -0
  15. package/payload/server/public/assets/{graph-DJOKFr_s.js → graph-ClQeGEH4.js} +3 -3
  16. package/payload/server/public/assets/{graph-labels-DFdBydWC.js → graph-labels-OaIKHgMg.js} +1 -1
  17. package/payload/server/public/assets/operator-Dxqfta5U.js +1 -0
  18. package/payload/server/public/assets/{page-BMeSKYGZ.js → page-BkIb7CHh.js} +4 -4
  19. package/payload/server/public/assets/page-Dv_YEOUW.js +1 -0
  20. package/payload/server/public/assets/{public-CGl0i1f-.js → public-C_mM8sSZ.js} +1 -1
  21. package/payload/server/public/assets/{rotate-ccw-Cg_V4XIU.js → rotate-ccw-VF0b6NTt.js} +1 -1
  22. package/payload/server/public/assets/useSubAccountSwitcher-CQbgG-FH.js +9 -0
  23. package/payload/server/public/assets/{useSubAccountSwitcher-Ca1GJeBC.css → useSubAccountSwitcher-VzvzZC7h.css} +1 -1
  24. package/payload/server/public/browser.html +4 -4
  25. package/payload/server/public/calendar.html +4 -4
  26. package/payload/server/public/chat.html +6 -6
  27. package/payload/server/public/data.html +5 -5
  28. package/payload/server/public/graph.html +7 -7
  29. package/payload/server/public/index.html +8 -8
  30. package/payload/server/public/operator.html +8 -8
  31. package/payload/server/public/public.html +6 -6
  32. package/payload/server/server.js +247 -72
  33. package/payload/server/public/assets/AdminShell-C2UXTLSB.js +0 -1
  34. package/payload/server/public/assets/admin-CRBQgWsm.js +0 -1
  35. package/payload/server/public/assets/calendar-Blb-5arm.js +0 -1
  36. package/payload/server/public/assets/chat--1ajLxwi.js +0 -1
  37. package/payload/server/public/assets/data-BYUmu98z.js +0 -1
  38. package/payload/server/public/assets/operator-DUVqlubZ.js +0 -1
  39. package/payload/server/public/assets/page-DBkTNfei.js +0 -1
  40. package/payload/server/public/assets/useSubAccountSwitcher-DAgBUed_.js +0 -9
@@ -72,7 +72,6 @@ import {
72
72
  loadAdminUserName,
73
73
  loadPersonNameByElementId,
74
74
  loadUserProfile,
75
- loadWhatsappSenderName,
76
75
  migrateLegacyRemotePassword,
77
76
  persistMessage,
78
77
  projectAgent,
@@ -110,7 +109,7 @@ import {
110
109
  vncLog,
111
110
  walkPremiumBundles,
112
111
  writeAdminUserAndPerson
113
- } from "./chunk-AQO6KLIH.js";
112
+ } from "./chunk-ZYS5V5QG.js";
114
113
  import {
115
114
  __commonJS,
116
115
  __toESM
@@ -1869,6 +1868,24 @@ function readSelfId(authDir) {
1869
1868
  return { e164: null, jid: null, lid: null };
1870
1869
  }
1871
1870
  }
1871
+ function credsCensus(authDir) {
1872
+ const raw = readCredsJsonRaw(resolveCredsPath(authDir));
1873
+ if (!raw) return { credsPresent: false, registered: false, hasAccountSignature: false, e164: null };
1874
+ try {
1875
+ const parsed = JSON.parse(raw);
1876
+ const registered = parsed?.registered === true;
1877
+ const hasAccountSignature = parsed?.account != null;
1878
+ let e164 = null;
1879
+ const jid = parsed?.me?.id;
1880
+ if (jid) {
1881
+ const match = jid.match(/^(\d+)(?::\d+)?@s\.whatsapp\.net$/i);
1882
+ if (match) e164 = match[1];
1883
+ }
1884
+ return { credsPresent: true, registered, hasAccountSignature, e164 };
1885
+ } catch {
1886
+ return { credsPresent: true, registered: false, hasAccountSignature: false, e164: null };
1887
+ }
1888
+ }
1872
1889
  async function clearAuth(authDir) {
1873
1890
  try {
1874
1891
  await fs.access(authDir);
@@ -2027,13 +2044,22 @@ function enqueueSaveCreds(authDir, saveCreds) {
2027
2044
  });
2028
2045
  }
2029
2046
  async function createWaSocket(opts) {
2030
- const { authDir, onQr, onConnectionUpdate, silent } = opts;
2047
+ const { authDir, onQr, onConnectionUpdate, silent, correlationId, account, getCodeIssuedTs } = opts;
2048
+ const cid = correlationId ?? "none";
2049
+ const acct = account ?? "unknown";
2031
2050
  await fs2.mkdir(authDir, { recursive: true });
2032
2051
  maybeRestoreCredsFromBackup(authDir);
2033
2052
  const { state, saveCreds } = await useMultiFileAuthState(authDir);
2034
2053
  const { version } = await fetchLatestBaileysVersion();
2054
+ if (!silent) {
2055
+ const preCensus = credsCensus(authDir);
2056
+ console.error(
2057
+ `${TAG2} op=creds-pre cid=${cid} account=${acct} credsPresent=${preCensus.credsPresent} registered=${preCensus.registered} hasAccount=${preCensus.hasAccountSignature}`
2058
+ );
2059
+ }
2060
+ const openTs = Date.now();
2035
2061
  console.error(
2036
- `${TAG2} creating socket authDir=${authDir} baileysVersion=${baileysPkgVersion} waProtocolVersion=${version.join(".")}`
2062
+ `${TAG2} op=socket-open cid=${cid} account=${acct} baileysVersion=${baileysPkgVersion} waProtocolVersion=${version.join(".")} openTs=${openTs}`
2037
2063
  );
2038
2064
  const baileysLogger = createBaileysLogger();
2039
2065
  const sock = makeWASocket({
@@ -2054,6 +2080,9 @@ async function createWaSocket(opts) {
2054
2080
  enqueueSaveCreds(authDir, saveCreds);
2055
2081
  });
2056
2082
  let qrSequence = 0;
2083
+ let everOpen = false;
2084
+ let lastQrTs = 0;
2085
+ let pairSuccessLogged = false;
2057
2086
  sock.ev.on("connection.update", (update) => {
2058
2087
  try {
2059
2088
  const parts = [];
@@ -2069,17 +2098,40 @@ async function createWaSocket(opts) {
2069
2098
  if (!silent && parts.length > 0) {
2070
2099
  console.error(`${TAG2} connection.update ${parts.join(" ")}`);
2071
2100
  }
2101
+ if (update.qr && !silent) {
2102
+ const now = Date.now();
2103
+ const sinceLastRefMs = lastQrTs ? now - lastQrTs : null;
2104
+ lastQrTs = now;
2105
+ console.error(
2106
+ `${TAG2} op=qr cid=${cid} qr=#${qrSequence} sinceOpenMs=${now - openTs} sinceLastRefMs=${sinceLastRefMs ?? "n/a"}`
2107
+ );
2108
+ }
2109
+ if (update.isNewLogin === true && !pairSuccessLogged && !silent) {
2110
+ pairSuccessLogged = true;
2111
+ const codeIssuedTs = getCodeIssuedTs?.();
2112
+ const sinceCodeIssuedMs = codeIssuedTs ? Date.now() - codeIssuedTs : null;
2113
+ const afterCensus = credsCensus(authDir);
2114
+ console.error(
2115
+ `${TAG2} op=pair-success cid=${cid} account=${acct} sinceCodeIssuedMs=${sinceCodeIssuedMs ?? "n/a"} hasAccountAfter=${afterCensus.hasAccountSignature}`
2116
+ );
2117
+ }
2072
2118
  if (update.qr && onQr) {
2073
2119
  onQr(update.qr);
2074
2120
  }
2075
2121
  if (update.connection === "close") {
2076
2122
  const status = getStatusCode(update.lastDisconnect?.error);
2123
+ if (!silent) {
2124
+ console.error(
2125
+ `${TAG2} op=close cid=${cid} account=${acct} status=${status ?? "unknown"} reason="${formatError(update.lastDisconnect?.error)}" socketLifeMs=${Date.now() - openTs} kind=${closeKind(status, everOpen)}`
2126
+ );
2127
+ }
2077
2128
  if (status === DisconnectReason.loggedOut && !silent) {
2078
2129
  console.error(`${TAG2} session logged out (401) \u2014 re-link required`);
2079
2130
  }
2080
2131
  }
2081
- if (update.connection === "open" && !silent) {
2082
- console.error(`${TAG2} connected`);
2132
+ if (update.connection === "open") {
2133
+ everOpen = true;
2134
+ if (!silent) console.error(`${TAG2} connected`);
2083
2135
  }
2084
2136
  onConnectionUpdate?.(update);
2085
2137
  } catch (err) {
@@ -2143,6 +2195,12 @@ function extractBoomDetails(err) {
2143
2195
  if (!statusCode && !error && !message) return null;
2144
2196
  return { statusCode, error, message };
2145
2197
  }
2198
+ function closeKind(status, everOpen) {
2199
+ if (status === DisconnectReason.restartRequired) return "restart-required-515";
2200
+ if (status === DisconnectReason.loggedOut) return "logged-out-401";
2201
+ if (status === 408) return everOpen ? "conn-lost-408" : "qr-refs-ended-408";
2202
+ return "other";
2203
+ }
2146
2204
 
2147
2205
  // app/lib/whatsapp/reconnect.ts
2148
2206
  import { DisconnectReason as DisconnectReason2 } from "@whiskeysockets/baileys";
@@ -3102,6 +3160,9 @@ var STORE_ROOT = () => join3(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data",
3102
3160
  function conversationFile(platformAccountId, remoteJid) {
3103
3161
  return join3(STORE_ROOT(), platformAccountId, `${remoteJid}.jsonl`);
3104
3162
  }
3163
+ function conversationFilePath(platformAccountId, remoteJid) {
3164
+ return conversationFile(platformAccountId, remoteJid);
3165
+ }
3105
3166
  function parseLines(raw) {
3106
3167
  const out = [];
3107
3168
  for (const line of raw.split("\n")) {
@@ -6055,6 +6116,13 @@ async function runPostPairing(login) {
6055
6116
  }
6056
6117
  async function loginConnectionLoop(accountId, login) {
6057
6118
  let attempt = 0;
6119
+ const cidShort = login.id.slice(0, 8);
6120
+ const logTerminal = (outcome, errMsg) => {
6121
+ const fc = credsCensus(login.authDir);
6122
+ console.error(
6123
+ `${TAG17} op=terminal cid=${cidShort} outcome=${outcome} credsFinal={registered=${fc.registered},account=${fc.hasAccountSignature},me=${fc.e164 ?? "null"}}` + (errMsg ? ` error="${errMsg}"` : "")
6124
+ );
6125
+ };
6058
6126
  while (true) {
6059
6127
  try {
6060
6128
  await waitForConnection(login.sock);
@@ -6063,6 +6131,7 @@ async function loginConnectionLoop(accountId, login) {
6063
6131
  await runPostPairing(current);
6064
6132
  current.connected = true;
6065
6133
  console.error(`${TAG17} loginConnectionLoop: connected account=${accountId} attempt=${attempt} configPersisted=${current.configPersisted}`);
6134
+ logTerminal("connected");
6066
6135
  }
6067
6136
  return;
6068
6137
  } catch (err) {
@@ -6079,6 +6148,7 @@ async function loginConnectionLoop(accountId, login) {
6079
6148
  current.error = formatError(err);
6080
6149
  }
6081
6150
  current.errorStatus = getStatusCode(err);
6151
+ logTerminal("error", current.error);
6082
6152
  return;
6083
6153
  }
6084
6154
  attempt++;
@@ -6090,14 +6160,19 @@ async function loginConnectionLoop(accountId, login) {
6090
6160
  await new Promise((r) => setTimeout(r, delay));
6091
6161
  const afterDelay = activeLogins.get(accountId);
6092
6162
  if (afterDelay?.id !== login.id) return;
6163
+ const rc = credsCensus(login.authDir);
6164
+ console.error(
6165
+ `${TAG17} op=reconnect cid=${cidShort} attempt=${attempt}/${LOGIN_MAX_RECONNECTS} withRegistered=${rc.registered} withAccount=${rc.hasAccountSignature}`
6166
+ );
6093
6167
  try {
6094
- const newSock = await createWaSocket({ authDir: login.authDir });
6168
+ const newSock = await createWaSocket({ authDir: login.authDir, correlationId: cidShort, account: accountId });
6095
6169
  current.sock = newSock;
6096
6170
  } catch (sockErr) {
6097
6171
  console.error(
6098
6172
  `${TAG17} reconnect socket creation failed (attempt ${attempt}/${LOGIN_MAX_RECONNECTS}): ${String(sockErr)}`
6099
6173
  );
6100
6174
  current.error = `Reconnection failed: ${String(sockErr)}`;
6175
+ logTerminal("error", current.error);
6101
6176
  return;
6102
6177
  }
6103
6178
  }
@@ -6105,11 +6180,13 @@ async function loginConnectionLoop(accountId, login) {
6105
6180
  }
6106
6181
  async function startLogin(opts) {
6107
6182
  const { accountId, authDir, phone, accountDir = null, force, timeoutMs = 3e4 } = opts;
6183
+ const loginId = randomUUID6();
6184
+ const cid = loginId.slice(0, 8);
6108
6185
  const existing0 = activeLogins.get(accountId);
6109
6186
  const hasAuth = await authExists(authDir);
6110
6187
  const selfId = readSelfId(authDir);
6111
6188
  console.error(
6112
- `${TAG17} startLogin account=${accountId} force=${!!force} hasAuth=${hasAuth}` + (existing0 ? ` activeLogin={id=${existing0.id.slice(0, 8)},age=${Math.round((Date.now() - existing0.startedAt) / 1e3)}s,hasCode=${!!existing0.pairingCode}}` : " activeLogin=none")
6189
+ `${TAG17} op=start cid=${cid} account=${accountId} force=${!!force} hasAuth=${hasAuth}` + (existing0 ? ` activeLogin={id=${existing0.id.slice(0, 8)},age=${Math.round((Date.now() - existing0.startedAt) / 1e3)}s,hasCode=${!!existing0.pairingCode}}` : " activeLogin=none")
6113
6190
  );
6114
6191
  if (hasAuth && !force) {
6115
6192
  const who = selfId.e164 ?? selfId.jid ?? "unknown";
@@ -6148,21 +6225,32 @@ async function startLogin(opts) {
6148
6225
  );
6149
6226
  let requested = false;
6150
6227
  let sock;
6228
+ let socketOpenTs = 0;
6229
+ let codeIssuedTs;
6151
6230
  try {
6152
6231
  sock = await createWaSocket({
6153
6232
  authDir,
6233
+ correlationId: cid,
6234
+ account: accountId,
6235
+ getCodeIssuedTs: () => codeIssuedTs,
6154
6236
  // The first QR event means the noise handshake is complete and the
6155
6237
  // socket can send the pairing IQ — the safe moment to request the code.
6156
6238
  // We never render the QR; it is only a readiness signal.
6157
6239
  onQr: () => {
6158
6240
  if (requested) return;
6159
6241
  requested = true;
6242
+ console.error(
6243
+ `${TAG17} op=pairing-request cid=${cid} account=${accountId} qrRef=#1 sinceOpenMs=${socketOpenTs ? Date.now() - socketOpenTs : 0}`
6244
+ );
6160
6245
  void sock.requestPairingCode(digits).then((code) => {
6161
6246
  clearTimeout(codeTimer);
6247
+ codeIssuedTs = Date.now();
6162
6248
  const current = activeLogins.get(accountId);
6163
6249
  if (current?.id !== login.id) return;
6164
6250
  if (!current.pairingCode) current.pairingCode = code;
6165
- console.error(`${TAG17} pairing-code-issued account=${accountId} phone=${maskPhone(digits)} codeLen=${code.length}`);
6251
+ console.error(
6252
+ `${TAG17} op=code-issued cid=${cid} account=${accountId} phone=${maskPhone(digits)} codeLen=${code.length} sinceOpenMs=${socketOpenTs ? codeIssuedTs - socketOpenTs : 0}`
6253
+ );
6166
6254
  resolveCode?.(code);
6167
6255
  }).catch((err) => {
6168
6256
  clearTimeout(codeTimer);
@@ -6170,6 +6258,7 @@ async function startLogin(opts) {
6170
6258
  });
6171
6259
  }
6172
6260
  });
6261
+ socketOpenTs = Date.now();
6173
6262
  } catch (err) {
6174
6263
  clearTimeout(codeTimer);
6175
6264
  resetActiveLogin(accountId);
@@ -6179,7 +6268,7 @@ async function startLogin(opts) {
6179
6268
  accountId,
6180
6269
  authDir,
6181
6270
  accountDir,
6182
- id: randomUUID6(),
6271
+ id: loginId,
6183
6272
  sock,
6184
6273
  startedAt: Date.now(),
6185
6274
  phone: digits,
@@ -6474,6 +6563,10 @@ function reconcileCredsOnDisk(opts) {
6474
6563
  for (const accountId of listCredsAccountIds(credsRoot)) {
6475
6564
  if (liveAccountIds.has(accountId)) continue;
6476
6565
  const authDir = join9(credsRoot, accountId);
6566
+ const census = credsCensus(authDir);
6567
+ if (census.registered && !census.hasAccountSignature) {
6568
+ console.error(`${TAG19} op=half-registered account=${accountId} registered=true hasAccount=false`);
6569
+ }
6477
6570
  const selfPhone = readSelfId(authDir).e164 ?? void 0;
6478
6571
  const configured = accountDir ? isAccountConfigured(accountDir, accountId) : false;
6479
6572
  console.error(
@@ -6947,9 +7040,39 @@ function selectReaderChannelSessions(rows) {
6947
7040
  lastMessageAt: r.lastMessageAt,
6948
7041
  modelGated: r.modelGated,
6949
7042
  model: r.model,
6950
- rowType: "session"
7043
+ source: "session"
6951
7044
  }));
6952
7045
  }
7046
+ function buildStoreConversationRows(accountId, convos) {
7047
+ const rows = [];
7048
+ for (const [remoteJid, messages] of convos) {
7049
+ if (messages.length === 0) continue;
7050
+ const last = messages[messages.length - 1];
7051
+ const scope = last.scope;
7052
+ const isGroup = remoteJid.endsWith("@g.us");
7053
+ const senderTelephone = isGroup ? null : messages[0].senderTelephone;
7054
+ const senderName = messages.find((m) => m.senderName)?.senderName ?? null;
7055
+ rows.push({
7056
+ sessionId: "",
7057
+ projectDir: "",
7058
+ title: remoteJid,
7059
+ senderId: senderTelephone,
7060
+ startedAt: messages[0].dateSent,
7061
+ channel: "whatsapp",
7062
+ role: scope === "admin" ? "admin" : "public",
7063
+ operatorName: null,
7064
+ whatsappName: senderName,
7065
+ lastMessageAt: last.dateSent,
7066
+ modelGated: false,
7067
+ model: null,
7068
+ source: "store",
7069
+ accountId,
7070
+ remoteJid,
7071
+ scope
7072
+ });
7073
+ }
7074
+ return rows.sort((a, b) => (b.lastMessageAt ?? "").localeCompare(a.lastMessageAt ?? ""));
7075
+ }
6953
7076
 
6954
7077
  // server/routes/admin/sidebar-sessions.ts
6955
7078
  var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
@@ -7744,7 +7867,7 @@ app4.get("/conversations", requireAdminSession, async (c) => {
7744
7867
  model: lastAssistantModel(body)
7745
7868
  });
7746
7869
  }
7747
- const selected = selectReaderChannelSessions(rows);
7870
+ const sessionRows = selectReaderChannelSessions(rows).filter((r) => r.channel !== "whatsapp");
7748
7871
  const account = resolveAccount();
7749
7872
  let users = [];
7750
7873
  if (account) {
@@ -7757,13 +7880,11 @@ app4.get("/conversations", requireAdminSession, async (c) => {
7757
7880
  }
7758
7881
  const admins = account?.config.admins ?? [];
7759
7882
  const nameBySender = /* @__PURE__ */ new Map();
7760
- const whatsappNameBySender = /* @__PURE__ */ new Map();
7761
- const distinct = [...new Set(selected.map((r) => r.senderId).filter((s) => !!s))];
7883
+ const distinct = [...new Set(sessionRows.map((r) => r.senderId).filter((s) => !!s))];
7762
7884
  await Promise.all(
7763
7885
  distinct.map(async (senderId) => {
7764
7886
  if (!account) {
7765
7887
  nameBySender.set(senderId, null);
7766
- whatsappNameBySender.set(senderId, null);
7767
7888
  return;
7768
7889
  }
7769
7890
  const idRes = classifyAdminUserId(users, admins, senderId);
@@ -7771,57 +7892,19 @@ app4.get("/conversations", requireAdminSession, async (c) => {
7771
7892
  const { name, reason } = resolveOperatorDisplay(idRes, nameRes);
7772
7893
  if (reason) console.error(`[wa-reader] op=operator-unresolved senderId=${senderId} reason=${reason}`);
7773
7894
  nameBySender.set(senderId, name);
7774
- if (!name) {
7775
- const waName = await loadWhatsappSenderName(account.accountId, senderId);
7776
- if (waName) console.error(`[wa-reader] op=operator-name-fallback senderId=${senderId} source=whatsapp-pushname`);
7777
- whatsappNameBySender.set(senderId, waName);
7778
- } else {
7779
- whatsappNameBySender.set(senderId, null);
7780
- }
7781
7895
  })
7782
7896
  );
7783
- const conversations = selected.map((r) => ({
7897
+ const sessionConversations = sessionRows.map((r) => ({
7784
7898
  ...r,
7785
- operatorName: r.senderId ? nameBySender.get(r.senderId) ?? null : null,
7786
- whatsappName: r.senderId ? whatsappNameBySender.get(r.senderId) ?? null : null,
7787
- rowType: "session"
7899
+ operatorName: r.senderId ? nameBySender.get(r.senderId) ?? null : null
7788
7900
  }));
7789
- const includePersistedOnly = c.req.query("includePersistedOnly") === "1";
7790
- let persistedOnlyRows = [];
7791
- if (includePersistedOnly && account) {
7792
- const allConvos = readAllConversations(account.accountId);
7793
- const coveredSenderIds = new Set(
7794
- conversations.filter((cv) => cv.role === "public" && cv.channel === "whatsapp" && cv.senderId).map((cv) => cv.senderId)
7795
- );
7796
- for (const [remoteJid, messages] of allConvos) {
7797
- if (messages.length === 0) continue;
7798
- const isGroup = remoteJid.endsWith("@g.us");
7799
- const senderTelephone = isGroup ? null : messages[0].senderTelephone;
7800
- if (!isGroup && senderTelephone && coveredSenderIds.has(senderTelephone)) continue;
7801
- const last = messages[messages.length - 1];
7802
- const resolvedName = isGroup ? null : messages.find((m) => m.senderName)?.senderName ?? null;
7803
- persistedOnlyRows.push({
7804
- sessionId: `persisted:${account.accountId}:${remoteJid}`,
7805
- projectDir: "",
7806
- title: remoteJid,
7807
- senderId: senderTelephone,
7808
- startedAt: messages[0].dateSent,
7809
- channel: "whatsapp",
7810
- role: "public",
7811
- operatorName: null,
7812
- whatsappName: resolvedName,
7813
- lastMessageAt: last.dateSent,
7814
- modelGated: false,
7815
- model: null,
7816
- rowType: "persisted-only",
7817
- accountId: account.accountId,
7818
- remoteJid
7819
- });
7820
- }
7821
- }
7822
- const allRows = [...conversations, ...persistedOnlyRows];
7823
- console.log(`[wa-reader] op=full-list accountId=${account?.accountId ?? "null"} sessionRows=${conversations.length} persistedOnlyRows=${persistedOnlyRows.length}`);
7824
- return c.json({ conversations: allRows });
7901
+ const storeRows = account ? buildStoreConversationRows(account.accountId, readAllConversations(account.accountId)) : [];
7902
+ const adminScope = storeRows.filter((r) => r.scope === "admin").length;
7903
+ const publicScope = storeRows.length - adminScope;
7904
+ console.log(
7905
+ `[wa-reader] op=list accountId=${account?.accountId ?? "null"} conversations=${storeRows.length} adminScope=${adminScope} publicScope=${publicScope}`
7906
+ );
7907
+ return c.json({ conversations: [...sessionConversations, ...storeRows] });
7825
7908
  });
7826
7909
  function readFrom(path2, from) {
7827
7910
  const end = statSync4(path2).size;
@@ -8161,7 +8244,7 @@ app4.get("/directive", requireAdminSession, (c) => {
8161
8244
  }
8162
8245
  return c.text(body);
8163
8246
  });
8164
- app4.get("/persisted-messages", requireAdminSession, async (c) => {
8247
+ app4.get("/store-stream", requireAdminSession, (c) => {
8165
8248
  const accountIdRaw = c.req.query("accountId");
8166
8249
  const remoteJid = c.req.query("remoteJid");
8167
8250
  if (!accountIdRaw || !remoteJid) {
@@ -8176,16 +8259,108 @@ app4.get("/persisted-messages", requireAdminSession, async (c) => {
8176
8259
  if (!isUserJid(remoteJid) && !isGroupJid(remoteJid)) {
8177
8260
  return c.json({ error: "invalid remoteJid" }, 400);
8178
8261
  }
8179
- const messages = readConversation(accountId, remoteJid);
8180
- const turns = messages.map((m) => ({
8262
+ const file = conversationFilePath(accountId, remoteJid);
8263
+ const encoder = new TextEncoder();
8264
+ const connId = `${remoteJid.slice(0, 12)}-${process.hrtime.bigint().toString(36).slice(-6)}`;
8265
+ const startedAt = Date.now();
8266
+ const lastEventId = c.req.header("Last-Event-ID");
8267
+ const toTurn = (r) => ({
8181
8268
  kind: "whatsapp-persisted",
8182
- text: m.body,
8183
- ts: m.dateSent,
8184
- fromMe: m.fromMe,
8185
- senderName: m.senderName
8186
- }));
8187
- console.log(`[wa-reader] op=persisted-messages accountId=${accountId} remoteJid=${remoteJid} count=${turns.length}`);
8188
- return c.json({ turns });
8269
+ text: r.body,
8270
+ ts: r.dateSent,
8271
+ fromMe: r.fromMe,
8272
+ senderName: r.senderName
8273
+ });
8274
+ const readable = new ReadableStream({
8275
+ start(controller) {
8276
+ const send = (turn, id) => {
8277
+ try {
8278
+ controller.enqueue(encoder.encode(`id: ${id}
8279
+ data: ${JSON.stringify(turn)}
8280
+
8281
+ `));
8282
+ } catch {
8283
+ }
8284
+ };
8285
+ const fileEnd0 = (() => {
8286
+ try {
8287
+ return statSync4(file).size;
8288
+ } catch {
8289
+ return 0;
8290
+ }
8291
+ })();
8292
+ let offset = resumeOffset(lastEventId, fileEnd0);
8293
+ if (offset === 0) {
8294
+ const records = [];
8295
+ try {
8296
+ const { buf, end } = readFrom(file, 0);
8297
+ offset = end;
8298
+ for (const line of buf.toString("utf8").split("\n")) {
8299
+ if (!line.trim()) continue;
8300
+ try {
8301
+ records.push(JSON.parse(line));
8302
+ } catch {
8303
+ }
8304
+ }
8305
+ } catch {
8306
+ offset = fileEnd0;
8307
+ }
8308
+ records.sort((a, b) => a.dateSent.localeCompare(b.dateSent));
8309
+ const scope = records.length ? records[records.length - 1].scope : "none";
8310
+ for (const m of records) send(toTurn(m), offset);
8311
+ console.log(
8312
+ `[wa-reader] op=open remoteJid=${remoteJid} scope=${scope} messages=${records.length} source=store`
8313
+ );
8314
+ }
8315
+ const drain = () => {
8316
+ try {
8317
+ const { buf, end } = readFrom(file, offset);
8318
+ if (end <= offset) return;
8319
+ const { lines, nextOffset } = splitNewLines(buf, offset);
8320
+ offset = nextOffset;
8321
+ let n = 0;
8322
+ for (const line of lines) {
8323
+ if (!line.trim()) continue;
8324
+ let rec;
8325
+ try {
8326
+ rec = JSON.parse(line);
8327
+ } catch {
8328
+ continue;
8329
+ }
8330
+ send(toTurn(rec), offset);
8331
+ n++;
8332
+ }
8333
+ if (n > 0) console.log(`[wa-reader] op=store-drain conn=${connId} turns=${n}`);
8334
+ } catch {
8335
+ }
8336
+ };
8337
+ let watcher = null;
8338
+ try {
8339
+ watcher = watch(file, drain);
8340
+ } catch {
8341
+ }
8342
+ const poll = setInterval(drain, 1e3);
8343
+ const heartbeat = setInterval(() => {
8344
+ try {
8345
+ controller.enqueue(encoder.encode(": ping\n\n"));
8346
+ } catch {
8347
+ }
8348
+ }, 2e4);
8349
+ c.req.raw.signal.addEventListener("abort", () => {
8350
+ watcher?.close();
8351
+ clearInterval(poll);
8352
+ clearInterval(heartbeat);
8353
+ console.log(`[wa-reader] op=store-close conn=${connId} ranMs=${Date.now() - startedAt}`);
8354
+ try {
8355
+ controller.close();
8356
+ } catch {
8357
+ }
8358
+ });
8359
+ }
8360
+ });
8361
+ return new Response(readable, {
8362
+ headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" }
8363
+ });
8189
8364
  });
8190
8365
  var whatsapp_reader_default = app4;
8191
8366
 
@@ -1 +0,0 @@
1
- import{o as e}from"./chunk-CAM3fms7.js";import{A as t,C as n,E as r,H as i,K as a,L as o,M as s,N as c,O as l,P as u,R as d,T as f,V as p,_ as m,g as h,j as g,m as ee,n as te,q as _,t as ne,v as re,x as v,y as ie}from"./useSubAccountSwitcher-DAgBUed_.js";async function y(){try{let e=await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`logout`})});return e.ok?(await e.json().catch(()=>({})))?.logged_out===!0:(console.error(`[admin-ui] claude-logout http-status=${e.status}`),!1)}catch(e){return console.error(`[admin-ui] claude-logout fetch failed: ${e instanceof Error?e.message:String(e)}`),!1}}var b=e(_(),1),x=i(),S={sm:14,md:16,lg:18},ae={sm:30,md:38,lg:46};function C({variant:e=`primary`,size:t=`md`,icon:n,iconPosition:r=`leading`,loading:i=!1,fullWidth:a=!1,disabled:o=!1,type:s=`button`,onClick:c,"aria-label":l,style:u,className:d,children:f}){let p=[`btn`,`btn--${e}`,t===`md`?``:`btn--${t}`,a?`btn--full`:``,d].filter(Boolean).join(` `),m=S[t],h={...e===`send`?{width:ae[t],height:ae[t]}:{},...u},g=Object.keys(h).length>0;return(0,x.jsxs)(`button`,{type:s,className:p,disabled:i||o,onClick:c,"aria-label":l,style:g?h:void 0,children:[(0,x.jsxs)(`span`,{className:`btn__content`,style:{visibility:i?`hidden`:`visible`},children:[n&&r===`leading`&&(0,x.jsx)(n,{size:m}),f,n&&r===`trailing`&&(0,x.jsx)(n,{size:m})]}),i&&(0,x.jsx)(`span`,{className:`btn__spinner`,children:`✱`})]})}var w=o(`archive-restore`,[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h2`,key:`tvwodi`}],[`path`,{d:`M20 8v11a2 2 0 0 1-2 2h-2`,key:`1gkqxj`}],[`path`,{d:`m9 15 3-3 3 3`,key:`1pd0qc`}],[`path`,{d:`M12 12v9`,key:`192myk`}]]),oe=o(`archive`,[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8`,key:`1s80jp`}],[`path`,{d:`M10 12h4`,key:`a56b0p`}]]),T=o(`bot`,[[`path`,{d:`M12 8V4H8`,key:`hb8ula`}],[`rect`,{width:`16`,height:`12`,x:`4`,y:`8`,rx:`2`,key:`enze0r`}],[`path`,{d:`M2 14h2`,key:`vft8re`}],[`path`,{d:`M20 14h2`,key:`4cs60a`}],[`path`,{d:`M15 13v2`,key:`1xurst`}],[`path`,{d:`M9 13v2`,key:`rq6x2g`}]]),se=o(`box`,[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]),ce=o(`history`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]]),le=o(`list-todo`,[[`path`,{d:`M13 5h8`,key:`a7qcls`}],[`path`,{d:`M13 12h8`,key:`h98zly`}],[`path`,{d:`M13 19h8`,key:`c3s6r1`}],[`path`,{d:`m3 17 2 2 4-4`,key:`1jhpwq`}],[`rect`,{x:`3`,y:`4`,width:`6`,height:`6`,rx:`1`,key:`cif1o7`}]]),E=o(`message-square`,[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}]]),ue=o(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]),de=o(`sliders-horizontal`,[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]]),D=o(`square`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]),O=o(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),k=`maxy-shell-side-px`;function fe(){if(typeof window>`u`)return 0;let e=document.querySelector(`.platform > .artefact`)?.getBoundingClientRect();return e&&e.width>0?Math.round(e.width):0}function A(e){if(typeof window>`u`)return e;let t=window.innerWidth,n=Math.max(248,t-480-fe());return Math.min(Math.max(e,248),n)}function j(){if(typeof window>`u`)return 264;try{let e=window.localStorage.getItem(k);if(!e)return 264;let t=parseInt(e,10);if(!Number.isFinite(t))return console.warn(`[admin-ui] sidebar-width-parse-failed stored=${JSON.stringify(e)} fallback=264`),264;if(t>=248)return A(t)}catch{}return 264}function M({targetSelector:e=`.platform`}){let t=(0,b.useRef)(null),[n,r]=(0,b.useState)(()=>j()),i=(0,b.useRef)(n);(0,b.useLayoutEffect)(()=>{let t=document.querySelector(e);!t||!(t instanceof HTMLElement)||(t.style.setProperty(`--side-px`,`${n}px`),i.current=n)},[n,e]);let a=(0,b.useCallback)(()=>{r(e=>{let t=A(e);return t===e?e:t})},[]);(0,b.useEffect)(()=>{a(),window.addEventListener(`resize`,a);let t=document.querySelector(e),n=null;return t instanceof HTMLElement&&(n=new MutationObserver(a),n.observe(t,{attributes:!0,attributeFilter:[`data-artefact`,`class`]})),()=>{window.removeEventListener(`resize`,a),n?.disconnect()}},[a,e]);let o=e=>{e.preventDefault();let n=t.current;if(!n)return;n.setPointerCapture(e.pointerId),n.classList.add(`dragging`);let a=!1,o=e=>{a=!0,r(A(Math.round(e.clientX)))},s=()=>{if(n.releasePointerCapture(e.pointerId),n.classList.remove(`dragging`),window.removeEventListener(`pointermove`,o),window.removeEventListener(`pointerup`,s),!a)return;let t=i.current;try{window.localStorage.setItem(k,String(t))}catch{}console.info(`[admin-ui] sidebar-resize px=${t}`)};window.addEventListener(`pointermove`,o),window.addEventListener(`pointerup`,s)},s=()=>{let e=A(264);r(e);try{window.localStorage.removeItem(k)}catch{}console.info(`[admin-ui] sidebar-resize px=${e}`)};return(0,x.jsx)(`div`,{ref:t,className:`side-resize-handle`,role:`separator`,"aria-orientation":`vertical`,"aria-label":`Resize sidebar`,onPointerDown:o,onDoubleClick:s})}var pe=a();function me({anchorRef:e,onClose:t,className:n,role:r,ariaLabel:i,children:a}){let o=(0,b.useRef)(null),[s,c]=(0,b.useState)({position:`fixed`,visibility:`hidden`}),l=(0,b.useCallback)(()=>{let t=e.current,n=o.current;if(!t||!n)return;let r=t.getBoundingClientRect(),i=n.getBoundingClientRect(),a=r.right-i.width;a<4&&(a=4);let s=window.innerHeight-r.bottom<i.height+8&&r.top>i.height+8?r.top-i.height:r.bottom;c({position:`fixed`,left:a,top:s,visibility:`visible`})},[e]);return(0,b.useLayoutEffect)(()=>{if(l(),typeof ResizeObserver>`u`)return;let e=new ResizeObserver(()=>l());return o.current&&e.observe(o.current),()=>e.disconnect()},[l]),(0,b.useEffect)(()=>{let n=e=>{e.key===`Escape`&&t()},r=n=>{let r=n.target;e.current?.contains(r)||o.current?.contains(r)||t()},i=n=>{let r=e.current;r&&n.target instanceof Node&&n.target.contains(r)&&t()},a=()=>t();return document.addEventListener(`keydown`,n),document.addEventListener(`pointerdown`,r),window.addEventListener(`scroll`,i,!0),window.addEventListener(`resize`,a),()=>{document.removeEventListener(`keydown`,n),document.removeEventListener(`pointerdown`,r),window.removeEventListener(`scroll`,i,!0),window.removeEventListener(`resize`,a)}},[e,t]),(0,pe.createPortal)((0,x.jsx)(`div`,{ref:o,className:n,role:r,"aria-label":i,style:s,children:a}),document.body)}function N({action:e,disabled:t,open:n,onToggle:r,onClose:i}){let a=(0,b.useRef)(null);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`button`,{ref:a,type:`button`,className:`conv-action`,onClick:r,disabled:t,"aria-haspopup":`dialog`,"aria-expanded":n,"aria-label":e.label,title:e.title,children:e.icon}),n&&(0,x.jsx)(me,{anchorRef:a,onClose:i,className:e.panelClassName,role:`dialog`,ariaLabel:e.label,children:e.panel()})]})}function he({actions:e,disabled:t,collapsed:n}){let[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)(!1),[c,l]=(0,b.useState)(null),u=(0,b.useRef)(null);(0,b.useEffect)(()=>{i(null),o(!1),l(null)},[n]);let d=(0,b.useCallback)(()=>{o(!1),l(null)},[]);return n?(0,x.jsxs)(`div`,{className:`conv-actions`,children:[(0,x.jsx)(`button`,{ref:u,type:`button`,className:`conv-action conv-actions-overflow`,onClick:()=>o(e=>!e),disabled:t,"aria-haspopup":`menu`,"aria-expanded":a,"aria-label":`Session actions`,title:`Session actions`,children:(0,x.jsx)(s,{size:12})}),a&&(0,x.jsx)(me,{anchorRef:u,onClose:d,className:`conv-actions-menu`,role:`menu`,children:e.map(e=>e.panel?(0,x.jsxs)(`div`,{className:`conv-actions-menu-disclosure`,children:[(0,x.jsxs)(`button`,{type:`button`,role:`menuitem`,"aria-haspopup":`dialog`,"aria-expanded":c===e.key,disabled:t,onClick:()=>l(t=>t===e.key?null:e.key),children:[e.icon,(0,x.jsx)(`span`,{children:e.menuLabel})]}),c===e.key&&(0,x.jsx)(`div`,{className:`conv-actions-menu-panel`,children:e.panel()})]},e.key):(0,x.jsxs)(`button`,{type:`button`,role:`menuitem`,className:e.danger?`conv-action-danger`:void 0,"aria-busy":e.busy,disabled:t,onClick:t=>{e.onClick?.(t),d()},children:[e.icon,(0,x.jsx)(`span`,{children:e.menuLabel})]},e.key))})]}):(0,x.jsx)(`div`,{className:`conv-actions`,children:e.map(e=>e.panel?(0,x.jsx)(N,{action:e,disabled:t,open:r===e.key,onToggle:()=>i(t=>t===e.key?null:e.key),onClose:()=>i(null)},e.key):(0,x.jsx)(`button`,{type:`button`,className:e.danger?`conv-action conv-action-danger`:`conv-action`,onClick:e.onClick,disabled:t,"aria-busy":e.busy,"aria-label":e.label,title:e.title,children:e.icon},e.key))})}var P=`claude-opus-4-8[1m]`,F=`claude-sonnet-5`,I=`claude-haiku-4-5`,L={[P]:`Opus 4.8 (1M context)`,[F]:`Sonnet 5`,[I]:`Haiku 4.5`};function ge(e){return L[e]??e}var _e=[P,F,I];function R(e){return e.replace(/\[1m\]$/,``)}function z(e){return _e.find(t=>R(t)===R(e))??e}var ve=[`default`,`acceptEdits`,`plan`,`auto`,`bypassPermissions`],B=[`low`,`medium`,`high`,`xhigh`];[...ve],[...B],[...B];var ye=[P,F,I],be={default:`Ask permissions`,acceptEdits:`Accept edits`,plan:`Plan mode`,auto:`Auto mode`,bypassPermissions:`Bypass permissions`},xe=ve.map(e=>({value:e,label:be[e]??e})),V={low:`Low`,medium:`Medium`,high:`High`,xhigh:`Highest`},H=B.map(e=>({value:e,label:V[e]??e}));function Se(e){if(e){let t=ye.find(t=>R(t)===R(e));if(t)return t}return P}function Ce({row:e,adminFetch:t,onError:n}){let[r,i]=(0,b.useState)(()=>Se(e.model)),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(``),[u,d]=(0,b.useState)(!1),f=(0,b.useRef)(!1);(0,b.useEffect)(()=>{i(Se(e.model))},[e.model]);let p=async()=>{if(!f.current){f.current=!0,d(!0);try{let i=await t(`/api/admin/session-reseat`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({fromSessionId:e.sessionId,model:r,...a?{permissionMode:a}:{},...s?{effort:s}:{}})});if(!i.ok){n(`Could not reset ${e.title} (status ${i.status})`),console.error(`[admin-ui] dashboard-reseat-failed sessionId=${e.sessionId} status=${i.status}`),f.current=!1,d(!1);return}let o=await i.json().catch(()=>({}));o.target?window.location.assign(o.target):(n(`Reset of ${e.title} returned no target`),f.current=!1,d(!1))}catch(t){n(`Could not reset ${e.title} (network error)`),console.error(`[admin-ui] dashboard-reseat-failed sessionId=${e.sessionId} error=${t instanceof Error?t.message:String(t)}`),f.current=!1,d(!1)}}};return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`label`,{className:`reseat-field`,children:[(0,x.jsx)(`span`,{children:`Model`}),(0,x.jsx)(`select`,{"data-kind":`model`,value:r,disabled:u,onChange:e=>i(e.target.value),children:ye.map(e=>(0,x.jsx)(`option`,{value:e,children:ge(e)},e))})]}),(0,x.jsxs)(`label`,{className:`reseat-field`,children:[(0,x.jsx)(`span`,{children:`Mode`}),(0,x.jsxs)(`select`,{"data-kind":`mode`,value:a,disabled:u,onChange:e=>o(e.target.value),children:[(0,x.jsx)(`option`,{value:``,children:`Keep current`}),xe.map(e=>(0,x.jsx)(`option`,{value:e.value,children:e.label},e.value))]})]}),(0,x.jsxs)(`label`,{className:`reseat-field`,children:[(0,x.jsx)(`span`,{children:`Effort`}),(0,x.jsxs)(`select`,{"data-kind":`effort`,value:s,disabled:u,onChange:e=>c(e.target.value),children:[(0,x.jsx)(`option`,{value:``,children:`Keep current`}),H.map(e=>(0,x.jsx)(`option`,{value:e.value,children:e.label},e.value))]})]}),(0,x.jsx)(`button`,{type:`button`,className:`reseat-apply`,disabled:u,"aria-busy":u,onClick:()=>void p(),children:u?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(l,{size:12,className:`spin`,"aria-hidden":`true`}),`Resetting…`]}):`Reset`})]})}var we=[`whatsapp`,`telegram`];function U(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return n>0?`${t}m ${n}s`:`${t}m`}function W(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}async function Te(e){if(navigator.clipboard)try{return await navigator.clipboard.writeText(e),!0}catch{}try{let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.opacity=`0`,document.body.appendChild(t),t.select();let n=document.execCommand(`copy`);return document.body.removeChild(t),n}catch{return!1}}function Ee({target:e,onConfirm:t,onCancel:n}){return e?(0,x.jsx)(`div`,{className:`claude-info-overlay`,onClick:n,children:(0,x.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),role:`alertdialog`,"aria-label":`Confirm delete session`,children:[(0,x.jsxs)(`div`,{className:`claude-info-header`,children:[(0,x.jsx)(`span`,{children:`Delete this conversation?`}),(0,x.jsx)(`button`,{className:`claude-info-close`,onClick:n,"aria-label":`Close`,children:`✕`})]}),(0,x.jsxs)(`div`,{className:`claude-info-section`,style:{padding:`12px 14px`,fontSize:`11px`,color:`var(--text-secondary)`},children:[`This permanently removes the transcript. It is not moved to Archive and cannot be recovered.`,e.live&&(0,x.jsx)(`div`,{style:{marginTop:`8px`},children:`This session is running; deleting stops it first.`})]}),(0,x.jsxs)(`div`,{className:`claude-info-section`,style:{display:`flex`,gap:`8px`,padding:`10px 14px`},children:[(0,x.jsx)(C,{variant:`danger`,size:`sm`,style:{flex:1},onClick:t,children:`Delete`}),(0,x.jsx)(C,{variant:`secondary`,size:`sm`,style:{flex:1},onClick:n,children:`Cancel`})]})]})}):null}var G=`auth-refresh-failed`;function De({error:e,onClose:t}){if(!e)return null;let n=e.reason===G,r=n?`Claude sign-in expired`:`Session didn’t open`,i=n?`Your claude.ai login has expired. Re-authenticate to resume sessions.`:`The session did not bind within 60 seconds, so there is no live conversation to open.`;return(0,x.jsx)(`div`,{className:`claude-info-overlay`,onClick:t,children:(0,x.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),role:`alertdialog`,"aria-label":`Session could not be opened`,children:[(0,x.jsxs)(`div`,{className:`claude-info-header`,children:[(0,x.jsx)(`span`,{children:r}),(0,x.jsx)(`button`,{className:`claude-info-close`,onClick:t,"aria-label":`Close`,children:`✕`})]}),(0,x.jsxs)(`div`,{className:`claude-info-section`,style:{padding:`12px 14px`,fontSize:`11px`,color:`var(--text-secondary)`},children:[i,(0,x.jsxs)(`div`,{className:`claude-info-row`,style:{marginTop:`8px`},children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Reason`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:e.reason})]}),e.sessionId&&(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,x.jsxs)(`span`,{className:`claude-info-value`,children:[e.sessionId.slice(0,8),`…`]})]})]})]})})}function Oe(e){let{show:t,onClose:n,claudeInfo:r,messages:i,sessionElapsed:a,sessionId:o,cacheKey:s}=e,[c,l]=(0,b.useState)(null);if(!t)return null;let u=i.flatMap(e=>e.events?.filter(e=>e.type===`usage`)??[]),d=u.at(-1),f=d?.peak_request_pct==null?d?.context_window?Math.round((d.input_tokens+d.cache_creation_tokens+d.cache_read_tokens)/d.context_window*100):0:Math.round(d.peak_request_pct*100),p=u.reduce((e,t)=>e+t.input_tokens+t.cache_creation_tokens+t.cache_read_tokens+t.output_tokens,0),m=i.flatMap(e=>e.events?.filter(e=>e.type===`rate_limit`)??[]).at(-1),h=u.reduce((e,t)=>e+(t.total_cost_usd??0),0),g=r?.account?.subscriptionType,ee=e=>{let t=e*1e3-Date.now();if(t<=0)return`now`;let n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4);return n>0?`${n}h ${r}m`:`${r}m`};return(0,x.jsx)(`div`,{className:`claude-info-overlay`,onClick:n,children:(0,x.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),children:[(0,x.jsxs)(`div`,{className:`claude-info-header`,children:[(0,x.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`claude-info-icon`}),(0,x.jsx)(`span`,{children:`Claude Code`}),(0,x.jsx)(`button`,{className:`claude-info-close`,onClick:n,"aria-label":`Close`,children:`✕`})]}),(0,x.jsxs)(`div`,{className:`claude-info-section`,children:[(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Version`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:r?r.version:`…`})]}),(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Email`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:r?.account?.email??`…`})]})]}),(g||m||h>0)&&(0,x.jsxs)(`div`,{className:`claude-info-section`,children:[g&&(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Plan`}),(0,x.jsx)(`span`,{className:`claude-info-value`,style:{textTransform:`capitalize`},children:g})]}),m&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Usage`}),(0,x.jsxs)(`span`,{className:`claude-info-value`,children:[Math.round(m.utilization*100),`%`]})]}),(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Resets in`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:ee(m.resetsAt)})]}),m.isUsingOverage&&(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Overage`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:`Active`})]})]}),h>0&&(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Session cost`}),(0,x.jsxs)(`span`,{className:`claude-info-value`,children:[`$`,h<.01?h.toFixed(4):h.toFixed(2)]})]})]}),(0,x.jsxs)(`div`,{className:`claude-info-section`,children:[(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Model`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:r?.model??`…`})]}),(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Context used`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:f>0?`${f}%`:`—`})]}),(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Tokens`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:p>0?W(p):`—`})]}),(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,x.jsx)(`span`,{className:`claude-info-value`,children:U(a)})]}),(o||s)&&(()=>{let e=o??s??``;return(0,x.jsxs)(`div`,{className:`claude-info-row`,children:[(0,x.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,x.jsx)(`button`,{type:`button`,className:`claude-info-value claude-info-id-copy`,title:`${e} (${o?`flushed`:`pre-flush`}) — click to copy`,onClick:async()=>{l(await Te(e)?`copied`:`failed`),setTimeout(()=>l(null),1200)},children:c===`copied`?`copied ✓`:c===`failed`?`copy failed ✕`:`${e.slice(0,8)}…`})]})})()]})]})})}var ke=`https://claude.ai/code`,Ae=200,je=[500,1e3,1500,2e3,2500,3e3,3e3];function Me(e,t,n){if(e&&n.target)return{kind:`navigate`,url:n.target,sameOrigin:!0};let r=n.slug??n.bridgeSessionId??null;if(e&&r)return{kind:`navigate`,url:`${ke}/${r}`,sameOrigin:!1};let i=n.reason||n.error||`status ${t}`;return{kind:`error`,sessionId:n.sessionId??null,reason:i}}function Ne(e){if(!e)return``;let t=Date.parse(e);return Number.isFinite(t)?new Date(t).toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`}):``}function Pe(e){let{businessName:i,cacheKey:a,role:o,userName:s,userAvatar:l,onSelectProjects:te,onSelectPeople:_,onSelectTasks:ne,onSelectAgents:ie,onCloseMobileDrawer:y,collapsed:S,selectedWhatsappId:ae,onSelectWhatsappConversation:C,initialWhatsappSurface:k=!1,onSelectData:fe,onCloseData:A,initialDataSurface:j=!1}=e,M=v(a),pe=(0,b.useCallback)(e=>({key:`reseat`,label:`Reset session ${e.title} (model, mode, effort)`,menuLabel:`Reset`,title:`Reset — move this session onto a chosen model, mode, and effort`,icon:(0,x.jsx)(de,{size:12}),panelClassName:`reseat-panel`,panel:()=>(0,x.jsx)(Ce,{row:e,adminFetch:M,onError:e=>H({message:e,failed:!0})})}),[M]),me=d.productName,N=typeof s==`string`?s:s===null?`name unavailable`:i||me,P=(N.trim().charAt(0)||`?`).toUpperCase(),[F,I]=(0,b.useState)(j?`data`:k?`whatsapp`:`sessions`),[L,ge]=(0,b.useState)([]),[_e,R]=(0,b.useState)(!1),[z,ve]=(0,b.useState)(null),[B,ye]=(0,b.useState)(!1),[be,xe]=(0,b.useState)(`file`),[V,H]=(0,b.useState)(null),[Se,U]=(0,b.useState)(null),[W,Te]=(0,b.useState)([]),[G,Oe]=(0,b.useState)(!1),[ke,Pe]=(0,b.useState)(null),[Fe,K]=(0,b.useState)(!1),[q,ze]=(0,b.useState)(!1),[J,Be]=(0,b.useState)(!1),[Ve,He]=(0,b.useState)(null),[Ue,We]=(0,b.useState)(new Set),[Ge,Y]=(0,b.useState)(null),[Ke,qe]=(0,b.useState)(new Set),[Je,Ye]=(0,b.useState)(new Set),[Xe,Ze]=(0,b.useState)(new Set),[Qe,$e]=(0,b.useState)(null),[et,X]=(0,b.useState)(``),[tt,nt]=(0,b.useState)(!1),[Z,rt]=(0,b.useState)(!1),it=(0,b.useRef)(null),at=(0,b.useRef)(0),[ot,st]=(0,b.useState)(0);(0,b.useEffect)(()=>{let e=it.current;if(!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(e=>{let t=e[0]?.contentRect.width??0;st(e=>Math.abs(e-t)<1?e:t)});return t.observe(e),()=>t.disconnect()},[F]);let ct=ot>0&&ot<400,[lt,ut]=(0,b.useState)([]),[dt,ft]=(0,b.useState)(!1),[pt,mt]=(0,b.useState)(null),[ht,gt]=(0,b.useState)(`whatsapp`),_t=(0,b.useCallback)(e=>{if(y(),!a){console.error(`[admin-ui] artefact-download-blocked id=${e.id} reason=no-cache-key`),H({message:`Session not ready — try again`,failed:!0});return}if(!e.downloadPath){console.error(`[admin-ui] artefact-download-blocked id=${e.id} reason=not-downloadable`),H({message:`${e.name} can’t be downloaded`,failed:!0});return}console.info(`[admin-ui] artefact-download id=${e.id} root=${e.downloadRoot??`data`} path=${e.downloadPath}`),ee(a,e.downloadPath,e.downloadRoot??`data`),H({message:`Downloading ${e.name}`,failed:!1})},[a,y]);(0,b.useEffect)(()=>{if(!V)return;let e=setTimeout(()=>H(null),2500);return()=>clearTimeout(e)},[V]);let vt=(0,b.useCallback)(async()=>{if(a){ye(!0),ve(null);try{let e=await M(`/api/admin/sidebar-artefacts`);if(!e.ok)throw Error(`status ${e.status}`);ge((await e.json()).artefacts??[]),R(!0)}catch(e){let t=e instanceof Error?e.message:String(e);ve(`Failed to load artefacts: ${t}`),console.error(`[admin-ui] sidebar-artefacts fetch failed: ${t}`)}finally{ye(!1)}}},[a,M]),Q=(0,b.useCallback)(async()=>{if(!a)return null;let e=++at.current;K(!0),Pe(null);try{let t=await M(`/api/admin/sidebar-sessions`);if(!t.ok)throw Error(`status ${t.status}`);let n=await t.json(),r=n.sessions??[];return e===at.current?(Te(r),He(n.accountId??null),Oe(!0),r):(console.info(`[admin-ui] sidebar-sessions-stale-response-dropped token=${e}`),r)}catch(t){let n=t instanceof Error?t.message:String(t);return e===at.current&&Pe(`Failed to load sessions: ${n}`),console.error(`[admin-ui] sidebar-sessions fetch failed: ${n}`),null}finally{e===at.current&&K(!1)}},[a,M]),yt=(0,b.useCallback)(async()=>{if(a){mt(null);try{let e=await M(`/api/whatsapp-reader/conversations`);if(!e.ok)throw Error(`status ${e.status}`);ut((await e.json()).conversations??[]),ft(!0)}catch(e){let t=e instanceof Error?e.message:String(e);mt(`Couldn't load conversations.`),console.error(`[admin-ui] channel-convos fetch failed: ${t}`)}}},[a,M]);(0,b.useEffect)(()=>{!a||G||Q()},[a,G,Q]),(0,b.useEffect)(()=>{if(!a)return;let e=null;return yt(),e=setInterval(()=>{yt()},Ie),()=>{e!==null&&clearInterval(e)}},[a,yt]),(0,b.useEffect)(()=>{if(!a)return;let e=null;function t(){console.info(`[admin-ui] sidebar-refresh surface=sessions trigger=poll`),Q()}function n(){e===null&&(e=setInterval(t,Le))}function r(){e!==null&&(clearInterval(e),e=null)}function i(){document.hidden?r():(t(),n())}return document.hidden||n(),document.addEventListener(`visibilitychange`,i),()=>{r(),document.removeEventListener(`visibilitychange`,i)}},[a,Q]);let bt=(0,b.useMemo)(()=>{let e=new Map;for(let t of we)e.set(t,[]);for(let t of lt)e.get(t.channel)?.push(t);for(let t of we)console.info(`[admin-ui] sidebar-nav surface=${t} count=${e.get(t).length}`);return e},[lt]),xt={whatsapp:`WhatsApp`,telegram:`Telegram`,webchat:`Webchat`},St=()=>{C(null),I(`artefacts`),console.info(`[admin-ui] sidebar-nav surface=artefacts count=${_e?L.length:0} collapsed=${S}`),vt()},$=1.5,Ct=()=>{console.info(`[admin-ui] sidebar-refresh surface=artefacts`),vt()},wt=()=>{C(null),I(`sessions`),console.info(`[admin-ui] sidebar-nav surface=sessions count=${G?W.length:0} collapsed=${S}`),G||Q()},Tt=()=>{console.info(`[admin-ui] sidebar-refresh surface=sessions trigger=manual`),Q()},Et=()=>{I(`data`),console.info(`[admin-ui] sidebar-nav surface=data collapsed=${S}`),fe(),y()},Dt=e=>{A?.(),I(`whatsapp`),gt(e),console.info(`[admin-ui] sidebar-nav surface=${e} count=${bt.get(e)?.length??0} collapsed=${S}`)},Ot=(0,b.useCallback)(async e=>{if(Ke.has(e.sessionId))return;qe(t=>{let n=new Set(t);return n.add(e.sessionId),n});let t=window.open(``,`_blank`);try{let n=await M(`/api/admin/session-rc-spawn`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:e.sessionId,name:e.title||e.sessionId,...e.accountId?{targetAccountId:e.accountId}:{}})}),r=await n.json().catch(()=>({})),i=Me(n.ok,n.status,{...r,sessionId:r.sessionId??e.sessionId});console.info(`[admin-ui] sidebar-session-resume sessionId=${e.sessionId} status=${n.status} outcome=${i.kind} slug=${r.slug??r.bridgeSessionId??`none`}`),i.kind===`navigate`?(y(),t?t.location.href=i.url:window.open(i.url,`_blank`)):(t?.close(),console.error(`[admin-ui] sidebar-session-resume-failed sessionId=${e.sessionId} status=${n.status} reason=${i.reason}`),U(i))}catch(n){t?.close();let r=n instanceof Error?n.message:String(n);console.error(`[admin-ui] sidebar-session-resume-failed sessionId=${e.sessionId} error=${r}`),U({sessionId:e.sessionId,reason:r})}finally{qe(t=>{let n=new Set(t);return n.delete(e.sessionId),n})}},[M,y,Ke]),kt=(0,b.useCallback)(async e=>{let t=e.slice(0,8);for(let n=1;n<=je.length;n++){await new Promise(e=>setTimeout(e,je[n-1]));let r=await Q();if(r&&r.some(t=>t.sessionId===e)){console.info(`[admin-ui] sidebar-new-session-converged sessionId=${t} via=retry attempts=${n}`);return}}console.error(`[admin-ui] sidebar-new-session-converge-timeout sessionId=${t}`)},[Q]),At=(0,b.useCallback)(async()=>{if(!Z){rt(!0);try{let e=await M(`/api/admin/session-rc-spawn`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({})}),t=await e.json().catch(()=>({})),n=Me(e.ok,e.status,t);console.info(`[admin-ui] sidebar-new-session-spawned status=${e.status} outcome=${n.kind} slug=${t.slug??t.bridgeSessionId??`none`}`),n.kind===`navigate`?n.sameOrigin?window.location.assign(n.url):(window.open(n.url,`_blank`),t.sessionId?kt(t.sessionId):console.error(`[admin-ui] sidebar-new-session-converge-skipped reason=no-session-id`)):(console.error(`[admin-ui] sidebar-new-session-failed status=${e.status} reason=${n.reason}`),U(n))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[admin-ui] sidebar-new-session-failed error=${t}`),U({sessionId:null,reason:t})}finally{rt(!1)}}},[M,Z,kt]),jt=(0,b.useCallback)((e,t)=>{e.stopPropagation(),Y(t)},[]),Mt=(0,b.useCallback)(async e=>{if(!Ue.has(e.sessionId)){We(t=>{let n=new Set(t);return n.add(e.sessionId),n});try{let t=await M(`/api/admin/session-delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:e.sessionId})});if(!t.ok){let n=await t.json().catch(()=>({}));console.error(`[admin-ui] sidebar-session-delete-failed sessionId=${e.sessionId} status=${t.status} error=${n.error??`unknown`}`),H({message:`Delete failed: ${n.error??`status ${t.status}`}`,failed:!0});return}let n=await t.json();console.info(`[admin-ui] sidebar-session-delete sessionId=${e.sessionId} live=${e.live} confirmed=true pidKilled=${n.pidKilled??`?`} deleted=${n.deleted??`?`}`),Te(t=>t.filter(t=>t.sessionId!==e.sessionId)),Q()}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[admin-ui] sidebar-session-delete-failed sessionId=${e.sessionId} error=${n}`),H({message:`Delete failed: ${n}`,failed:!0})}finally{We(t=>{let n=new Set(t);return n.delete(e.sessionId),n})}}},[M,Ue,Q]),Nt=(0,b.useCallback)(async(e,t)=>{if(e.stopPropagation(),!Je.has(t.sessionId)){Ye(e=>{let n=new Set(e);return n.add(t.sessionId),n});try{let e=await M(`/api/admin/session-stop`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:t.sessionId})});if(!e.ok){let n=await e.json().catch(()=>({}));console.error(`[admin-ui] sidebar-session-stop-failed sessionId=${t.sessionId} status=${e.status} error=${n.error??`unknown`}`),H({message:`Stop failed: ${n.error??`status ${e.status}`}`,failed:!0});return}console.info(`[admin-ui] sidebar-session-stop sessionId=${t.sessionId}`),Q()}catch(e){let n=e instanceof Error?e.message:String(e);console.error(`[admin-ui] sidebar-session-stop-failed sessionId=${t.sessionId} error=${n}`),H({message:`Stop failed: ${n}`,failed:!0})}finally{Ye(e=>{let n=new Set(e);return n.delete(t.sessionId),n})}}},[M,Je,Q]),Pt=(0,b.useCallback)(async(e,t,n)=>{if(e.stopPropagation(),!Xe.has(t.sessionId)){Ze(e=>{let n=new Set(e);return n.add(t.sessionId),n});try{let e=await M(`/api/admin/session-archive`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:t.sessionId,mode:n})});if(!e.ok){let r=await e.json().catch(()=>({})),i=r.detail??r.error??`status ${e.status}`;console.error(`[admin-ui] sidebar-session-archive-failed sessionId=${t.sessionId} mode=${n} status=${e.status} error=${r.error??`unknown`}`),H({message:`${n===`archive`?`Archive`:`Unarchive`} failed: ${i}`,failed:!0});return}console.info(`[admin-ui] sidebar-session-archive sessionId=${t.sessionId} mode=${n}`),Q()}catch(e){let r=e instanceof Error?e.message:String(e);console.error(`[admin-ui] sidebar-session-archive-failed sessionId=${t.sessionId} mode=${n} error=${r}`),H({message:`${n===`archive`?`Archive`:`Unarchive`} failed: ${r}`,failed:!0})}finally{Ze(e=>{let n=new Set(e);return n.delete(t.sessionId),n})}}},[M,Xe,Q]),Ft=(0,b.useCallback)(async e=>{let t=et.trim();if(!t){H({message:`Title can’t be empty`,failed:!0});return}if(t.length>Ae){H({message:`Title too long (max ${Ae})`,failed:!0});return}nt(!0);try{let n=await M(`/api/admin/session-rename`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:e.sessionId,title:t})});if(!n.ok){let t=await n.json().catch(()=>({})),r=t.reason??t.error??`status ${n.status}`;console.error(`[admin-ui] sidebar-session-rename sessionId=${e.sessionId.slice(0,8)} outcome=rejected reason=${r}`),H({message:`Rename failed: ${r}`,failed:!0});return}console.info(`[admin-ui] sidebar-session-rename sessionId=${e.sessionId.slice(0,8)} outcome=ok`),$e(null),X(``),Q()}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[admin-ui] sidebar-session-rename sessionId=${e.sessionId.slice(0,8)} outcome=rejected reason=${n}`),H({message:`Rename failed: ${n}`,failed:!0})}finally{nt(!1)}},[M,et,Q]);return(0,x.jsxs)(`aside`,{className:`side`,children:[(0,x.jsx)(`div`,{className:`side-new-session-row`,children:(0,x.jsxs)(`button`,{type:`button`,className:`side-new-session`,onClick:At,disabled:Z,"aria-busy":Z,children:[(0,x.jsx)(ue,{size:14}),(0,x.jsx)(`span`,{children:Z?`Spawning…`:`New session`})]})}),(0,x.jsxs)(`nav`,{className:`side-nav`,children:[(0,x.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=people`),_(),y()},children:[(0,x.jsx)(O,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:`People`}),(0,x.jsx)(`span`,{className:`kbd`})]}),(0,x.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=agents`),ie(),y()},children:[(0,x.jsx)(T,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:`Agents`}),(0,x.jsx)(`span`,{className:`kbd`})]}),(0,x.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=projects`),te(),y()},children:[(0,x.jsx)(se,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:p().term}),(0,x.jsx)(`span`,{className:`kbd`})]}),(0,x.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=tasks`),ne(),y()},children:[(0,x.jsx)(le,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:`Tasks`}),(0,x.jsx)(`span`,{className:`kbd`})]}),(0,x.jsxs)(`button`,{type:`button`,className:`nav-row${F===`artefacts`?` active`:``}`,onClick:St,children:[(0,x.jsx)(t,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:`Artefacts`}),(0,x.jsx)(`span`,{className:`kbd`})]}),(0,x.jsxs)(`button`,{type:`button`,className:`nav-row${F===`sessions`?` active`:``}`,onClick:wt,children:[(0,x.jsx)(ce,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:`Sessions`}),(0,x.jsx)(`span`,{className:`kbd`})]}),(0,x.jsxs)(`button`,{type:`button`,className:`nav-row${F===`data`?` active`:``}`,onClick:Et,children:[(0,x.jsx)(u,{size:20,strokeWidth:$}),(0,x.jsx)(`span`,{className:`label`,children:`Data`}),(0,x.jsx)(`span`,{className:`kbd`})]}),dt&&we.filter(e=>bt.get(e).length>0).map(e=>(0,x.jsxs)(`button`,{type:`button`,className:`nav-row${F===`whatsapp`&&ht===e?` active`:``}`,onClick:()=>Dt(e),children:[(0,x.jsx)(m,{channel:e,size:16}),(0,x.jsx)(`span`,{className:`label`,children:xt[e]}),(0,x.jsx)(`span`,{className:`kbd`})]},e)),pt&&(0,x.jsx)(`div`,{className:`nav-row`,style:{color:`var(--text-tertiary)`,cursor:`default`},"aria-disabled":`true`,children:(0,x.jsx)(`span`,{className:`label`,children:pt})})]}),F===`artefacts`&&(0,x.jsxs)(`div`,{className:`side-list`,children:[(0,x.jsxs)(`div`,{className:`group-head`,children:[(0,x.jsx)(`span`,{children:`Artefacts`}),(0,x.jsxs)(`span`,{className:`group-head-meta`,children:[(0,x.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh artefacts`,"aria-label":`Refresh artefacts`,onClick:Ct,disabled:B,children:(0,x.jsx)(f,{size:12,className:B?`spinning`:void 0})}),(0,x.jsx)(`span`,{children:B?`…`:String(L.length)})]})]}),z&&(0,x.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:z}),_e&&!z&&L.length>0&&(()=>{let e=L.filter(e=>e.kind===`agent-template`).length,t=L.length-e;return(0,x.jsx)(`div`,{className:`artefact-filter-chips`,children:[{key:`all`,label:`All`,count:L.length},{key:`agent`,label:`Agents`,count:e},{key:`file`,label:`Files`,count:t}].map(e=>(0,x.jsxs)(`button`,{type:`button`,className:`artefact-filter-chip${be===e.key?` active`:``}`,onClick:()=>xe(e.key),disabled:e.count===0&&e.key!==`all`,children:[e.label,(0,x.jsx)(`span`,{className:`artefact-filter-chip-count`,children:e.count})]},e.key))})})(),_e&&!z&&L.length===0&&(0,x.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:`No artefacts yet`}),L.filter(e=>be===`all`?!0:be===`agent`?e.kind===`agent-template`:e.kind!==`agent-template`).map(e=>{let n=e.kind===`agent-template`,r=n?T:t,i=Ne(e.updatedAt),a=e.downloadPath!==null;return(0,x.jsxs)(`button`,{type:`button`,className:`conv`,onClick:()=>_t(e),disabled:!a,style:a?void 0:{cursor:`default`},title:a?`Download ${e.name}`:`${e.name} can’t be downloaded`,children:[(0,x.jsx)(r,{size:14,className:`conv-icon`,"data-kind":n?`agent`:`file`,"aria-label":n?`agent template`:`file`}),(0,x.jsxs)(`span`,{className:`conv-stack`,children:[(0,x.jsx)(`span`,{className:`conv-name-line`,children:(0,x.jsx)(`span`,{className:`conv-name`,children:e.name})}),i&&(0,x.jsx)(`span`,{className:`conv-timestamp`,children:i})]}),a&&(0,x.jsx)(c,{size:12,className:`conv-rc-icon`,"aria-hidden":`true`})]},e.id)})]}),F===`sessions`&&(()=>{let e=W.filter(e=>q?!0:!e.isSubagent).filter(e=>J?!0:!e.archived),t=W.some(e=>e.isSubagent),i=W.some(e=>e.archived);return(0,x.jsxs)(`div`,{className:`side-list`,ref:it,children:[(0,x.jsxs)(`div`,{className:`group-head`,children:[(0,x.jsx)(`span`,{children:`Sessions`}),(0,x.jsxs)(`span`,{className:`group-head-meta`,children:[(0,x.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh sessions`,"aria-label":`Refresh sessions`,onClick:Tt,disabled:Fe,children:(0,x.jsx)(f,{size:12,className:Fe?`spinning`:void 0})}),(0,x.jsx)(`span`,{children:Fe?`…`:String(e.length)})]})]}),Ve&&(0,x.jsx)(`div`,{className:`side-account-id`,title:`This install's accountId. The first 8 characters match the truncated UUID label on the live Remote Control daemon entry in claude.ai/code.`,children:(0,x.jsx)(`code`,{children:Ve})}),(t||i)&&(0,x.jsxs)(`div`,{className:`artefact-filter-chips`,children:[t&&(0,x.jsx)(`button`,{type:`button`,className:`artefact-filter-chip${q?` active`:``}`,"aria-pressed":q,onClick:()=>ze(e=>!e),title:q?`Hide subagent sessions`:`Show subagent sessions`,children:`Subagents`}),i&&(0,x.jsx)(`button`,{type:`button`,className:`artefact-filter-chip${J?` active`:``}`,"aria-pressed":J,onClick:()=>Be(e=>!e),title:J?`Hide archived sessions`:`Show archived sessions`,children:`Archived`})]}),ke&&(0,x.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:ke}),G&&!ke&&e.length===0&&(0,x.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:`No sessions yet`}),e.map(e=>{let t=Ne(e.startedAt),i=Ke.has(e.sessionId),a=Ue.has(e.sessionId),o=Je.has(e.sessionId),s=Xe.has(e.sessionId),c=i||a||o||s,l=[{key:`open`,label:`Resume session ${e.title} in claude.ai/code`,menuLabel:`Resume in claude.ai/code`,title:`Resume in a fresh local Remote Control PTY`,icon:(0,x.jsx)(g,{size:12}),busy:i,onClick:()=>{Ot(e)}},{key:`message`,label:`Open session ${e.title} in admin webchat`,menuLabel:`Open in webchat`,title:`Open in admin webchat (/chat) — sending resumes this session`,icon:(0,x.jsx)(E,{size:12}),onClick:()=>{window.location.assign(`/chat?session=${e.sessionId}`)}},...e.live?[{key:`stop`,label:`Stop session ${e.title}`,menuLabel:`Stop`,title:`Stop session process (keeps the conversation, can resume later)`,icon:(0,x.jsx)(D,{size:12}),busy:o,onClick:t=>{Nt(t,e)}}]:[],e.archived?{key:`unarchive`,label:`Unarchive session ${e.title}`,menuLabel:`Unarchive`,title:`Unarchive (move back to the active list)`,icon:(0,x.jsx)(w,{size:12}),busy:s,onClick:t=>{Pt(t,e,`unarchive`)}}:{key:`archive`,label:`Archive session ${e.title}`,menuLabel:`Archive`,title:`Archive (hide from the list, keeps the conversation resumable)`,icon:(0,x.jsx)(oe,{size:12}),busy:s,onClick:t=>{Pt(t,e,`archive`)}},{key:`rename`,label:`Rename session ${e.title}`,menuLabel:`Rename`,title:`Rename this session`,icon:(0,x.jsx)(r,{size:12}),busy:tt&&Qe===e.sessionId,onClick:t=>{t.stopPropagation(),$e(e.sessionId),X(e.personName??e.title)}},{key:`delete`,label:`Delete session ${e.title}`,menuLabel:`Delete`,title:`Delete session (stops the process, removes the conversation)`,icon:(0,x.jsx)(n,{size:12}),danger:!0,busy:a,onClick:t=>{jt(t,e)}},pe({sessionId:e.sessionId,model:e.model??null,title:e.personName??e.title})];return(0,x.jsxs)(`div`,{className:`conv conv-with-actions`,children:[(0,x.jsxs)(`div`,{className:`conv-main-static`,children:[(0,x.jsx)(`span`,{className:`conv-live-dot`,"data-live":e.live?`1`:`0`,"aria-label":e.live?`live session`:`ended session`}),(0,x.jsxs)(`span`,{className:`conv-stack`,children:[(0,x.jsxs)(`span`,{className:`conv-name-line`,children:[e.channel&&(0,x.jsx)(re,{channel:e.channel,size:13}),Qe===e.sessionId?(0,x.jsx)(`input`,{className:`conv-name conv-name-edit`,autoFocus:!0,value:et,disabled:tt,"aria-label":`New title for session ${e.title}`,onChange:e=>X(e.target.value),onClick:e=>e.stopPropagation(),onKeyDown:t=>{t.key===`Enter`?(t.preventDefault(),Ft(e)):t.key===`Escape`&&(t.preventDefault(),$e(null),X(``))},onBlur:()=>{Qe===e.sessionId&&!tt&&($e(null),X(``))}}):(0,x.jsx)(`span`,{className:`conv-name`,title:e.personName??e.title,children:e.personName??e.title})]}),(0,x.jsxs)(`span`,{className:`conv-timestamp`,children:[(0,x.jsx)(`code`,{className:`conv-session-id`,title:`First 8 characters of this session's id — distinguishes rows with identical auto-titles. The resume/delete buttons act on the full id.`,children:e.sessionId.slice(0,8)}),t&&(0,x.jsxs)(`span`,{children:[` · `,t]})]})]})]}),(0,x.jsx)(he,{actions:l,disabled:c,collapsed:ct})]},e.sessionId)})]})})(),F===`whatsapp`&&(0,x.jsxs)(`div`,{className:`side-list`,children:[(0,x.jsxs)(`div`,{className:`group-head`,children:[(0,x.jsx)(`span`,{children:xt[ht]}),(0,x.jsxs)(`span`,{className:`group-head-meta`,children:[(0,x.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh conversations`,"aria-label":`Refresh conversations`,onClick:()=>{yt()},children:(0,x.jsx)(f,{size:12})}),(0,x.jsx)(`span`,{children:String(bt.get(ht).length)})]})]}),bt.get(ht).map(e=>{let t=Ne(e.lastMessageAt);return(0,x.jsxs)(`div`,{className:`conv conv-with-actions${ae===e.sessionId?` active`:``}`,children:[(0,x.jsxs)(`button`,{type:`button`,className:`conv-main-static conv-main-btn`,onClick:()=>{C(e),y()},title:e.title,children:[(0,x.jsx)(m,{channel:e.channel,size:14}),(0,x.jsxs)(`span`,{className:`conv-stack`,children:[(0,x.jsxs)(`span`,{className:`conv-name-line`,children:[(0,x.jsx)(`span`,{className:`conv-name`,children:h(e)}),e.role===`public`&&(0,x.jsx)(`span`,{className:`conv-tag conv-tag-public`,children:`Public`})]}),t&&(0,x.jsx)(`span`,{className:`conv-timestamp`,children:t})]})]}),(0,x.jsx)(he,{actions:[pe({sessionId:e.sessionId,model:e.model,title:e.title})],disabled:!1,collapsed:ct})]},e.sessionId)})]}),(0,x.jsx)(Re,{}),(0,x.jsxs)(`div`,{className:`side-foot`,children:[(0,x.jsx)(`div`,{className:`avatar`,children:l?(0,x.jsx)(`img`,{src:l,alt:N}):P}),(0,x.jsxs)(`div`,{className:`who`,children:[(0,x.jsx)(`span`,{className:`name`,children:N}),(0,x.jsx)(`span`,{className:`role`,children:o??`operator`})]})]}),V&&(0,x.jsx)(`div`,{className:`copy-toast${V.failed?` copy-toast-failed`:``}`,role:`status`,children:V.message}),(0,x.jsx)(De,{error:Se,onClose:()=>U(null)}),(0,x.jsx)(Ee,{target:Ge,onCancel:()=>Y(null),onConfirm:()=>{let e=Ge;Y(null),e&&Mt(e)}})]})}var Fe=5e3,Ie=3e4,Le=3e4;function Re(){let[e,t]=(0,b.useState)(null);if((0,b.useEffect)(()=>{let e=!1,n=null;async function r(){try{let n=await fetch(`/api/admin/system-stats`);if(!n.ok){console.error(`[admin-ui] system-stats-fetch-failed status=${n.status}`);return}let r=await n.json();e||t(r)}catch(e){console.error(`[admin-ui] system-stats-fetch-failed reason=${e instanceof Error?e.message:String(e)}`)}}function i(){n===null&&(r(),n=setInterval(()=>{r()},Fe))}function a(){n!==null&&(clearInterval(n),n=null)}function o(){document.hidden?a():i()}return document.hidden||i(),document.addEventListener(`visibilitychange`,o),()=>{e=!0,a(),document.removeEventListener(`visibilitychange`,o)}},[]),!e||e.platform===`darwin`)return null;let n=e.cpuPct,r=e.memUsedPct,i=n!==null&&n>=.9,a=n!==null&&n>=.98,o=r!==null&&r>=.9,s=r!==null&&r>=.98,c=i||o,l=a||s,u=e=>e===null?`—`:`${Math.round(e*100)}%`,d=e=>{if(e===null)return{width:`0%`,background:`var(--text-tertiary)`};let t=Math.min(1,Math.max(0,e)),n=Math.round(140*(1-t));return{width:`${Math.round(t*100)}%`,background:`hsl(${n}, 65%, 45%)`}},f=[`system-stats`];return c&&f.push(`system-stats--warn`),l&&f.push(`system-stats--crit`),(0,x.jsxs)(`div`,{className:f.join(` `),role:`status`,"aria-label":`host CPU and RAM`,children:[(0,x.jsxs)(`div`,{className:`system-stats__metric`,children:[(0,x.jsxs)(`span`,{className:i?`system-stats__fig system-stats__fig--warn`:`system-stats__fig`,children:[`CPU `,u(n)]}),(0,x.jsx)(`div`,{className:`system-stats__bar`,children:(0,x.jsx)(`div`,{className:`system-stats__bar-fill`,style:d(n)})})]}),(0,x.jsxs)(`div`,{className:`system-stats__metric`,children:[(0,x.jsxs)(`span`,{className:o?`system-stats__fig system-stats__fig--warn`:`system-stats__fig`,children:[`RAM `,u(r)]}),(0,x.jsx)(`div`,{className:`system-stats__bar`,children:(0,x.jsx)(`div`,{className:`system-stats__bar-fill`,style:d(r)})})]})]})}var K=`admin-sidebar-collapsed`,q=`admin-sidebar-drawer-open`;function ze(){if(typeof window>`u`)return!1;try{return window.sessionStorage.getItem(K)===`1`}catch{return!1}}function J(e){if(!(typeof window>`u`))try{e?window.sessionStorage.setItem(K,`1`):window.sessionStorage.removeItem(K)}catch{}}function Be(){if(typeof window>`u`)return!1;try{return window.sessionStorage.getItem(q)===`1`}catch{return!1}}function Ve(e){if(!(typeof window>`u`))try{e?window.sessionStorage.setItem(q,`1`):window.sessionStorage.removeItem(q)}catch{}}var He=720;function Ue(e,t){return e===`/`?{via:`in-place`}:{via:`navigate`,href:`/?wa=${encodeURIComponent(t.sessionId)}&projectDir=${encodeURIComponent(t.projectDir)}`}}function We(e){return e===`/`?{via:`in-place`}:{via:`navigate`,href:`/?data=1`}}function Ge(e,t){if(e!==`/`)return null;let n=new URLSearchParams(t),r=n.get(`wa`),i=n.get(`projectDir`);return!r||!i?null:{sessionId:r,projectDir:i,title:``,senderId:null,startedAt:``,channel:`whatsapp`,role:`admin`,operatorName:null,whatsappName:null,lastMessageAt:null,modelGated:!1,model:null,rowType:`session`}}function Y(e,t){return e===`/`?new URLSearchParams(t).has(`data`):!1}function Ke(e,t){return t===`operator`&&e===`chat`||e===`dashboard`?`/`:e===`data`?`/data`:e===`graph`?`/graph`:e===`calendar`?`/calendar`:e===`chat`?`/chat`:`/browser`}function qe(e){let{cacheKey:t,businessName:n,variant:r=`admin`,onLogout:i,onDisconnect:a,disconnecting:o,userName:s,userAvatar:c,role:l,onOpenConversations:u,children:d,footer:f}=e,{subAccounts:m,activeAccountId:h,switching:g,switchAccount:ee}=ne(t),[_,re]=(0,b.useState)(()=>ze()),[v,y]=(0,b.useState)(()=>Be()),[S,ae]=(0,b.useState)(()=>typeof window<`u`&&window.matchMedia(`(max-width: ${He}px)`).matches),[C,w]=(0,b.useState)(()=>typeof window>`u`||Y(window.location.pathname,window.location.search)?null:Ge(window.location.pathname,window.location.search)),[oe]=(0,b.useState)(()=>C!==null),[T,se]=(0,b.useState)(()=>typeof window>`u`?!1:Y(window.location.pathname,window.location.search)),[ce]=(0,b.useState)(()=>T);(0,b.useEffect)(()=>{if(typeof window>`u`)return;let e=window.matchMedia(`(max-width: ${He}px)`),t=e=>ae(e.matches);return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]);let le=(0,b.useCallback)(e=>{J(e),re(e)},[]),E=(0,b.useCallback)(e=>{Ve(e),y(e)},[]);(0,b.useEffect)(()=>{if(typeof window>`u`)return;let e=window.location?.pathname??``;console.info(`[admin-ui] shell-mount route=${e} variant=${r} sidebar=${r===`operator`?`none`:`present`} collapsed=${_} drawer=${v}`)},[]),(0,b.useEffect)(()=>{typeof window>`u`||!C||(console.info(`[admin-ui] wa-hydrate route=/ sessionId=${C.sessionId.slice(0,8)}`),window.history.replaceState(null,``,`/`))},[]),(0,b.useEffect)(()=>{typeof window>`u`||!T||(console.info(`[admin-ui] data-hydrate route=/`),window.history.replaceState(null,``,`/`))},[]);let ue=(0,b.useCallback)(e=>{if(se(!1),e===null){w(null);return}let t=typeof window<`u`?window.location.pathname:`/`,n=Ue(t,e);console.info(`[admin-ui] wa-open route=${t} via=${n.via} sessionId=${e.sessionId.slice(0,8)}`),n.via===`in-place`?w(e):window.location.href=n.href},[]),de=(0,b.useCallback)(()=>{let e=typeof window<`u`?window.location.pathname:`/`,t=We(e);if(console.info(`[admin-ui] data-open route=${e} via=${t.via}`),t.via===`navigate`){window.location.href=t.href;return}w(null),se(!0)},[]),D=S?v:!_,O=(0,b.useCallback)(()=>{if(!(typeof window>`u`))if(window.matchMedia(`(max-width: ${He}px)`).matches){let e=v;console.info(`[admin-ui] header-sidebar-toggle from=${e?`open`:`closed`} mode=drawer`),E(!e)}else{let e=_;console.info(`[admin-ui] header-sidebar-toggle from=${e?`closed`:`open`} mode=collapse`),le(!e)}},[_,v,le,E]),k=(0,b.useCallback)(e=>{let t=Ke(e,r);console.info(`[admin-ui] header-menu-nav target=${e} dest=${t}`),window.location.href=t},[r]),[fe,A]=(0,b.useState)(`chat`),[j,pe]=(0,b.useState)([]);(0,b.useEffect)(()=>{if(r!==`operator`||!t)return;let e=!1;return fetch(`/api/whatsapp-reader/conversations?session_key=${encodeURIComponent(t)}&includePersistedOnly=1`).then(e=>e.ok?e.json():{conversations:[]}).then(t=>{e||pe(t.conversations??[])}).catch(()=>{}),()=>{e=!0}},[r,t]);let me=(0,b.useMemo)(()=>[...new Set(j.map(e=>e.channel))],[j]),N={collapsed:_,mobileDrawerOpen:v,sidebarOpen:D,onToggleSidebar:O,setMobileDrawerOpen:E,selectedWhatsapp:C,onClearWhatsapp:()=>w(null),dataOpen:T};return r===`operator`?(0,x.jsxs)(`div`,{className:`admin-shell admin-page admin-shell-root`,children:[(0,x.jsx)(ie,{businessName:n,variant:r,onNavigate:k,conversationsCount:j.length,conversationsChannels:me,onOpenConversations:()=>A(`conversations`),onToggleSidebar:O,sidebarOpen:D,onLogout:i,onDisconnect:a,disconnecting:o,cacheKey:t,subAccounts:m,activeAccountId:h,switchingAccount:g,onSwitchAccount:ee}),(0,x.jsx)(`div`,{className:`platform platform-operator`,children:fe===`conversations`?(0,x.jsx)(te,{conversations:j,sessionKey:t??``,onBack:()=>A(`chat`)}):typeof d==`function`?d(N):d}),f]}):(0,x.jsxs)(`div`,{className:`admin-shell admin-page admin-shell-root`,children:[(0,x.jsx)(ie,{businessName:n,variant:r,onNavigate:k,onOpenConversations:u,onToggleSidebar:O,sidebarOpen:D,onLogout:i,onDisconnect:a,disconnecting:o,cacheKey:t,subAccounts:m,activeAccountId:h,switchingAccount:g,onSwitchAccount:ee}),(0,x.jsxs)(`div`,{className:`platform${v?` menu-open`:``}${_?` sidebar-collapsed`:``}`,"data-artefact":`closed`,children:[(0,x.jsx)(Pe,{businessName:n,cacheKey:t,role:l??null,userName:s,userAvatar:c??null,onSelectProjects:()=>{window.location.href=`/graph?label=${p().label}`},onSelectPeople:()=>{window.location.href=`/graph?label=Person`},onSelectTasks:()=>{window.location.href=`/graph?label=Task`},onSelectAgents:()=>{window.location.href=`/graph?label=Agent`},onCloseMobileDrawer:()=>E(!1),collapsed:_,mobileDrawerOpen:v,selectedWhatsappId:C?.sessionId??null,onSelectWhatsappConversation:ue,initialWhatsappSurface:oe,onSelectData:de,onCloseData:()=>se(!1),initialDataSurface:ce}),!S&&(0,x.jsx)(M,{}),typeof d==`function`?d(N):d]}),v&&(0,x.jsx)(`div`,{className:`sidebar-backdrop menu-open`,"aria-hidden":`true`,onClick:()=>E(!1)}),f]})}export{w as _,I as a,z as c,D as d,de as f,oe as g,T as h,Te as i,ge as l,le as m,Me as n,P as o,ue as p,Oe as r,F as s,qe as t,O as u,C as v,y};
@@ -1 +0,0 @@
1
- import{o as e}from"./chunk-CAM3fms7.js";import{G as t,H as n,b as r,o as i,q as a}from"./useSubAccountSwitcher-DAgBUed_.js";import{n as o,t as s}from"./AdminLoginScreens-B9u1V35g.js";import"./admin-types-DJoj6VJv.js";import{r as c,t as l}from"./AdminShell-C2UXTLSB.js";import"./Checkbox-B2g2SCpw.js";import{n as u}from"./page-DBkTNfei.js";import"./graph-labels-DFdBydWC.js";var d=t(),f=e(a(),1),p=n();function m({onOpen:e}){return(0,p.jsx)(`footer`,{className:`admin-footer`,children:(0,p.jsxs)(`div`,{className:`powered-by`,role:`button`,tabIndex:0,onClick:e,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),e())},"aria-label":`Powered by Claude Code — show details`,children:[(0,p.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`powered-by-icon`}),(0,p.jsx)(`span`,{children:`Powered by Claude Code`})]})})}function h(){let e=o(),[t,n]=(0,f.useState)(!1);(0,f.useEffect)(()=>{if(!t)return;let e=e=>{e.key===`Escape`&&n(!1)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]);let a=(0,f.useCallback)(async()=>{let t=e.claudeInfo!=null;if(n(!0),t){console.info(`[admin-ui] claude-info-open cached=true ms=0`);return}let r=Date.now();try{let t=await fetch(`/api/admin/claude-info`);if(t.ok){let n=await t.json();e.setClaudeInfo(n)}console.info(`[admin-ui] claude-info-open cached=false ms=${Date.now()-r}`)}catch(e){console.error(`[admin-ui] claude-info-fetch-failed ms=${Date.now()-r} error="${e instanceof Error?e.message:String(e)}"`)}},[e]),d=(0,f.useCallback)(({code:t,path:n})=>{console.warn(`[admin-auth] outcome=chat-tab-logout-on-401 code=${t} path=${n}`),e.handleLogout()},[e]);return e.appState===`chat`?(0,p.jsx)(r,{cacheKey:e.cacheKey,onSessionExpired:d,surface:`chat`,children:(0,p.jsx)(l,{cacheKey:e.cacheKey,businessName:e.businessName,sessionId:e.sessionId,onLogout:e.handleLogout,onDisconnect:e.handleDisconnect,disconnecting:e.disconnecting,userName:e.userName,userAvatar:e.userAvatar,role:e.role,footer:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(m,{onOpen:a}),(0,p.jsx)(c,{show:t,onClose:()=>n(!1),claudeInfo:e.claudeInfo,messages:[],sessionElapsed:0,sessionId:e.sessionId,cacheKey:e.cacheKey})]}),children:t=>(0,p.jsx)(p.Fragment,{children:t.dataOpen&&e.cacheKey?(0,p.jsx)(u,{cacheKey:e.cacheKey}):t.selectedWhatsapp&&e.cacheKey?(0,p.jsx)(i,{sessionId:t.selectedWhatsapp.sessionId,projectDir:t.selectedWhatsapp.projectDir,sessionKey:e.cacheKey,cleanViewToggle:!0},t.selectedWhatsapp.sessionId):(0,p.jsx)(`main`,{})})})}):(0,p.jsx)(s,{auth:e})}(0,d.createRoot)(document.getElementById(`root`)).render((0,p.jsx)(h,{}));