@rubytech/create-maxy-code 0.1.382 → 0.1.383

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 (59) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +15 -8
  3. package/payload/platform/plugins/docs/references/admin-ui.md +9 -6
  4. package/payload/platform/plugins/docs/references/attachments.md +5 -1
  5. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/d1-command.test.d.ts +2 -0
  6. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/d1-command.test.d.ts.map +1 -0
  7. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/d1-command.test.js +23 -0
  8. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/d1-command.test.js.map +1 -0
  9. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.d.ts +12 -0
  10. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.d.ts.map +1 -0
  11. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.js +14 -0
  12. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.js.map +1 -0
  13. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +3 -1
  14. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  15. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +1 -1
  16. package/payload/platform/services/claude-session-manager/dist/account-title-stores.d.ts +21 -0
  17. package/payload/platform/services/claude-session-manager/dist/account-title-stores.d.ts.map +1 -0
  18. package/payload/platform/services/claude-session-manager/dist/account-title-stores.js +71 -0
  19. package/payload/platform/services/claude-session-manager/dist/account-title-stores.js.map +1 -0
  20. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +2 -2
  21. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  22. package/payload/platform/services/claude-session-manager/dist/http-server.js +46 -103
  23. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  24. package/payload/platform/services/claude-session-manager/dist/index.js +13 -8
  25. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  26. package/payload/server/package.json +2 -1
  27. package/payload/server/public/assets/{AdminLoginScreens-C_Qn0UPy.js → AdminLoginScreens-C32Kg8HN.js} +1 -1
  28. package/payload/server/public/assets/AdminShell-DizHgGBB.js +1 -0
  29. package/payload/server/public/assets/{Checkbox-B76SHnPC.js → Checkbox-C-dvkjKb.js} +1 -1
  30. package/payload/server/public/assets/{admin-RTEhnrPk.js → admin-CSBsndZ4.js} +1 -1
  31. package/payload/server/public/assets/admin-types-hioowVct.js +1 -0
  32. package/payload/server/public/assets/{browser-Chmp3Xfv.js → browser-BUuA2PPl.js} +1 -1
  33. package/payload/server/public/assets/{calendar-CjE7hiqV.js → calendar-CGlyx54B.js} +1 -1
  34. package/payload/server/public/assets/chat-DT1PbRkD.js +1 -0
  35. package/payload/server/public/assets/data-BC4KTIX4.js +1 -0
  36. package/payload/server/public/assets/{graph-DEHmvpNl.js → graph-CvQZVxwZ.js} +1 -1
  37. package/payload/server/public/assets/{graph-labels-CYAjU3rz.js → graph-labels-C7bJMcXs.js} +1 -1
  38. package/payload/server/public/assets/{operator-BDTnuQhB.js → operator-4skjNtEa.js} +1 -1
  39. package/payload/server/public/assets/{page-D8FFXoI9.js → page-B0zvkWaG.js} +1 -1
  40. package/payload/server/public/assets/page-BYlBTwqJ.js +32 -0
  41. package/payload/server/public/assets/{public-BIOxrxZK.js → public-ClYyeEA1.js} +1 -1
  42. package/payload/server/public/assets/{rotate-ccw-K1xZvf3B.js → rotate-ccw-DPCP-Lmz.js} +1 -1
  43. package/payload/server/public/assets/useSubAccountSwitcher-B8FEcQNM.js +9 -0
  44. package/payload/server/public/assets/{useSubAccountSwitcher-B44qYovc.css → useSubAccountSwitcher-DqxG4I5C.css} +1 -1
  45. package/payload/server/public/browser.html +4 -4
  46. package/payload/server/public/calendar.html +4 -4
  47. package/payload/server/public/chat.html +7 -7
  48. package/payload/server/public/data.html +5 -5
  49. package/payload/server/public/graph.html +7 -7
  50. package/payload/server/public/index.html +9 -9
  51. package/payload/server/public/operator.html +9 -9
  52. package/payload/server/public/public.html +7 -7
  53. package/payload/server/server.js +150 -21
  54. package/payload/server/public/assets/AdminShell-iHdYhspw.js +0 -1
  55. package/payload/server/public/assets/admin-types-DJoj6VJv.js +0 -1
  56. package/payload/server/public/assets/chat-DiKmCMO1.js +0 -1
  57. package/payload/server/public/assets/data-5PpEsUR3.js +0 -1
  58. package/payload/server/public/assets/page-HeiBebPq.js +0 -32
  59. package/payload/server/public/assets/useSubAccountSwitcher-DPEkYkYd.js +0 -9
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Browser — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/browser-Chmp3Xfv.js"></script>
8
+ <script type="module" crossorigin src="/assets/browser-BUuA2PPl.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
12
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Calendar — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/calendar-CjE7hiqV.js"></script>
8
+ <script type="module" crossorigin src="/assets/calendar-CGlyx54B.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
12
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
@@ -5,15 +5,15 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Chat — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/chat-DiKmCMO1.js"></script>
8
+ <script type="module" crossorigin src="/assets/chat-DT1PbRkD.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
12
- <link rel="modulepreload" crossorigin href="/assets/admin-types-DJoj6VJv.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-B_l5jfgx.js">
14
- <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-K1xZvf3B.js">
15
- <link rel="modulepreload" crossorigin href="/assets/page-HeiBebPq.js">
16
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
14
+ <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-DPCP-Lmz.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/page-BYlBTwqJ.js">
16
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
17
17
  </head>
18
18
  <body>
19
19
  <div id="root"></div>
@@ -5,12 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Data — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/data-5PpEsUR3.js"></script>
8
+ <script type="module" crossorigin src="/assets/data-BC4KTIX4.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/graph-labels-CYAjU3rz.js">
12
- <link rel="modulepreload" crossorigin href="/assets/page-D8FFXoI9.js">
13
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/graph-labels-C7bJMcXs.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/page-B0zvkWaG.js">
13
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
14
14
  </head>
15
15
  <body>
16
16
  <div id="root"></div>
@@ -5,14 +5,14 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Graph — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/graph-DEHmvpNl.js"></script>
8
+ <script type="module" crossorigin src="/assets/graph-CvQZVxwZ.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/graph-labels-CYAjU3rz.js">
12
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-B76SHnPC.js">
14
- <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-K1xZvf3B.js">
15
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/graph-labels-C7bJMcXs.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-C-dvkjKb.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-DPCP-Lmz.js">
15
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="root"></div>
@@ -5,16 +5,16 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-RTEhnrPk.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-CSBsndZ4.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/graph-labels-CYAjU3rz.js">
12
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
13
- <link rel="modulepreload" crossorigin href="/assets/admin-types-DJoj6VJv.js">
14
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-B76SHnPC.js">
15
- <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-C_Qn0UPy.js">
16
- <link rel="modulepreload" crossorigin href="/assets/page-D8FFXoI9.js">
17
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/graph-labels-C7bJMcXs.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-C-dvkjKb.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-C32Kg8HN.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/page-B0zvkWaG.js">
17
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
18
18
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
19
19
  <link rel="stylesheet" href="/brand-defaults.css">
20
20
  </head>
@@ -5,17 +5,17 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Operator — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/operator-BDTnuQhB.js"></script>
8
+ <script type="module" crossorigin src="/assets/operator-4skjNtEa.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
12
- <link rel="modulepreload" crossorigin href="/assets/admin-types-DJoj6VJv.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Checkbox-B76SHnPC.js">
14
- <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-C_Qn0UPy.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/Checkbox-C-dvkjKb.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/AdminLoginScreens-C32Kg8HN.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-B_l5jfgx.js">
16
- <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-K1xZvf3B.js">
17
- <link rel="modulepreload" crossorigin href="/assets/page-HeiBebPq.js">
18
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
16
+ <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-DPCP-Lmz.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/page-BYlBTwqJ.js">
18
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
19
19
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
20
20
  </head>
21
21
  <body>
@@ -5,15 +5,15 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/public-BIOxrxZK.js"></script>
8
+ <script type="module" crossorigin src="/assets/public-ClYyeEA1.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CAM3fms7.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DPEkYkYd.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-iHdYhspw.js">
12
- <link rel="modulepreload" crossorigin href="/assets/admin-types-DJoj6VJv.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B8FEcQNM.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-DizHgGBB.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/admin-types-hioowVct.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-B_l5jfgx.js">
14
- <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-K1xZvf3B.js">
15
- <link rel="modulepreload" crossorigin href="/assets/page-HeiBebPq.js">
16
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-B44qYovc.css">
14
+ <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-DPCP-Lmz.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/page-BYlBTwqJ.js">
16
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DqxG4I5C.css">
17
17
  <link rel="stylesheet" href="/brand-defaults.css">
18
18
  </head>
19
19
  <body class="public-surface">
@@ -5272,6 +5272,92 @@ function resolveScratchpadPath(raw, scratchpadRootAbs) {
5272
5272
  return resolveUnderRoot(raw, scratchpadRootAbs, "scratchpad");
5273
5273
  }
5274
5274
 
5275
+ // app/lib/doc-to-text.ts
5276
+ import { unzipSync, strFromU8 } from "fflate";
5277
+ var DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
5278
+ var ODT = "application/vnd.oasis.opendocument.text";
5279
+ var CONVERTIBLE_DOC_MIME = /* @__PURE__ */ new Set([
5280
+ DOCX,
5281
+ ODT,
5282
+ "text/rtf",
5283
+ "application/rtf"
5284
+ ]);
5285
+ function bareMime(mimeType) {
5286
+ return mimeType.split(";")[0].trim().toLowerCase();
5287
+ }
5288
+ function unescapeXml(s) {
5289
+ return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
5290
+ }
5291
+ function unzipEntry(buffer, entry) {
5292
+ const files = unzipSync(new Uint8Array(buffer));
5293
+ const bytes = files[entry];
5294
+ if (!bytes) throw new Error(`zip entry not found: ${entry}`);
5295
+ return strFromU8(bytes);
5296
+ }
5297
+ function docxToText(buffer) {
5298
+ const xml = unzipEntry(buffer, "word/document.xml");
5299
+ const paras = [];
5300
+ for (const p of xml.split("</w:p>")) {
5301
+ const withBreaks = p.replace(/<w:tab\b[^>]*\/?>/g, " ").replace(/<w:br\b[^>]*\/?>/g, "\n");
5302
+ let line = "";
5303
+ for (const m of withBreaks.matchAll(/<w:t\b[^>]*>([\s\S]*?)<\/w:t>/g)) {
5304
+ line += unescapeXml(m[1]);
5305
+ }
5306
+ if (line.length > 0) paras.push(line);
5307
+ }
5308
+ return paras.join("\n");
5309
+ }
5310
+ function odtToText(buffer) {
5311
+ const xml = unzipEntry(buffer, "content.xml");
5312
+ const body = xml.replace(/^[\s\S]*?<office:text\b[^>]*>/, "").replace(/<\/office:text>[\s\S]*$/, "");
5313
+ const withBreaks = body.replace(/<text:line-break\b[^>]*\/?>/g, "\n").replace(/<text:tab\b[^>]*\/?>/g, " ").replace(/<\/text:(?:p|h)>/g, "\n");
5314
+ const stripped = withBreaks.replace(/<[^>]+>/g, "");
5315
+ return unescapeXml(stripped).replace(/\n{3,}/g, "\n\n").trim();
5316
+ }
5317
+ var RTF_DROP_DEST = /^\\(?:\*|fonttbl|colortbl|stylesheet|listtable|info|pict)\b/;
5318
+ function stripRtfDestinations(s) {
5319
+ let out = "";
5320
+ for (let i = 0; i < s.length; i++) {
5321
+ const ch = s[i];
5322
+ if (ch === "\\" && i + 1 < s.length) {
5323
+ out += ch + s[i + 1];
5324
+ i++;
5325
+ continue;
5326
+ }
5327
+ if (ch === "{" && RTF_DROP_DEST.test(s.slice(i + 1))) {
5328
+ let depth = 1;
5329
+ let j = i + 1;
5330
+ for (; j < s.length && depth > 0; j++) {
5331
+ if (s[j] === "\\") {
5332
+ j++;
5333
+ continue;
5334
+ }
5335
+ if (s[j] === "{") depth++;
5336
+ else if (s[j] === "}") depth--;
5337
+ }
5338
+ i = j - 1;
5339
+ continue;
5340
+ }
5341
+ out += ch;
5342
+ }
5343
+ return out;
5344
+ }
5345
+ function rtfToText(rtf) {
5346
+ let s = stripRtfDestinations(rtf);
5347
+ s = s.replace(/\\par[d]?\b/g, "\n").replace(/\\line\b/g, "\n").replace(/\\tab\b/g, " ");
5348
+ s = s.replace(/\\'([0-9a-fA-F]{2})/g, (_m, h) => String.fromCharCode(parseInt(h, 16)));
5349
+ s = s.replace(/\\[a-zA-Z]+-?\d* ?/g, "");
5350
+ s = s.replace(/\\([{}\\])/g, "$1").replace(/[{}]/g, "");
5351
+ return s.replace(/[ \t]{2,}/g, " ").replace(/\n{3,}/g, "\n\n").trim();
5352
+ }
5353
+ function docToText(buffer, mimeType) {
5354
+ const mime = bareMime(mimeType);
5355
+ if (mime === DOCX) return docxToText(buffer);
5356
+ if (mime === ODT) return odtToText(buffer);
5357
+ if (mime === "text/rtf" || mime === "application/rtf") return rtfToText(buffer.toString("latin1"));
5358
+ return null;
5359
+ }
5360
+
5275
5361
  // app/lib/attachments.ts
5276
5362
  function uploadsDirFor(accountId, subPath, attachmentId) {
5277
5363
  return subPath ? resolve7(DATA_ROOT, "accounts", accountId, "uploads", subPath, attachmentId) : resolve7(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
@@ -5289,6 +5375,14 @@ var SUPPORTED_MIME_TYPES = /* @__PURE__ */ new Set([
5289
5375
  "text/calendar",
5290
5376
  "application/zip",
5291
5377
  "application/x-zip-compressed",
5378
+ // Task 1347 — Word/OpenDocument/RTF text documents. The bytes are converted to
5379
+ // a readable-text sibling at ingestion (writeAttachment → doc-to-text.ts)
5380
+ // because the on-device Read tool cannot parse the binary containers. rtf is
5381
+ // reported by browsers as either text/rtf or application/rtf.
5382
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
5383
+ "application/vnd.oasis.opendocument.text",
5384
+ "text/rtf",
5385
+ "application/rtf",
5292
5386
  // Task 1240 — voice recordings persist as playable clips in the admin bubble.
5293
5387
  // These match AUDIO_MIME_TYPES in app/lib/stt/audio-mime.ts exactly.
5294
5388
  "audio/ogg",
@@ -5304,6 +5398,7 @@ var MAX_FILE_SIZE_BYTES = 50 * 1024 * 1024;
5304
5398
  var MAX_FILES_PER_MESSAGE = 5;
5305
5399
  var MAX_DATA_UPLOAD_BYTES = 2 * 1024 * 1024 * 1024;
5306
5400
  var MAX_ZIP_UNCOMPRESSED_BYTES = 100 * 1024 * 1024;
5401
+ var EXTRACTED_TEXT_SUFFIX = ".extracted.txt";
5307
5402
  function assertSupportedMime(mimeType) {
5308
5403
  const bare = mimeType.split(";")[0].trim().toLowerCase();
5309
5404
  if (!SUPPORTED_MIME_TYPES.has(bare)) {
@@ -5329,7 +5424,15 @@ async function writeAttachment(accountId, subPath, filename, mimeType, sizeBytes
5329
5424
  };
5330
5425
  await writeFile2(storagePath, buffer);
5331
5426
  await writeFile2(metaPath, JSON.stringify(meta, null, 2));
5332
- return { attachmentId, filename, storagePath, metaPath, mimeType, sizeBytes };
5427
+ let readableTextPath;
5428
+ if (CONVERTIBLE_DOC_MIME.has(mimeType.split(";")[0].trim().toLowerCase())) {
5429
+ const text = docToText(buffer, mimeType);
5430
+ if (text) {
5431
+ readableTextPath = resolve7(dir, `${attachmentId}${EXTRACTED_TEXT_SUFFIX}`);
5432
+ await writeFile2(readableTextPath, text);
5433
+ }
5434
+ }
5435
+ return { attachmentId, filename, storagePath, metaPath, mimeType, sizeBytes, readableTextPath };
5333
5436
  }
5334
5437
  async function storeAttachment(accountId, file) {
5335
5438
  assertSupportedMime(file.type);
@@ -5370,6 +5473,8 @@ var MIME_BY_EXT = {
5370
5473
  ".zip": "application/zip",
5371
5474
  ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
5372
5475
  ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
5476
+ ".odt": "application/vnd.oasis.opendocument.text",
5477
+ ".rtf": "text/rtf",
5373
5478
  ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
5374
5479
  ".ics": "text/calendar"
5375
5480
  };
@@ -6223,6 +6328,15 @@ async function loginConnectionLoop(accountId, login) {
6223
6328
  } catch (err) {
6224
6329
  const current = activeLogins.get(accountId);
6225
6330
  if (current?.id !== login.id) return;
6331
+ await drainCredsSaveQueue();
6332
+ const preRetryCensus = credsCensus(login.authDir);
6333
+ if (!preRetryCensus.hasAccountSignature) {
6334
+ current.error = "WhatsApp accepted the code but did not finish linking. This usually means the number has reached its linked-device limit or has a stale linked device. On the phone, open WhatsApp, Linked Devices, remove existing devices, then ask for a new code.";
6335
+ console.error(
6336
+ `${TAG17} op=pairing-incomplete cid=${cidShort} closeKind=${closeKind(getStatusCode(err), false)} reason=no-account-signature`
6337
+ );
6338
+ return;
6339
+ }
6226
6340
  const classification = classifyDisconnect(err);
6227
6341
  if (!classification.shouldRetry || attempt >= LOGIN_MAX_RECONNECTS) {
6228
6342
  if (attempt >= LOGIN_MAX_RECONNECTS) {
@@ -7924,16 +8038,29 @@ function pickActivity(entries, grown, nowMs, concurrencyWindowMs) {
7924
8038
  // server/routes/whatsapp-reader.ts
7925
8039
  var app4 = new Hono();
7926
8040
  app4.get("/conversations", requireAdminSession, async (c) => {
8041
+ const cacheKey = c.var.cacheKey;
8042
+ const scopeAccountId = getAccountIdForSession(cacheKey) ?? null;
8043
+ const validAccounts = listValidAccounts();
8044
+ const multiAccount = validAccounts.length > 1;
8045
+ if (multiAccount && !scopeAccountId) {
8046
+ console.log(`[wa-reader] op=list-scope-unresolved cacheKey=${cacheKey.slice(0, 8)}`);
8047
+ return c.json({ conversations: [] });
8048
+ }
7927
8049
  const cfg = claudeConfigDir();
7928
8050
  if (!cfg) return c.json({ conversations: [] });
7929
8051
  const projectsRoot = join14(cfg, "projects");
7930
8052
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
7931
8053
  const rows = [];
8054
+ let sessionRowsExcludedUntagged = 0;
7932
8055
  for (const { path: path2 } of enumerateJsonls(projectsRoot)) {
7933
8056
  const sessionId = basename4(path2).replace(/\.jsonl$/, "");
7934
8057
  const projectDir = dirname3(path2);
7935
8058
  const meta = readSidecarMeta(join14(projectDir, `${sessionId}.meta.json`));
7936
8059
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
8060
+ if (multiAccount) {
8061
+ if (meta.accountId === null) sessionRowsExcludedUntagged += 1;
8062
+ if (meta.accountId !== scopeAccountId) continue;
8063
+ }
7937
8064
  let body = "";
7938
8065
  try {
7939
8066
  body = readFileSync15(path2, "utf8");
@@ -7958,7 +8085,7 @@ app4.get("/conversations", requireAdminSession, async (c) => {
7958
8085
  });
7959
8086
  }
7960
8087
  const sessionRows = selectReaderChannelSessions(rows).filter((r) => r.channel !== "whatsapp");
7961
- const account = resolveAccount();
8088
+ const account = multiAccount ? validAccounts.find((a) => a.accountId === scopeAccountId) ?? null : resolveAccount();
7962
8089
  let users = [];
7963
8090
  if (account) {
7964
8091
  try {
@@ -7991,8 +8118,9 @@ app4.get("/conversations", requireAdminSession, async (c) => {
7991
8118
  const storeRows = account ? buildStoreConversationRows(account.accountId, readConversationSummaries(account.accountId)) : [];
7992
8119
  const adminScope = storeRows.filter((r) => r.scope === "admin").length;
7993
8120
  const publicScope = storeRows.length - adminScope;
8121
+ const sessionRowCount = sessionConversations.length;
7994
8122
  console.log(
7995
- `[wa-reader] op=list accountId=${account?.accountId ?? "null"} conversations=${storeRows.length} adminScope=${adminScope} publicScope=${publicScope}`
8123
+ `[wa-reader] op=list pinnedAccount=${scopeAccountId?.slice(0, 8) ?? "null"} resolvedAccount=${account?.accountId.slice(0, 8) ?? "null"} multiAccount=${multiAccount} conversations=${sessionRowCount + storeRows.length} sessionRows=${sessionRowCount} storeRows=${storeRows.length} adminScope=${adminScope} publicScope=${publicScope} sessionRowsExcludedUntagged=${sessionRowsExcludedUntagged}`
7996
8124
  );
7997
8125
  return c.json({ conversations: [...sessionConversations, ...storeRows] });
7998
8126
  });
@@ -8730,7 +8858,7 @@ app5.get("/attachment/:attachmentId", (c) => {
8730
8858
  let dataFile;
8731
8859
  let buffer;
8732
8860
  try {
8733
- dataFile = readdirSync9(dir).find((f) => !f.endsWith(".meta.json"));
8861
+ dataFile = readdirSync9(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
8734
8862
  if (!dataFile) throw new Error("no data file");
8735
8863
  buffer = readFileSync16(resolve13(dir, dataFile));
8736
8864
  } catch {
@@ -9359,8 +9487,13 @@ ${result.result.text}` : result.result.text;
9359
9487
  console.error(`[webchat:inbound] op=send-refused kind=files reason=store-failed detail=${detail}`);
9360
9488
  return c.json({ error: "failed to store attachment" }, 500);
9361
9489
  }
9490
+ for (const s of stored) {
9491
+ const dot = s.filename.lastIndexOf(".");
9492
+ const ext = dot >= 0 ? s.filename.slice(dot).toLowerCase() : "";
9493
+ console.log(`[attach-ingest] mime=${s.mimeType} ext=${ext} converted=${!!s.readableTextPath} path=${s.storagePath}`);
9494
+ }
9362
9495
  if (stored.length > 0) {
9363
- const listing = stored.map((s) => `${s.filename} (${s.storagePath})`).join(", ");
9496
+ const listing = stored.map((s) => `${s.filename} (${s.readableTextPath ?? s.storagePath})`).join(", ");
9364
9497
  const note = `[The operator uploaded ${stored.length} file(s): ${listing}]`;
9365
9498
  text = text.length > 0 ? `${text}
9366
9499
 
@@ -11118,7 +11251,7 @@ app15.get("/:attachmentId", requireAdminSession, async (c) => {
11118
11251
  return new Response("Not found", { status: 404 });
11119
11252
  }
11120
11253
  const entries = await readdir(dir);
11121
- const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
11254
+ const dataFile = entries.find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
11122
11255
  if (!dataFile) {
11123
11256
  return new Response("Not found", { status: 404 });
11124
11257
  }
@@ -13598,11 +13731,11 @@ app21.get("/download", requireAdminSession, async (c) => {
13598
13731
  const nodeStream = createReadStream2(absolute);
13599
13732
  const webStream = Readable2.toWeb(nodeStream);
13600
13733
  if (disposition === "inline") {
13601
- if (!mimeType.startsWith("image/")) {
13602
- console.error(`[data] op=thumb-refused path="${relPath}" mime="${mimeType}" reason=not-image`);
13603
- return c.json({ error: "Inline serve is image-only" }, 400);
13734
+ if (!mimeType.startsWith("image/") && mimeType !== "application/pdf") {
13735
+ console.error(`[data] op=inline-refused path="${relPath}" mime="${mimeType}" reason=not-image-or-pdf`);
13736
+ return c.json({ error: "Inline serve is image- or PDF-only" }, 400);
13604
13737
  }
13605
- console.error(`[data] op=thumb-serve path="${relPath}" mime="${mimeType}" size=${info.size} status=200`);
13738
+ console.error(`[data] op=inline-serve path="${relPath}" mime="${mimeType}" size=${info.size} status=200`);
13606
13739
  return new Response(webStream, {
13607
13740
  status: 200,
13608
13741
  headers: {
@@ -16546,10 +16679,8 @@ app29.post("/", requireAdminSession, async (c) => {
16546
16679
  return c.json({ error: "sessionId must be a v4 UUID" }, 400);
16547
16680
  }
16548
16681
  const base = managerBase("session-delete:wrapper");
16549
- const accountId = getAccountIdForSession(c.var.cacheKey);
16550
- const acctQuery = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
16551
16682
  try {
16552
- const stop = await fetch(`${base}/${sessionId}/stop${acctQuery}`, { method: "POST" });
16683
+ const stop = await fetch(`${base}/${sessionId}/stop`, { method: "POST" });
16553
16684
  if (stop.status !== 204 && stop.status !== 200 && stop.status !== 404) {
16554
16685
  console.error(`[session-delete] sessionId=${sessionId} stop-status=${stop.status}`);
16555
16686
  return c.json({ error: `stop-failed-${stop.status}` }, 502);
@@ -16560,7 +16691,7 @@ app29.post("/", requireAdminSession, async (c) => {
16560
16691
  }
16561
16692
  let del;
16562
16693
  try {
16563
- del = await fetch(`${base}/${sessionId}${acctQuery}`, { method: "DELETE" });
16694
+ del = await fetch(`${base}/${sessionId}`, { method: "DELETE" });
16564
16695
  } catch (err) {
16565
16696
  console.error(`[session-delete] sessionId=${sessionId} delete-unreachable err=${err instanceof Error ? err.message : String(err)}`);
16566
16697
  return c.json({ error: "manager-unreachable" }, 502);
@@ -16589,11 +16720,9 @@ app30.post("/", requireAdminSession, async (c) => {
16589
16720
  if (!SESSION_ID_RE2.test(sessionId)) {
16590
16721
  return c.json({ error: "sessionId must be a v4 UUID" }, 400);
16591
16722
  }
16592
- const accountId = getAccountIdForSession(c.var.cacheKey);
16593
- const acctQuery = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
16594
16723
  let res;
16595
16724
  try {
16596
- res = await fetch(`${managerBase("session-stop:wrapper")}/${sessionId}/stop${acctQuery}`, { method: "POST" });
16725
+ res = await fetch(`${managerBase("session-stop:wrapper")}/${sessionId}/stop`, { method: "POST" });
16597
16726
  } catch (err) {
16598
16727
  console.error(`[session-stop] sessionId=${sessionId} manager-unreachable err=${err instanceof Error ? err.message : String(err)}`);
16599
16728
  return c.json({ error: "manager-unreachable" }, 502);
@@ -22856,14 +22985,14 @@ var chatRoutes = createChatRoutes({
22856
22985
  awaitReply: (key, timeoutMs) => webchatGateway.awaitReply(key, timeoutMs)
22857
22986
  });
22858
22987
  app55.use("*", clientIpMiddleware);
22988
+ function allowsSameOriginFraming(path2) {
22989
+ return path2 === "/vnc-viewer.html" || path2.startsWith("/api/admin/attachment/") || path2.startsWith("/api/public-reader/attachment/") || path2 === "/api/admin/files/download";
22990
+ }
22859
22991
  app55.use("*", async (c, next) => {
22860
22992
  await next();
22861
22993
  c.header("X-Content-Type-Options", "nosniff");
22862
22994
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
22863
- c.header(
22864
- "X-Frame-Options",
22865
- c.req.path === "/vnc-viewer.html" ? "SAMEORIGIN" : "DENY"
22866
- );
22995
+ c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
22867
22996
  });
22868
22997
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
22869
22998
  app55.use("*", async (c, next) => {
@@ -1 +0,0 @@
1
- import{o as e}from"./chunk-CAM3fms7.js";import{A as t,B as n,C as r,D as i,F as a,I as o,J as s,M as c,N as l,O as u,P as d,T as f,U as p,W as m,Y as h,_ as g,b as ee,g as _,m as te,n as ne,t as re,v as ie,x as ae,y as v,z as y}from"./useSubAccountSwitcher-DPEkYkYd.js";async function b(){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 x=e(h(),1),S=m(),C={sm:14,md:16,lg:18},w={sm:30,md:38,lg:46};function T({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=C[t],h={...e===`send`?{width:w[t],height:w[t]}:{},...u},g=Object.keys(h).length>0;return(0,S.jsxs)(`button`,{type:s,className:p,disabled:i||o,onClick:c,"aria-label":l,style:g?h:void 0,children:[(0,S.jsxs)(`span`,{className:`btn__content`,style:{visibility:i?`hidden`:`visible`},children:[n&&r===`leading`&&(0,S.jsx)(n,{size:m}),f,n&&r===`trailing`&&(0,S.jsx)(n,{size:m})]}),i&&(0,S.jsx)(`span`,{className:`btn__spinner`,children:`✱`})]})}var oe=y(`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`}]]),E=y(`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`}]]),D=y(`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=y(`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=y(`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`}]]),O=y(`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`}]]),le=y(`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=y(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]),k=y(`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`}]]),A=y(`square`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]),de=y(`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`}]]),j=`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 M(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 pe(){if(typeof window>`u`)return 264;try{let e=window.localStorage.getItem(j);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 M(t)}catch{}return 264}function N({targetSelector:e=`.platform`}){let t=(0,x.useRef)(null),[n,r]=(0,x.useState)(()=>pe()),i=(0,x.useRef)(n);(0,x.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,x.useCallback)(()=>{r(e=>{let t=M(e);return t===e?e:t})},[]);(0,x.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(M(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(j,String(t))}catch{}console.info(`[admin-ui] sidebar-resize px=${t}`)};window.addEventListener(`pointermove`,o),window.addEventListener(`pointerup`,s)},s=()=>{let e=M(264);r(e);try{window.localStorage.removeItem(j)}catch{}console.info(`[admin-ui] sidebar-resize px=${e}`)};return(0,S.jsx)(`div`,{ref:t,className:`side-resize-handle`,role:`separator`,"aria-orientation":`vertical`,"aria-label":`Resize sidebar`,onPointerDown:o,onDoubleClick:s})}var me=s();function he({anchorRef:e,onClose:t,className:n,role:r,ariaLabel:i,children:a}){let o=(0,x.useRef)(null),[s,c]=(0,x.useState)({position:`fixed`,visibility:`hidden`}),l=(0,x.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,x.useLayoutEffect)(()=>{if(l(),typeof ResizeObserver>`u`)return;let e=new ResizeObserver(()=>l());return o.current&&e.observe(o.current),()=>e.disconnect()},[l]),(0,x.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,me.createPortal)((0,S.jsx)(`div`,{ref:o,className:n,role:r,"aria-label":i,style:s,children:a}),document.body)}function ge({action:e,disabled:t,open:n,onToggle:r,onClose:i}){let a=(0,x.useRef)(null);return(0,S.jsxs)(S.Fragment,{children:[(0,S.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,S.jsx)(he,{anchorRef:a,onClose:i,className:e.panelClassName,role:`dialog`,ariaLabel:e.label,children:e.panel()})]})}function _e({actions:e,disabled:t,collapsed:n}){let[r,i]=(0,x.useState)(null),[a,o]=(0,x.useState)(!1),[s,c]=(0,x.useState)(null),l=(0,x.useRef)(null);(0,x.useEffect)(()=>{i(null),o(!1),c(null)},[n]);let u=(0,x.useCallback)(()=>{o(!1),c(null)},[]);return n?(0,S.jsxs)(`div`,{className:`conv-actions`,children:[(0,S.jsx)(`button`,{ref:l,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,S.jsx)(d,{size:12})}),a&&(0,S.jsx)(he,{anchorRef:l,onClose:u,className:`conv-actions-menu`,role:`menu`,children:e.map(e=>e.panel?(0,S.jsxs)(`div`,{className:`conv-actions-menu-disclosure`,children:[(0,S.jsxs)(`button`,{type:`button`,role:`menuitem`,"aria-haspopup":`dialog`,"aria-expanded":s===e.key,disabled:t,onClick:()=>c(t=>t===e.key?null:e.key),children:[e.icon,(0,S.jsx)(`span`,{children:e.menuLabel})]}),s===e.key&&(0,S.jsx)(`div`,{className:`conv-actions-menu-panel`,children:e.panel()})]},e.key):(0,S.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),u()},children:[e.icon,(0,S.jsx)(`span`,{children:e.menuLabel})]},e.key))})]}):(0,S.jsx)(`div`,{className:`conv-actions`,children:e.map(e=>e.panel?(0,S.jsx)(ge,{action:e,disabled:t,open:r===e.key,onToggle:()=>i(t=>t===e.key?null:e.key),onClose:()=>i(null)},e.key):(0,S.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 ve(e){return L[e]??e}var ye=[P,F,I];function R(e){return e.replace(/\[1m\]$/,``)}function z(e){return ye.find(t=>R(t)===R(e))??e}var be=[`default`,`acceptEdits`,`plan`,`auto`,`bypassPermissions`],B=[`low`,`medium`,`high`,`xhigh`];[...be],[...B],[...B];var xe=[P,F,I],Se={default:`Ask permissions`,acceptEdits:`Accept edits`,plan:`Plan mode`,auto:`Auto mode`,bypassPermissions:`Bypass permissions`},Ce=be.map(e=>({value:e,label:Se[e]??e})),V={low:`Low`,medium:`Medium`,high:`High`,xhigh:`Highest`},H=B.map(e=>({value:e,label:V[e]??e}));function we(e){if(e){let t=xe.find(t=>R(t)===R(e));if(t)return t}return P}function Te({row:e,adminFetch:n,onError:r}){let[i,a]=(0,x.useState)(()=>we(e.model)),[o,s]=(0,x.useState)(``),[c,l]=(0,x.useState)(``),[u,d]=(0,x.useState)(!1),f=(0,x.useRef)(!1);(0,x.useEffect)(()=>{a(we(e.model))},[e.model]);let p=async()=>{if(!f.current){f.current=!0,d(!0);try{let t=await n(`/api/admin/session-reseat`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({fromSessionId:e.sessionId,model:i,...o?{permissionMode:o}:{},...c?{effort:c}:{}})});if(!t.ok){r(`Could not reset ${e.title} (status ${t.status})`),console.error(`[admin-ui] dashboard-reseat-failed sessionId=${e.sessionId} status=${t.status}`),f.current=!1,d(!1);return}let a=await t.json().catch(()=>({}));a.target?window.location.assign(a.target):(r(`Reset of ${e.title} returned no target`),f.current=!1,d(!1))}catch(t){r(`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,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`label`,{className:`reseat-field`,children:[(0,S.jsx)(`span`,{children:`Model`}),(0,S.jsx)(`select`,{"data-kind":`model`,value:i,disabled:u,onChange:e=>a(e.target.value),children:xe.map(e=>(0,S.jsx)(`option`,{value:e,children:ve(e)},e))})]}),(0,S.jsxs)(`label`,{className:`reseat-field`,children:[(0,S.jsx)(`span`,{children:`Mode`}),(0,S.jsxs)(`select`,{"data-kind":`mode`,value:o,disabled:u,onChange:e=>s(e.target.value),children:[(0,S.jsx)(`option`,{value:``,children:`Keep current`}),Ce.map(e=>(0,S.jsx)(`option`,{value:e.value,children:e.label},e.value))]})]}),(0,S.jsxs)(`label`,{className:`reseat-field`,children:[(0,S.jsx)(`span`,{children:`Effort`}),(0,S.jsxs)(`select`,{"data-kind":`effort`,value:c,disabled:u,onChange:e=>l(e.target.value),children:[(0,S.jsx)(`option`,{value:``,children:`Keep current`}),H.map(e=>(0,S.jsx)(`option`,{value:e.value,children:e.label},e.value))]})]}),(0,S.jsx)(`button`,{type:`button`,className:`reseat-apply`,disabled:u,"aria-busy":u,onClick:()=>void p(),children:u?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(t,{size:12,className:`spin`,"aria-hidden":`true`}),`Resetting…`]}):`Reset`})]})}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 Ee(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 De({target:e,onConfirm:t,onCancel:n}){return e?(0,S.jsx)(`div`,{className:`claude-info-overlay`,onClick:n,children:(0,S.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),role:`alertdialog`,"aria-label":`Confirm delete session`,children:[(0,S.jsxs)(`div`,{className:`claude-info-header`,children:[(0,S.jsx)(`span`,{children:`Delete this conversation?`}),(0,S.jsx)(`button`,{className:`claude-info-close`,onClick:n,"aria-label":`Close`,children:`✕`})]}),(0,S.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,S.jsx)(`div`,{style:{marginTop:`8px`},children:`This session is running; deleting stops it first.`})]}),(0,S.jsxs)(`div`,{className:`claude-info-section`,style:{display:`flex`,gap:`8px`,padding:`10px 14px`},children:[(0,S.jsx)(T,{variant:`danger`,size:`sm`,style:{flex:1},onClick:t,children:`Delete`}),(0,S.jsx)(T,{variant:`secondary`,size:`sm`,style:{flex:1},onClick:n,children:`Cancel`})]})]})}):null}var G=`auth-refresh-failed`;function Oe({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,S.jsx)(`div`,{className:`claude-info-overlay`,onClick:t,children:(0,S.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),role:`alertdialog`,"aria-label":`Session could not be opened`,children:[(0,S.jsxs)(`div`,{className:`claude-info-header`,children:[(0,S.jsx)(`span`,{children:r}),(0,S.jsx)(`button`,{className:`claude-info-close`,onClick:t,"aria-label":`Close`,children:`✕`})]}),(0,S.jsxs)(`div`,{className:`claude-info-section`,style:{padding:`12px 14px`,fontSize:`11px`,color:`var(--text-secondary)`},children:[i,(0,S.jsxs)(`div`,{className:`claude-info-row`,style:{marginTop:`8px`},children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Reason`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:e.reason})]}),e.sessionId&&(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,S.jsxs)(`span`,{className:`claude-info-value`,children:[e.sessionId.slice(0,8),`…`]})]})]})]})})}function ke(e){let{show:t,onClose:n,claudeInfo:r,messages:i,sessionElapsed:a,sessionId:o,cacheKey:s}=e,[c,l]=(0,x.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,S.jsx)(`div`,{className:`claude-info-overlay`,onClick:n,children:(0,S.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),children:[(0,S.jsxs)(`div`,{className:`claude-info-header`,children:[(0,S.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`claude-info-icon`}),(0,S.jsx)(`span`,{children:`Claude Code`}),(0,S.jsx)(`button`,{className:`claude-info-close`,onClick:n,"aria-label":`Close`,children:`✕`})]}),(0,S.jsxs)(`div`,{className:`claude-info-section`,children:[(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Version`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:r?r.version:`…`})]}),(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Email`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:r?.account?.email??`…`})]})]}),(g||m||h>0)&&(0,S.jsxs)(`div`,{className:`claude-info-section`,children:[g&&(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Plan`}),(0,S.jsx)(`span`,{className:`claude-info-value`,style:{textTransform:`capitalize`},children:g})]}),m&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Usage`}),(0,S.jsxs)(`span`,{className:`claude-info-value`,children:[Math.round(m.utilization*100),`%`]})]}),(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Resets in`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:ee(m.resetsAt)})]}),m.isUsingOverage&&(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Overage`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:`Active`})]})]}),h>0&&(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Session cost`}),(0,S.jsxs)(`span`,{className:`claude-info-value`,children:[`$`,h<.01?h.toFixed(4):h.toFixed(2)]})]})]}),(0,S.jsxs)(`div`,{className:`claude-info-section`,children:[(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Model`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:r?.model??`…`})]}),(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Context used`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:f>0?`${f}%`:`—`})]}),(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Tokens`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:p>0?W(p):`—`})]}),(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,S.jsx)(`span`,{className:`claude-info-value`,children:U(a)})]}),(o||s)&&(()=>{let e=o??s??``;return(0,S.jsxs)(`div`,{className:`claude-info-row`,children:[(0,S.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,S.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 Ee(e)?`copied`:`failed`),setTimeout(()=>l(null),1200)},children:c===`copied`?`copied ✓`:c===`failed`?`copy failed ✕`:`${e.slice(0,8)}…`})]})})()]})]})})}var Ae=`https://claude.ai/code`,je=200,Me=[500,1e3,1500,2e3,2500,3e3,3e3];function Ne(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:`${Ae}/${r}`,sameOrigin:!1};let i=n.reason||n.error||`status ${t}`;return{kind:`error`,sessionId:n.sessionId??null,reason:i}}function Pe(e){if(!e)return``;let t=Date.parse(e);return Number.isFinite(t)?new Date(t).toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`}):``}function Fe(e){let{businessName:t,cacheKey:s,role:d,userName:m,userAvatar:h,onSelectProjects:ne,onSelectPeople:re,onSelectTasks:ae,onSelectAgents:y,onCloseMobileDrawer:b,collapsed:C,selectedWhatsappId:w,onSelectWhatsappConversation:T,initialWhatsappSurface:j=!1,onSelectData:fe,onCloseData:M,initialDataSurface:pe=!1}=e,N=r(s),me=(0,x.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,S.jsx)(k,{size:12}),panelClassName:`reseat-panel`,panel:()=>(0,S.jsx)(Te,{row:e,adminFetch:N,onError:e=>H({message:e,failed:!0})})}),[N]),he=n.productName,ge=typeof m==`string`?m:m===null?`name unavailable`:t||he,P=(ge.trim().charAt(0)||`?`).toUpperCase(),[F,I]=(0,x.useState)(pe?`data`:j?`whatsapp`:`sessions`),[L,ve]=(0,x.useState)([]),[ye,R]=(0,x.useState)(!1),[z,be]=(0,x.useState)(null),[B,xe]=(0,x.useState)(!1),[Se,Ce]=(0,x.useState)(`file`),[V,H]=(0,x.useState)(null),[we,U]=(0,x.useState)(null),[W,Ee]=(0,x.useState)([]),[G,ke]=(0,x.useState)(!1),[Ae,Fe]=(0,x.useState)(null),[Ie,K]=(0,x.useState)(!1),[q,Be]=(0,x.useState)(!1),[J,Ve]=(0,x.useState)(!1),[He,Ue]=(0,x.useState)(null),[We,Ge]=(0,x.useState)(new Set),[Ke,Y]=(0,x.useState)(null),[qe,Je]=(0,x.useState)(new Set),[Ye,Xe]=(0,x.useState)(new Set),[Ze,Qe]=(0,x.useState)(new Set),[$e,et]=(0,x.useState)(null),[tt,X]=(0,x.useState)(``),[nt,rt]=(0,x.useState)(!1),[Z,it]=(0,x.useState)(!1),at=(0,x.useRef)(null),ot=(0,x.useRef)(0),[st,ct]=(0,x.useState)(0);(0,x.useEffect)(()=>{let e=at.current;if(!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(e=>{let t=e[0]?.contentRect.width??0;ct(e=>Math.abs(e-t)<1?e:t)});return t.observe(e),()=>t.disconnect()},[F]);let lt=st>0&&st<400,[ut,dt]=(0,x.useState)([]),[ft,pt]=(0,x.useState)(!1),[mt,ht]=(0,x.useState)(null),[gt,_t]=(0,x.useState)(`whatsapp`),vt=(0,x.useCallback)(e=>{if(b(),!s){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}`),te(s,e.downloadPath,e.downloadRoot??`data`),H({message:`Downloading ${e.name}`,failed:!1})},[s,b]);(0,x.useEffect)(()=>{if(!V)return;let e=setTimeout(()=>H(null),2500);return()=>clearTimeout(e)},[V]);let yt=(0,x.useCallback)(async()=>{if(s){xe(!0),be(null);try{let e=await N(`/api/admin/sidebar-artefacts`);if(!e.ok)throw Error(`status ${e.status}`);ve((await e.json()).artefacts??[]),R(!0)}catch(e){let t=e instanceof Error?e.message:String(e);be(`Failed to load artefacts: ${t}`),console.error(`[admin-ui] sidebar-artefacts fetch failed: ${t}`)}finally{xe(!1)}}},[s,N]),Q=(0,x.useCallback)(async()=>{if(!s)return null;let e=++ot.current;K(!0),Fe(null);try{let t=await N(`/api/admin/sidebar-sessions`);if(!t.ok)throw Error(`status ${t.status}`);let n=await t.json(),r=n.sessions??[];return e===ot.current?(Ee(r),Ue(n.accountId??null),ke(!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===ot.current&&Fe(`Failed to load sessions: ${n}`),console.error(`[admin-ui] sidebar-sessions fetch failed: ${n}`),null}finally{e===ot.current&&K(!1)}},[s,N]),bt=(0,x.useCallback)(async()=>{if(s){ht(null);try{let e=await N(`/api/whatsapp-reader/conversations`);if(!e.ok)throw Error(`status ${e.status}`);dt((await e.json()).conversations??[]),pt(!0)}catch(e){let t=e instanceof Error?e.message:String(e);ht(`Couldn't load conversations.`),console.error(`[admin-ui] channel-convos fetch failed: ${t}`)}}},[s,N]);(0,x.useEffect)(()=>{!s||G||Q()},[s,G,Q]),(0,x.useEffect)(()=>{if(!s)return;let e=null;return bt(),e=setInterval(()=>{bt()},Le),()=>{e!==null&&clearInterval(e)}},[s,bt]),(0,x.useEffect)(()=>{if(!s)return;let e=null;function t(){console.info(`[admin-ui] sidebar-refresh surface=sessions trigger=poll`),Q()}function n(){e===null&&(e=setInterval(t,Re))}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)}},[s,Q]);let xt=(0,x.useMemo)(()=>{let e=new Map;for(let t of g)e.set(t,[]);for(let t of ut)e.get(t.channel)?.push(t);for(let t of g)console.info(`[admin-ui] sidebar-nav surface=${t} count=${e.get(t).length}`);return e},[ut]),St={whatsapp:`WhatsApp`,telegram:`Telegram`,webchat:`Webchat`},Ct=()=>{T(null),I(`artefacts`),console.info(`[admin-ui] sidebar-nav surface=artefacts count=${ye?L.length:0} collapsed=${C}`),yt()},$=1.5,wt=()=>{console.info(`[admin-ui] sidebar-refresh surface=artefacts`),yt()},Tt=()=>{T(null),I(`sessions`),console.info(`[admin-ui] sidebar-nav surface=sessions count=${G?W.length:0} collapsed=${C}`),G||Q()},Et=()=>{console.info(`[admin-ui] sidebar-refresh surface=sessions trigger=manual`),Q()},Dt=()=>{I(`data`),console.info(`[admin-ui] sidebar-nav surface=data collapsed=${C}`),fe(),b()},Ot=e=>{M?.(),I(`whatsapp`),_t(e),console.info(`[admin-ui] sidebar-nav surface=${e} count=${xt.get(e)?.length??0} collapsed=${C}`)},kt=(0,x.useCallback)(async e=>{if(qe.has(e.sessionId))return;Je(t=>{let n=new Set(t);return n.add(e.sessionId),n});let t=window.open(``,`_blank`);try{let n=await N(`/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=Ne(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`?(b(),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{Je(t=>{let n=new Set(t);return n.delete(e.sessionId),n})}},[N,b,qe]),At=(0,x.useCallback)(async e=>{let t=e.slice(0,8);for(let n=1;n<=Me.length;n++){await new Promise(e=>setTimeout(e,Me[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]),jt=(0,x.useCallback)(async()=>{if(!Z){it(!0);try{let e=await N(`/api/admin/session-rc-spawn`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({})}),t=await e.json().catch(()=>({})),n=Ne(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?At(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{it(!1)}}},[N,Z,At]),Mt=(0,x.useCallback)((e,t)=>{e.stopPropagation(),Y(t)},[]),Nt=(0,x.useCallback)(async e=>{if(!We.has(e.sessionId)){Ge(t=>{let n=new Set(t);return n.add(e.sessionId),n});try{let t=await N(`/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??`?`}`),Ee(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{Ge(t=>{let n=new Set(t);return n.delete(e.sessionId),n})}}},[N,We,Q]),Pt=(0,x.useCallback)(async(e,t)=>{if(e.stopPropagation(),!Ye.has(t.sessionId)){Xe(e=>{let n=new Set(e);return n.add(t.sessionId),n});try{let e=await N(`/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{Xe(e=>{let n=new Set(e);return n.delete(t.sessionId),n})}}},[N,Ye,Q]),Ft=(0,x.useCallback)(async(e,t,n)=>{if(e.stopPropagation(),!Ze.has(t.sessionId)){Qe(e=>{let n=new Set(e);return n.add(t.sessionId),n});try{let e=await N(`/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{Qe(e=>{let n=new Set(e);return n.delete(t.sessionId),n})}}},[N,Ze,Q]),It=(0,x.useCallback)(async e=>{let t=tt.trim();if(!t){H({message:`Title can’t be empty`,failed:!0});return}if(t.length>je){H({message:`Title too long (max ${je})`,failed:!0});return}rt(!0);try{let n=await N(`/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`),et(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{rt(!1)}},[N,tt,Q]);return(0,S.jsxs)(`aside`,{className:`side`,children:[(0,S.jsx)(`div`,{className:`side-new-session-row`,children:(0,S.jsxs)(`button`,{type:`button`,className:`side-new-session`,onClick:jt,disabled:Z,"aria-busy":Z,children:[(0,S.jsx)(ue,{size:14}),(0,S.jsx)(`span`,{children:Z?`Spawning…`:`New session`})]})}),(0,S.jsxs)(`nav`,{className:`side-nav`,children:[(0,S.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=people`),re(),b()},children:[(0,S.jsx)(de,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:`People`}),(0,S.jsx)(`span`,{className:`kbd`})]}),(0,S.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=agents`),y(),b()},children:[(0,S.jsx)(D,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:`Agents`}),(0,S.jsx)(`span`,{className:`kbd`})]}),(0,S.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=projects`),ne(),b()},children:[(0,S.jsx)(se,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:p().term}),(0,S.jsx)(`span`,{className:`kbd`})]}),(0,S.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=tasks`),ae(),b()},children:[(0,S.jsx)(O,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:`Tasks`}),(0,S.jsx)(`span`,{className:`kbd`})]}),(0,S.jsxs)(`button`,{type:`button`,className:`nav-row${F===`artefacts`?` active`:``}`,onClick:Ct,children:[(0,S.jsx)(c,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:`Artefacts`}),(0,S.jsx)(`span`,{className:`kbd`})]}),(0,S.jsxs)(`button`,{type:`button`,className:`nav-row${F===`sessions`?` active`:``}`,onClick:Tt,children:[(0,S.jsx)(ce,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:`Sessions`}),(0,S.jsx)(`span`,{className:`kbd`})]}),(0,S.jsxs)(`button`,{type:`button`,className:`nav-row${F===`data`?` active`:``}`,onClick:Dt,children:[(0,S.jsx)(o,{size:20,strokeWidth:$}),(0,S.jsx)(`span`,{className:`label`,children:`Data`}),(0,S.jsx)(`span`,{className:`kbd`})]}),ft&&g.filter(e=>xt.get(e).length>0).map(e=>(0,S.jsxs)(`button`,{type:`button`,className:`nav-row${F===`whatsapp`&&gt===e?` active`:``}`,onClick:()=>Ot(e),children:[(0,S.jsx)(v,{channel:e,size:16}),(0,S.jsx)(`span`,{className:`label`,children:St[e]}),(0,S.jsx)(`span`,{className:`kbd`})]},e)),mt&&(0,S.jsx)(`div`,{className:`nav-row`,style:{color:`var(--text-tertiary)`,cursor:`default`},"aria-disabled":`true`,children:(0,S.jsx)(`span`,{className:`label`,children:mt})})]}),F===`artefacts`&&(0,S.jsxs)(`div`,{className:`side-list`,children:[(0,S.jsxs)(`div`,{className:`group-head`,children:[(0,S.jsx)(`span`,{children:`Artefacts`}),(0,S.jsxs)(`span`,{className:`group-head-meta`,children:[(0,S.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh artefacts`,"aria-label":`Refresh artefacts`,onClick:wt,disabled:B,children:(0,S.jsx)(i,{size:12,className:B?`spinning`:void 0})}),(0,S.jsx)(`span`,{children:B?`…`:String(L.length)})]})]}),z&&(0,S.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:z}),ye&&!z&&L.length>0&&(()=>{let e=L.filter(e=>e.kind===`agent-template`).length,t=L.length-e;return(0,S.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,S.jsxs)(`button`,{type:`button`,className:`artefact-filter-chip${Se===e.key?` active`:``}`,onClick:()=>Ce(e.key),disabled:e.count===0&&e.key!==`all`,children:[e.label,(0,S.jsx)(`span`,{className:`artefact-filter-chip-count`,children:e.count})]},e.key))})})(),ye&&!z&&L.length===0&&(0,S.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:`No artefacts yet`}),L.filter(e=>Se===`all`?!0:Se===`agent`?e.kind===`agent-template`:e.kind!==`agent-template`).map(e=>{let t=e.kind===`agent-template`,n=t?D:c,r=Pe(e.updatedAt),i=e.downloadPath!==null;return(0,S.jsxs)(`button`,{type:`button`,className:`conv`,onClick:()=>vt(e),disabled:!i,style:i?void 0:{cursor:`default`},title:i?`Download ${e.name}`:`${e.name} can’t be downloaded`,children:[(0,S.jsx)(n,{size:14,className:`conv-icon`,"data-kind":t?`agent`:`file`,"aria-label":t?`agent template`:`file`}),(0,S.jsxs)(`span`,{className:`conv-stack`,children:[(0,S.jsx)(`span`,{className:`conv-name-line`,children:(0,S.jsx)(`span`,{className:`conv-name`,children:e.name})}),r&&(0,S.jsx)(`span`,{className:`conv-timestamp`,children:r})]}),i&&(0,S.jsx)(a,{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),n=W.some(e=>e.archived);return(0,S.jsxs)(`div`,{className:`side-list`,ref:at,children:[(0,S.jsxs)(`div`,{className:`group-head`,children:[(0,S.jsx)(`span`,{children:`Sessions`}),(0,S.jsxs)(`span`,{className:`group-head-meta`,children:[(0,S.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh sessions`,"aria-label":`Refresh sessions`,onClick:Et,disabled:Ie,children:(0,S.jsx)(i,{size:12,className:Ie?`spinning`:void 0})}),(0,S.jsx)(`span`,{children:Ie?`…`:String(e.length)})]})]}),He&&(0,S.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,S.jsx)(`code`,{children:He})}),(t||n)&&(0,S.jsxs)(`div`,{className:`artefact-filter-chips`,children:[t&&(0,S.jsx)(`button`,{type:`button`,className:`artefact-filter-chip${q?` active`:``}`,"aria-pressed":q,onClick:()=>Be(e=>!e),title:q?`Hide subagent sessions`:`Show subagent sessions`,children:`Subagents`}),n&&(0,S.jsx)(`button`,{type:`button`,className:`artefact-filter-chip${J?` active`:``}`,"aria-pressed":J,onClick:()=>Ve(e=>!e),title:J?`Hide archived sessions`:`Show archived sessions`,children:`Archived`})]}),Ae&&(0,S.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:Ae}),G&&!Ae&&e.length===0&&(0,S.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:`No sessions yet`}),e.map(e=>{let t=Pe(e.startedAt),n=qe.has(e.sessionId),r=We.has(e.sessionId),i=Ye.has(e.sessionId),a=Ze.has(e.sessionId),o=n||r||i||a,s=[{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,S.jsx)(l,{size:12}),busy:n,onClick:()=>{kt(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,S.jsx)(le,{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,S.jsx)(A,{size:12}),busy:i,onClick:t=>{Pt(t,e)}}]:[],e.archived?{key:`unarchive`,label:`Unarchive session ${e.title}`,menuLabel:`Unarchive`,title:`Unarchive (move back to the active list)`,icon:(0,S.jsx)(oe,{size:12}),busy:a,onClick:t=>{Ft(t,e,`unarchive`)}}:{key:`archive`,label:`Archive session ${e.title}`,menuLabel:`Archive`,title:`Archive (hide from the list, keeps the conversation resumable)`,icon:(0,S.jsx)(E,{size:12}),busy:a,onClick:t=>{Ft(t,e,`archive`)}},{key:`rename`,label:`Rename session ${e.title}`,menuLabel:`Rename`,title:`Rename this session`,icon:(0,S.jsx)(u,{size:12}),busy:nt&&$e===e.sessionId,onClick:t=>{t.stopPropagation(),et(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,S.jsx)(f,{size:12}),danger:!0,busy:r,onClick:t=>{Mt(t,e)}},me({sessionId:e.sessionId,model:e.model??null,title:e.personName??e.title})];return(0,S.jsxs)(`div`,{className:`conv conv-with-actions`,children:[(0,S.jsxs)(`div`,{className:`conv-main-static`,children:[(0,S.jsx)(`span`,{className:`conv-live-dot`,"data-live":e.live?`1`:`0`,"aria-label":e.live?`live session`:`ended session`}),(0,S.jsxs)(`span`,{className:`conv-stack`,children:[(0,S.jsxs)(`span`,{className:`conv-name-line`,children:[e.channel&&(0,S.jsx)(ee,{channel:e.channel,size:13}),$e===e.sessionId?(0,S.jsx)(`input`,{className:`conv-name conv-name-edit`,autoFocus:!0,value:tt,disabled:nt,"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(),It(e)):t.key===`Escape`&&(t.preventDefault(),et(null),X(``))},onBlur:()=>{$e===e.sessionId&&!nt&&(et(null),X(``))}}):(0,S.jsx)(`span`,{className:`conv-name`,title:e.personName??e.title,children:e.personName??e.title})]}),(0,S.jsxs)(`span`,{className:`conv-timestamp`,children:[(0,S.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,S.jsxs)(`span`,{children:[` · `,t]})]})]})]}),(0,S.jsx)(_e,{actions:s,disabled:o,collapsed:lt})]},e.sessionId)})]})})(),F===`whatsapp`&&(0,S.jsxs)(`div`,{className:`side-list`,children:[(0,S.jsxs)(`div`,{className:`group-head`,children:[(0,S.jsx)(`span`,{children:St[gt]}),(0,S.jsxs)(`span`,{className:`group-head-meta`,children:[(0,S.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh conversations`,"aria-label":`Refresh conversations`,onClick:()=>{bt()},children:(0,S.jsx)(i,{size:12})}),(0,S.jsx)(`span`,{children:String(xt.get(gt).length)})]})]}),xt.get(gt).map(e=>{let t=Pe(e.lastMessageAt),n=ie(e);return(0,S.jsxs)(`div`,{className:`conv conv-with-actions${e.source===`store`?e.scope===`admin`?` conv-scope-admin`:` conv-scope-public`:``}${w===n?` active`:``}`,children:[(0,S.jsxs)(`button`,{type:`button`,className:`conv-main-static conv-main-btn`,onClick:()=>{T(e),b()},title:e.title,children:[(0,S.jsx)(v,{channel:e.channel,size:14}),(0,S.jsxs)(`span`,{className:`conv-stack`,children:[(0,S.jsx)(`span`,{className:`conv-name-line`,children:(0,S.jsx)(`span`,{className:`conv-name`,children:_(e)})}),t&&(0,S.jsx)(`span`,{className:`conv-timestamp`,children:t})]})]}),e.source===`session`&&(0,S.jsx)(_e,{actions:[me({sessionId:e.sessionId,model:e.model,title:e.title})],disabled:!1,collapsed:lt})]},n)})]}),(0,S.jsx)(ze,{}),(0,S.jsxs)(`div`,{className:`side-foot`,children:[(0,S.jsx)(`div`,{className:`avatar`,children:h?(0,S.jsx)(`img`,{src:h,alt:ge}):P}),(0,S.jsxs)(`div`,{className:`who`,children:[(0,S.jsx)(`span`,{className:`name`,children:ge}),(0,S.jsx)(`span`,{className:`role`,children:d??`operator`})]})]}),V&&(0,S.jsx)(`div`,{className:`copy-toast${V.failed?` copy-toast-failed`:``}`,role:`status`,children:V.message}),(0,S.jsx)(Oe,{error:we,onClose:()=>U(null)}),(0,S.jsx)(De,{target:Ke,onCancel:()=>Y(null),onConfirm:()=>{let e=Ke;Y(null),e&&Nt(e)}})]})}var Ie=5e3,Le=3e4,Re=3e4;function ze(){let[e,t]=(0,x.useState)(null);if((0,x.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()},Ie))}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,S.jsxs)(`div`,{className:f.join(` `),role:`status`,"aria-label":`host CPU and RAM`,children:[(0,S.jsxs)(`div`,{className:`system-stats__metric`,children:[(0,S.jsxs)(`span`,{className:i?`system-stats__fig system-stats__fig--warn`:`system-stats__fig`,children:[`CPU `,u(n)]}),(0,S.jsx)(`div`,{className:`system-stats__bar`,children:(0,S.jsx)(`div`,{className:`system-stats__bar-fill`,style:d(n)})})]}),(0,S.jsxs)(`div`,{className:`system-stats__metric`,children:[(0,S.jsxs)(`span`,{className:o?`system-stats__fig system-stats__fig--warn`:`system-stats__fig`,children:[`RAM `,u(r)]}),(0,S.jsx)(`div`,{className:`system-stats__bar`,children:(0,S.jsx)(`div`,{className:`system-stats__bar-fill`,style:d(r)})})]})]})}var K=`admin-sidebar-collapsed`,q=`admin-sidebar-drawer-open`;function Be(){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 Ve(){if(typeof window>`u`)return!1;try{return window.sessionStorage.getItem(q)===`1`}catch{return!1}}function He(e){if(!(typeof window>`u`))try{e?window.sessionStorage.setItem(q,`1`):window.sessionStorage.removeItem(q)}catch{}}var Ue=720;function We(e,t){return e===`/`?{via:`in-place`}:{via:`navigate`,href:`/?wa=${encodeURIComponent(t.remoteJid??``)}&acct=${encodeURIComponent(t.accountId??``)}`}}function Ge(e){return e===`/`?{via:`in-place`}:{via:`navigate`,href:`/?data=1`}}function Ke(e,t){if(e!==`/`)return null;let n=new URLSearchParams(t),r=n.get(`wa`),i=n.get(`acct`);return!r||!i?null:{sessionId:``,projectDir:``,title:``,senderId:null,startedAt:``,channel:`whatsapp`,role:`public`,operatorName:null,whatsappName:null,lastMessageAt:null,modelGated:!1,model:null,source:`store`,accountId:i,remoteJid:r}}function Y(e,t){return e===`/`?new URLSearchParams(t).has(`data`):!1}function qe(e,t){return t===`operator`&&e===`chat`||e===`dashboard`?`/`:e===`data`?`/data`:e===`graph`?`/graph`:e===`calendar`?`/calendar`:e===`chat`?`/chat`:`/browser`}function Je(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}=re(t),[_,te]=(0,x.useState)(()=>Be()),[v,y]=(0,x.useState)(()=>Ve()),[b,C]=(0,x.useState)(()=>typeof window<`u`&&window.matchMedia(`(max-width: ${Ue}px)`).matches),[w,T]=(0,x.useState)(()=>typeof window>`u`||Y(window.location.pathname,window.location.search)?null:Ke(window.location.pathname,window.location.search)),[oe]=(0,x.useState)(()=>w!==null),[E,D]=(0,x.useState)(()=>typeof window>`u`?!1:Y(window.location.pathname,window.location.search)),[se]=(0,x.useState)(()=>E);(0,x.useEffect)(()=>{if(typeof window>`u`)return;let e=window.matchMedia(`(max-width: ${Ue}px)`),t=e=>C(e.matches);return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]);let ce=(0,x.useCallback)(e=>{J(e),te(e)},[]),O=(0,x.useCallback)(e=>{He(e),y(e)},[]);(0,x.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,x.useEffect)(()=>{typeof window>`u`||!w||(console.info(`[admin-ui] wa-hydrate route=/ remoteJid=${w.remoteJid??``}`),window.history.replaceState(null,``,`/`))},[]),(0,x.useEffect)(()=>{typeof window>`u`||!E||(console.info(`[admin-ui] data-hydrate route=/`),window.history.replaceState(null,``,`/`))},[]);let le=(0,x.useCallback)(e=>{if(D(!1),e===null){T(null);return}let t=typeof window<`u`?window.location.pathname:`/`,n=We(t,e);console.info(`[admin-ui] wa-open route=${t} via=${n.via} sessionId=${e.sessionId.slice(0,8)}`),n.via===`in-place`?T(e):window.location.href=n.href},[]),ue=(0,x.useCallback)(()=>{let e=typeof window<`u`?window.location.pathname:`/`,t=Ge(e);if(console.info(`[admin-ui] data-open route=${e} via=${t.via}`),t.via===`navigate`){window.location.href=t.href;return}T(null),D(!0)},[]),k=b?v:!_,A=(0,x.useCallback)(()=>{if(!(typeof window>`u`))if(window.matchMedia(`(max-width: ${Ue}px)`).matches){let e=v;console.info(`[admin-ui] header-sidebar-toggle from=${e?`open`:`closed`} mode=drawer`),O(!e)}else{let e=_;console.info(`[admin-ui] header-sidebar-toggle from=${e?`closed`:`open`} mode=collapse`),ce(!e)}},[_,v,ce,O]),de=(0,x.useCallback)(e=>{let t=qe(e,r);console.info(`[admin-ui] header-menu-nav target=${e} dest=${t}`),window.location.href=t},[r]),[j,fe]=(0,x.useState)(`chat`),[M,pe]=(0,x.useState)([]);(0,x.useEffect)(()=>{if(r!==`operator`||!t)return;let e=!1;return fetch(`/api/whatsapp-reader/conversations?session_key=${encodeURIComponent(t)}`).then(e=>e.ok?e.json():{conversations:[]}).then(t=>{e||pe(t.conversations??[])}).catch(()=>{}),()=>{e=!0}},[r,t]);let me=(0,x.useMemo)(()=>[...new Set(M.map(e=>e.channel))],[M]),he={collapsed:_,mobileDrawerOpen:v,sidebarOpen:k,onToggleSidebar:A,setMobileDrawerOpen:O,selectedWhatsapp:w,onClearWhatsapp:()=>T(null),dataOpen:E};return r===`operator`?(0,S.jsxs)(`div`,{className:`admin-shell admin-page admin-shell-root`,children:[(0,S.jsx)(ae,{businessName:n,variant:r,onNavigate:de,conversationsCount:M.length,conversationsChannels:me,onOpenConversations:()=>fe(`conversations`),onToggleSidebar:A,sidebarOpen:k,onLogout:i,onDisconnect:a,disconnecting:o,cacheKey:t,subAccounts:m,activeAccountId:h,switchingAccount:g,onSwitchAccount:ee}),(0,S.jsx)(`div`,{className:`platform platform-operator`,children:j===`conversations`?(0,S.jsx)(ne,{conversations:M,sessionKey:t??``,onBack:()=>fe(`chat`)}):typeof d==`function`?d(he):d}),f]}):(0,S.jsxs)(`div`,{className:`admin-shell admin-page admin-shell-root`,children:[(0,S.jsx)(ae,{businessName:n,variant:r,onNavigate:de,onOpenConversations:u,onToggleSidebar:A,sidebarOpen:k,onLogout:i,onDisconnect:a,disconnecting:o,cacheKey:t,subAccounts:m,activeAccountId:h,switchingAccount:g,onSwitchAccount:ee}),(0,S.jsxs)(`div`,{className:`platform${v?` menu-open`:``}${_?` sidebar-collapsed`:``}`,"data-artefact":`closed`,children:[(0,S.jsx)(Fe,{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:()=>O(!1),collapsed:_,mobileDrawerOpen:v,selectedWhatsappId:w?ie(w):null,onSelectWhatsappConversation:le,initialWhatsappSurface:oe,onSelectData:ue,onCloseData:()=>D(!1),initialDataSurface:se}),!b&&(0,S.jsx)(N,{}),typeof d==`function`?d(he):d]}),v&&(0,S.jsx)(`div`,{className:`sidebar-backdrop menu-open`,"aria-hidden":`true`,onClick:()=>O(!1)}),f]})}export{oe as _,I as a,z as c,A as d,k as f,E as g,D as h,Ee as i,ve as l,O as m,Ne as n,P as o,ue as p,ke as r,F as s,Je as t,de as u,T as v,b as y};
@@ -1 +0,0 @@
1
- var e=`image/jpeg,image/png,image/gif,image/webp,application/pdf,text/plain,text/markdown,text/csv,text/html,text/calendar,application/zip,application/x-zip-compressed,audio/ogg,audio/opus,audio/mp4,audio/x-m4a,audio/mpeg,audio/webm,audio/wav,video/mp4,.opus,.ogg,.m4a,.mp4,.mp3,.wav,.webm`,t=new Set(e.split(`,`).filter(e=>!e.startsWith(`.`))),n=50*1024*1024;function r(e){switch(e){case`expanded`:return!0;case`collapsed`:return!1;default:return}}export{r as i,n,t as r,e as t};
@@ -1 +0,0 @@
1
- import{W as e,q as t}from"./useSubAccountSwitcher-DPEkYkYd.js";import"./admin-types-DJoj6VJv.js";import"./AdminShell-iHdYhspw.js";import{n}from"./page-HeiBebPq.js";var r=t(),i=e();(0,r.createRoot)(document.getElementById(`root`)).render((0,i.jsx)(n,{}));