@rubytech/create-sitedesk-code 0.1.531 → 0.1.533

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 (188) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +10 -7
  3. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
  4. package/payload/platform/plugins/docs/references/calendar-booking.md +9 -6
  5. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
  6. package/payload/platform/plugins/whatsapp/PLUGIN.md +4 -2
  7. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +35 -6
  8. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  9. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +12 -4
  10. package/payload/platform/plugins/whatsapp/skills/manage-whatsapp-config/SKILL.md +11 -1
  11. package/payload/server/{chunk-SVB5NZ64.js → chunk-AJC3SQSF.js} +114 -18
  12. package/payload/server/{manager-4Q3DTLXO.js → manager-PLRHVALC.js} +1 -1
  13. package/payload/server/public/activity.html +5 -5
  14. package/payload/server/public/agents.html +4 -4
  15. package/payload/server/public/assets/{AdminLoginScreens-7Czw3MAC.js → AdminLoginScreens-CGRty7xT.js} +1 -1
  16. package/payload/server/public/assets/AdminLoginScreens-CGRty7xT.js.br +0 -0
  17. package/payload/server/public/assets/AdminLoginScreens-CGRty7xT.js.gz +0 -0
  18. package/payload/server/public/assets/{AdminShell-D5GApZ_n.js → AdminShell-BQy9Ob22.js} +1 -1
  19. package/payload/server/public/assets/AdminShell-BQy9Ob22.js.br +0 -0
  20. package/payload/server/public/assets/AdminShell-BQy9Ob22.js.gz +0 -0
  21. package/payload/server/public/assets/{CdpScreencastSurface-BbekDUFw.js → CdpScreencastSurface-BrDZji8F.js} +1 -1
  22. package/payload/server/public/assets/CdpScreencastSurface-BrDZji8F.js.br +0 -0
  23. package/payload/server/public/assets/CdpScreencastSurface-BrDZji8F.js.gz +0 -0
  24. package/payload/server/public/assets/{activity-ClI-RgJu.js → activity-0IcMRF5a.js} +1 -1
  25. package/payload/server/public/assets/activity-0IcMRF5a.js.br +0 -0
  26. package/payload/server/public/assets/activity-0IcMRF5a.js.gz +0 -0
  27. package/payload/server/public/assets/{admin-svtCmBPk.js → admin-CKy-bmrs.js} +1 -1
  28. package/payload/server/public/assets/admin-CKy-bmrs.js.br +0 -0
  29. package/payload/server/public/assets/admin-CKy-bmrs.js.gz +0 -0
  30. package/payload/server/public/assets/{agents-BO8YBj8d.js → agents-xjw-fJjo.js} +1 -1
  31. package/payload/server/public/assets/agents-xjw-fJjo.js.br +0 -0
  32. package/payload/server/public/assets/agents-xjw-fJjo.js.gz +0 -0
  33. package/payload/server/public/assets/{browser-Bj8oTG5R.js → browser-ByWKTnUQ.js} +1 -1
  34. package/payload/server/public/assets/browser-ByWKTnUQ.js.br +0 -0
  35. package/payload/server/public/assets/browser-ByWKTnUQ.js.gz +0 -0
  36. package/payload/server/public/assets/calendar-DX2tE1B2.js +1 -0
  37. package/payload/server/public/assets/calendar-DX2tE1B2.js.br +0 -0
  38. package/payload/server/public/assets/calendar-DX2tE1B2.js.gz +0 -0
  39. package/payload/server/public/assets/chat-DkNDthRg.js +1 -0
  40. package/payload/server/public/assets/chat-DkNDthRg.js.br +0 -0
  41. package/payload/server/public/assets/chat-DkNDthRg.js.gz +0 -0
  42. package/payload/server/public/assets/chevron-left-CPwk14nY.js +1 -0
  43. package/payload/server/public/assets/chevron-right-Bz6INVTF.js +1 -0
  44. package/payload/server/public/assets/chevron-right-Bz6INVTF.js.br +0 -0
  45. package/payload/server/public/assets/clock-3YLNejcB.js +1 -0
  46. package/payload/server/public/assets/clock-3YLNejcB.js.br +0 -0
  47. package/payload/server/public/assets/clock-3YLNejcB.js.gz +0 -0
  48. package/payload/server/public/assets/data-DiDeaOUN.js +1 -0
  49. package/payload/server/public/assets/data-DiDeaOUN.js.br +0 -0
  50. package/payload/server/public/assets/data-DiDeaOUN.js.gz +0 -0
  51. package/payload/server/public/assets/{file-download-Di_s0_4w.js → file-download-ChX5qAB2.js} +1 -1
  52. package/payload/server/public/assets/file-download-ChX5qAB2.js.br +0 -0
  53. package/payload/server/public/assets/file-download-ChX5qAB2.js.gz +0 -0
  54. package/payload/server/public/assets/{file-text-CP1KIrJV.js → file-text-DziWy8hF.js} +1 -1
  55. package/payload/server/public/assets/file-text-DziWy8hF.js.br +0 -0
  56. package/payload/server/public/assets/file-text-DziWy8hF.js.gz +0 -0
  57. package/payload/server/public/assets/{graph-BCMscnCV.js → graph-Ci8RmSp3.js} +1 -1
  58. package/payload/server/public/assets/graph-Ci8RmSp3.js.br +0 -0
  59. package/payload/server/public/assets/{graph-BCMscnCV.js.gz → graph-Ci8RmSp3.js.gz} +0 -0
  60. package/payload/server/public/assets/{graph-labels-CgP17xHK.js → graph-labels-JkRVzaVL.js} +1 -1
  61. package/payload/server/public/assets/graph-labels-JkRVzaVL.js.br +0 -0
  62. package/payload/server/public/assets/graph-labels-JkRVzaVL.js.gz +0 -0
  63. package/payload/server/public/assets/{maximize-2-DkQzDv-g.js → maximize-2-DnINkTp0.js} +1 -1
  64. package/payload/server/public/assets/maximize-2-DnINkTp0.js.br +0 -0
  65. package/payload/server/public/assets/maximize-2-DnINkTp0.js.gz +0 -0
  66. package/payload/server/public/assets/{operator-CLbCar9e.js → operator-CFOJBXCH.js} +1 -1
  67. package/payload/server/public/assets/operator-CFOJBXCH.js.br +0 -0
  68. package/payload/server/public/assets/operator-CFOJBXCH.js.gz +0 -0
  69. package/payload/server/public/assets/{page-CPVUAwb8.js → page-BGv8bLm5.js} +1 -1
  70. package/payload/server/public/assets/page-BGv8bLm5.js.br +0 -0
  71. package/payload/server/public/assets/page-BGv8bLm5.js.gz +0 -0
  72. package/payload/server/public/assets/{page-CNJl3tWT.js → page-DXTCBZRa.js} +1 -1
  73. package/payload/server/public/assets/page-DXTCBZRa.js.br +0 -0
  74. package/payload/server/public/assets/page-DXTCBZRa.js.gz +0 -0
  75. package/payload/server/public/assets/{public-DQea3Ybz.js → public-yBY2wTJN.js} +1 -1
  76. package/payload/server/public/assets/public-yBY2wTJN.js.br +0 -0
  77. package/payload/server/public/assets/public-yBY2wTJN.js.gz +0 -0
  78. package/payload/server/public/assets/{rotate-ccw-DPw0vXC0.js → rotate-ccw-CfaIgRAI.js} +1 -1
  79. package/payload/server/public/assets/rotate-ccw-CfaIgRAI.js.br +0 -0
  80. package/payload/server/public/assets/rotate-ccw-CfaIgRAI.js.gz +0 -0
  81. package/payload/server/public/assets/{routines-CwiiYpfK.js → routines-BIlcD8sn.js} +1 -1
  82. package/payload/server/public/assets/routines-BIlcD8sn.js.br +0 -0
  83. package/payload/server/public/assets/routines-BIlcD8sn.js.gz +0 -0
  84. package/payload/server/public/assets/{skills-0FOjKUM-.js → skills-DGID2WqF.js} +1 -1
  85. package/payload/server/public/assets/skills-DGID2WqF.js.br +0 -0
  86. package/payload/server/public/assets/skills-DGID2WqF.js.gz +0 -0
  87. package/payload/server/public/assets/{tasks-BUVsPEGm.js → tasks-BukjwR7A.js} +1 -1
  88. package/payload/server/public/assets/tasks-BukjwR7A.js.br +0 -0
  89. package/payload/server/public/assets/tasks-BukjwR7A.js.gz +0 -0
  90. package/payload/server/public/assets/{time-entry-format-B6fX_19a.js → time-entry-format-DNl35lg9.js} +1 -1
  91. package/payload/server/public/assets/time-entry-format-DNl35lg9.js.br +0 -0
  92. package/payload/server/public/assets/time-entry-format-DNl35lg9.js.gz +0 -0
  93. package/payload/server/public/assets/{triangle-alert-vAaSDhVq.js → triangle-alert-DI_VASJO.js} +1 -1
  94. package/payload/server/public/assets/triangle-alert-DI_VASJO.js.br +0 -0
  95. package/payload/server/public/assets/triangle-alert-DI_VASJO.js.gz +0 -0
  96. package/payload/server/public/assets/{useCopyFeedback-BvIRgs7W.js → useCopyFeedback-Bu0ZQZQM.js} +1 -1
  97. package/payload/server/public/assets/useCopyFeedback-Bu0ZQZQM.js.br +0 -0
  98. package/payload/server/public/assets/useCopyFeedback-Bu0ZQZQM.js.gz +0 -0
  99. package/payload/server/public/assets/{useSubAccountSwitcher-DM5Y9eio.css → useSubAccountSwitcher-CZBZ3iV8.css} +1 -1
  100. package/payload/server/public/assets/useSubAccountSwitcher-CZBZ3iV8.css.br +0 -0
  101. package/payload/server/public/assets/{useSubAccountSwitcher-DM5Y9eio.css.gz → useSubAccountSwitcher-CZBZ3iV8.css.gz} +0 -0
  102. package/payload/server/public/assets/{useVoiceRecorder-CiDOh8PG.js → useVoiceRecorder-CbVwXEjY.js} +1 -1
  103. package/payload/server/public/assets/useVoiceRecorder-CbVwXEjY.js.br +0 -0
  104. package/payload/server/public/assets/useVoiceRecorder-CbVwXEjY.js.gz +0 -0
  105. package/payload/server/public/assets/{wrench-BNBtwT2p.js → wrench-p4gW_ImW.js} +1 -1
  106. package/payload/server/public/assets/wrench-p4gW_ImW.js.br +0 -0
  107. package/payload/server/public/assets/wrench-p4gW_ImW.js.gz +0 -0
  108. package/payload/server/public/browser.html +5 -5
  109. package/payload/server/public/calendar.html +7 -7
  110. package/payload/server/public/chat.html +13 -13
  111. package/payload/server/public/data.html +12 -12
  112. package/payload/server/public/graph.html +9 -9
  113. package/payload/server/public/index.html +16 -16
  114. package/payload/server/public/operator.html +15 -15
  115. package/payload/server/public/public.html +13 -13
  116. package/payload/server/public/routines.html +7 -7
  117. package/payload/server/public/skills.html +5 -5
  118. package/payload/server/public/tasks.html +6 -6
  119. package/payload/server/server.js +1230 -886
  120. package/payload/server/public/assets/AdminLoginScreens-7Czw3MAC.js.br +0 -0
  121. package/payload/server/public/assets/AdminLoginScreens-7Czw3MAC.js.gz +0 -0
  122. package/payload/server/public/assets/AdminShell-D5GApZ_n.js.br +0 -0
  123. package/payload/server/public/assets/AdminShell-D5GApZ_n.js.gz +0 -0
  124. package/payload/server/public/assets/CdpScreencastSurface-BbekDUFw.js.br +0 -0
  125. package/payload/server/public/assets/CdpScreencastSurface-BbekDUFw.js.gz +0 -0
  126. package/payload/server/public/assets/activity-ClI-RgJu.js.br +0 -0
  127. package/payload/server/public/assets/activity-ClI-RgJu.js.gz +0 -0
  128. package/payload/server/public/assets/admin-svtCmBPk.js.br +0 -0
  129. package/payload/server/public/assets/admin-svtCmBPk.js.gz +0 -0
  130. package/payload/server/public/assets/agents-BO8YBj8d.js.br +0 -0
  131. package/payload/server/public/assets/agents-BO8YBj8d.js.gz +0 -0
  132. package/payload/server/public/assets/browser-Bj8oTG5R.js.br +0 -0
  133. package/payload/server/public/assets/browser-Bj8oTG5R.js.gz +0 -0
  134. package/payload/server/public/assets/calendar-CrkSY8U7.js +0 -1
  135. package/payload/server/public/assets/calendar-CrkSY8U7.js.br +0 -0
  136. package/payload/server/public/assets/calendar-CrkSY8U7.js.gz +0 -0
  137. package/payload/server/public/assets/chat-Bvxoni2e.js +0 -1
  138. package/payload/server/public/assets/chat-Bvxoni2e.js.br +0 -0
  139. package/payload/server/public/assets/chat-Bvxoni2e.js.gz +0 -0
  140. package/payload/server/public/assets/chevron-left-CdUzxzeB.js +0 -1
  141. package/payload/server/public/assets/chevron-left-CdUzxzeB.js.br +0 -0
  142. package/payload/server/public/assets/chevron-right-CKGwd-M0.js +0 -1
  143. package/payload/server/public/assets/chevron-right-CKGwd-M0.js.br +0 -0
  144. package/payload/server/public/assets/clock-Cf8Oe9qi.js +0 -1
  145. package/payload/server/public/assets/clock-Cf8Oe9qi.js.br +0 -0
  146. package/payload/server/public/assets/clock-Cf8Oe9qi.js.gz +0 -0
  147. package/payload/server/public/assets/data-DF0Pstdp.js +0 -1
  148. package/payload/server/public/assets/data-DF0Pstdp.js.br +0 -1
  149. package/payload/server/public/assets/data-DF0Pstdp.js.gz +0 -0
  150. package/payload/server/public/assets/file-download-Di_s0_4w.js.br +0 -0
  151. package/payload/server/public/assets/file-download-Di_s0_4w.js.gz +0 -0
  152. package/payload/server/public/assets/file-text-CP1KIrJV.js.br +0 -1
  153. package/payload/server/public/assets/file-text-CP1KIrJV.js.gz +0 -0
  154. package/payload/server/public/assets/graph-BCMscnCV.js.br +0 -0
  155. package/payload/server/public/assets/graph-labels-CgP17xHK.js.br +0 -0
  156. package/payload/server/public/assets/graph-labels-CgP17xHK.js.gz +0 -0
  157. package/payload/server/public/assets/maximize-2-DkQzDv-g.js.br +0 -0
  158. package/payload/server/public/assets/maximize-2-DkQzDv-g.js.gz +0 -0
  159. package/payload/server/public/assets/operator-CLbCar9e.js.br +0 -0
  160. package/payload/server/public/assets/operator-CLbCar9e.js.gz +0 -0
  161. package/payload/server/public/assets/page-CNJl3tWT.js.br +0 -0
  162. package/payload/server/public/assets/page-CNJl3tWT.js.gz +0 -0
  163. package/payload/server/public/assets/page-CPVUAwb8.js.br +0 -0
  164. package/payload/server/public/assets/page-CPVUAwb8.js.gz +0 -0
  165. package/payload/server/public/assets/public-DQea3Ybz.js.br +0 -0
  166. package/payload/server/public/assets/public-DQea3Ybz.js.gz +0 -0
  167. package/payload/server/public/assets/rotate-ccw-DPw0vXC0.js.br +0 -0
  168. package/payload/server/public/assets/rotate-ccw-DPw0vXC0.js.gz +0 -0
  169. package/payload/server/public/assets/routines-CwiiYpfK.js.br +0 -0
  170. package/payload/server/public/assets/routines-CwiiYpfK.js.gz +0 -0
  171. package/payload/server/public/assets/skills-0FOjKUM-.js.br +0 -0
  172. package/payload/server/public/assets/skills-0FOjKUM-.js.gz +0 -0
  173. package/payload/server/public/assets/tasks-BUVsPEGm.js.br +0 -0
  174. package/payload/server/public/assets/tasks-BUVsPEGm.js.gz +0 -0
  175. package/payload/server/public/assets/time-entry-format-B6fX_19a.js.br +0 -0
  176. package/payload/server/public/assets/time-entry-format-B6fX_19a.js.gz +0 -0
  177. package/payload/server/public/assets/triangle-alert-vAaSDhVq.js.br +0 -0
  178. package/payload/server/public/assets/triangle-alert-vAaSDhVq.js.gz +0 -0
  179. package/payload/server/public/assets/useCopyFeedback-BvIRgs7W.js.br +0 -0
  180. package/payload/server/public/assets/useCopyFeedback-BvIRgs7W.js.gz +0 -0
  181. package/payload/server/public/assets/useSubAccountSwitcher-DM5Y9eio.css.br +0 -0
  182. package/payload/server/public/assets/useVoiceRecorder-CiDOh8PG.js.br +0 -0
  183. package/payload/server/public/assets/useVoiceRecorder-CiDOh8PG.js.gz +0 -0
  184. package/payload/server/public/assets/wrench-BNBtwT2p.js.br +0 -0
  185. package/payload/server/public/assets/wrench-BNBtwT2p.js.gz +0 -0
  186. /package/payload/server/public/assets/{useSubAccountSwitcher-BEwQMRMo.js → useSubAccountSwitcher-B6Ns2Z43.js} +0 -0
  187. /package/payload/server/public/assets/{useSubAccountSwitcher-BEwQMRMo.js.br → useSubAccountSwitcher-B6Ns2Z43.js.br} +0 -0
  188. /package/payload/server/public/assets/{useSubAccountSwitcher-BEwQMRMo.js.gz → useSubAccountSwitcher-B6Ns2Z43.js.gz} +0 -0
@@ -240,8 +240,7 @@ function discardAuthDirSync(authDir) {
240
240
  return false;
241
241
  }
242
242
  }
243
- function listCredentialAccountIds(configDir2) {
244
- const credsRoot = path.join(os.homedir(), configDir2, "credentials", "whatsapp");
243
+ function listCredentialAccountIdsAtRoot(credsRoot) {
245
244
  try {
246
245
  const entries = fsSync.readdirSync(credsRoot, { withFileTypes: true });
247
246
  return entries.filter((e) => e.isDirectory() && hasCredsSync(path.join(credsRoot, e.name))).map((e) => e.name);
@@ -249,6 +248,18 @@ function listCredentialAccountIds(configDir2) {
249
248
  return [];
250
249
  }
251
250
  }
251
+ function listCredentialAccountIds(configDir2) {
252
+ return listCredentialAccountIdsAtRoot(
253
+ path.join(os.homedir(), configDir2, "credentials", "whatsapp")
254
+ );
255
+ }
256
+ function listCredentialSelfPhones(credsRoot) {
257
+ try {
258
+ return fsSync.readdirSync(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(path.join(credsRoot, e.name))).map((e) => ({ accountId: e.name, selfPhone: readSelfId(path.join(credsRoot, e.name)).e164 }));
259
+ } catch {
260
+ return [];
261
+ }
262
+ }
252
263
 
253
264
  // app/lib/whatsapp/session.ts
254
265
  import { randomUUID } from "crypto";
@@ -1633,7 +1644,12 @@ function resolveAccountConfig(config, accountConfig) {
1633
1644
  selfChatMode: accountConfig?.selfChatMode ?? false,
1634
1645
  // Account-manager bindings are a house-level routing table only — never a
1635
1646
  // per-account override, so this reads the top-level map unconditionally.
1636
- accountManagers: config.accountManagers ?? {}
1647
+ accountManagers: config.accountManagers ?? {},
1648
+ sources: {
1649
+ dmPolicy: accountConfig?.dmPolicy !== void 0 ? "account" : "house",
1650
+ adminPhones: accountConfig?.adminPhones !== void 0 ? "account" : "house",
1651
+ allowFrom: accountConfig?.allowFrom !== void 0 ? "account" : "house"
1652
+ }
1637
1653
  };
1638
1654
  }
1639
1655
  function isAdminPhone(phone, adminPhones) {
@@ -1642,38 +1658,89 @@ function isAdminPhone(phone, adminPhones) {
1642
1658
  return adminPhones.some((entry2) => phonesMatch(entry2, normalized));
1643
1659
  }
1644
1660
  function checkDmAccess(params) {
1645
- const { senderPhone, selfPhone, accountId } = params;
1661
+ const { senderPhone, selfPhone, accountId, houseAccountId } = params;
1646
1662
  const cfg = resolveAccountConfig(params.config, params.accountConfig);
1647
1663
  if (phonesMatch(senderPhone, selfPhone)) {
1648
1664
  return { allowed: true, reason: "self-phone", agentType: "admin", effectiveAccountId: accountId };
1649
1665
  }
1650
- if (isAdminPhone(senderPhone, cfg.adminPhones)) {
1651
- return { allowed: true, reason: "admin-binding", agentType: "admin", effectiveAccountId: accountId };
1652
- }
1653
1666
  const managed = managedAccountFor(cfg.accountManagers, senderPhone);
1654
- if (managed) {
1655
- if (params.isValidAccount && !params.isValidAccount(managed.account)) {
1667
+ const managerAdmit = (bound) => {
1668
+ if (params.isValidAccount && !params.isValidAccount(bound.account)) {
1656
1669
  return { allowed: false, reason: "account-manager-unresolved", agentType: "admin" };
1657
1670
  }
1658
- return { allowed: true, reason: "account-manager", agentType: "admin", effectiveAccountId: managed.account, passive: managed.mode === "passive" };
1671
+ return {
1672
+ allowed: true,
1673
+ reason: "account-manager",
1674
+ agentType: "admin",
1675
+ effectiveAccountId: bound.account,
1676
+ passive: bound.mode === "passive"
1677
+ };
1678
+ };
1679
+ if (managed && accountId !== void 0 && managed.account === accountId) {
1680
+ return managerAdmit(managed);
1681
+ }
1682
+ if (isAdminPhone(senderPhone, cfg.adminPhones)) {
1683
+ return {
1684
+ allowed: true,
1685
+ reason: "admin-binding",
1686
+ agentType: "admin",
1687
+ effectiveAccountId: accountId,
1688
+ policyField: "adminPhones",
1689
+ policySource: cfg.sources.adminPhones
1690
+ };
1691
+ }
1692
+ if (managed && houseAccountId !== void 0 && accountId === houseAccountId) {
1693
+ return managerAdmit(managed);
1659
1694
  }
1660
1695
  switch (cfg.dmPolicy) {
1661
1696
  case "open":
1662
- return { allowed: true, reason: "dm-policy-open", agentType: "public", effectiveAccountId: accountId };
1697
+ return {
1698
+ allowed: true,
1699
+ reason: "dm-policy-open",
1700
+ agentType: "public",
1701
+ effectiveAccountId: accountId,
1702
+ policyField: "dmPolicy",
1703
+ policySource: cfg.sources.dmPolicy
1704
+ };
1663
1705
  case "allowlist": {
1664
1706
  const inList = cfg.allowFrom.some((entry2) => {
1665
1707
  if (entry2 === "*") return true;
1666
1708
  return phonesMatch(entry2, senderPhone);
1667
1709
  });
1668
1710
  if (inList) {
1669
- return { allowed: true, reason: "allowlist-match", agentType: "public", effectiveAccountId: accountId };
1711
+ return {
1712
+ allowed: true,
1713
+ reason: "allowlist-match",
1714
+ agentType: "public",
1715
+ effectiveAccountId: accountId,
1716
+ policyField: "allowFrom",
1717
+ policySource: cfg.sources.allowFrom
1718
+ };
1670
1719
  }
1671
- return { allowed: false, reason: "not-in-allowlist", agentType: "public" };
1720
+ return {
1721
+ allowed: false,
1722
+ reason: "not-in-allowlist",
1723
+ agentType: "public",
1724
+ policyField: "allowFrom",
1725
+ policySource: cfg.sources.allowFrom
1726
+ };
1672
1727
  }
1673
1728
  case "disabled":
1674
- return { allowed: false, reason: "dm-policy-disabled", agentType: "public" };
1729
+ return {
1730
+ allowed: false,
1731
+ reason: "dm-policy-disabled",
1732
+ agentType: "public",
1733
+ policyField: "dmPolicy",
1734
+ policySource: cfg.sources.dmPolicy
1735
+ };
1675
1736
  default:
1676
- return { allowed: false, reason: "unknown-dm-policy", agentType: "public" };
1737
+ return {
1738
+ allowed: false,
1739
+ reason: "unknown-dm-policy",
1740
+ agentType: "public",
1741
+ policyField: "dmPolicy",
1742
+ policySource: cfg.sources.dmPolicy
1743
+ };
1677
1744
  }
1678
1745
  }
1679
1746
  async function resolveDmAccess(params) {
@@ -1694,6 +1761,16 @@ async function resolveDmAccess(params) {
1694
1761
  function checkGroupAccess(_params) {
1695
1762
  return { allowed: false, reason: "group-observe-only", agentType: "public" };
1696
1763
  }
1764
+ function buildPolicyInheritance(params) {
1765
+ const rows = params.accountKeys.map((accountId) => {
1766
+ const { sources } = resolveAccountConfig(params.config, params.config.accounts?.[accountId]);
1767
+ return { accountId, dmPolicy: sources.dmPolicy, adminPhones: sources.adminPhones, allowFrom: sources.allowFrom };
1768
+ });
1769
+ const inheritedCount = rows.filter(
1770
+ (r) => r.dmPolicy === "house" || r.adminPhones === "house" || r.allowFrom === "house"
1771
+ ).length;
1772
+ return { rows, inheritedCount };
1773
+ }
1697
1774
 
1698
1775
  // app/lib/whatsapp/inbound/dispatch-mode.ts
1699
1776
  function shouldDispatchInbound(config, accountId) {
@@ -2212,7 +2289,7 @@ async function sendTextMessage(sock, to, text, opts) {
2212
2289
  const messageId = result?.key?.id;
2213
2290
  if (messageId) {
2214
2291
  trackAgentSentMessage(messageId);
2215
- console.error(`${TAG9} sent text to=${jid} id=${messageId}`);
2292
+ console.error(`${TAG9} sent text to=${jid} id=${messageId} account=${opts?.accountId ?? "unknown"}`);
2216
2293
  }
2217
2294
  if (opts?.accountId) {
2218
2295
  recordActivity({ accountId: opts.accountId, direction: "outbound", jid, messageType: "text" });
@@ -2296,7 +2373,7 @@ async function sendMediaMessage(sock, to, media, opts) {
2296
2373
  const messageId = result?.key?.id;
2297
2374
  if (messageId) {
2298
2375
  trackAgentSentMessage(messageId);
2299
- console.error(`${TAG9} sent ${media.type} to=${jid} id=${messageId}`);
2376
+ console.error(`${TAG9} sent ${media.type} to=${jid} id=${messageId} account=${opts?.accountId ?? "unknown"}`);
2300
2377
  }
2301
2378
  if (opts?.accountId) {
2302
2379
  recordActivity({ accountId: opts.accountId, direction: "outbound", jid, messageType: media.type });
@@ -4112,6 +4189,11 @@ function resolveConversationPersistAccount(sendAccountId, counterpartyPhone) {
4112
4189
  // to `effectiveAccountId` for every non-manager admit, and that value reaches
4113
4190
  // the graph and the spawn; the dirname is a credential path, not an account.
4114
4191
  accountId: conn.platformAccountId,
4192
+ // Task 2227 — arm 4. The task named only the two inbound call sites; without
4193
+ // it here a non-admin manager's REPLY persists under the connection account
4194
+ // while their inbound persisted under the bound sub-account: one thread, two
4195
+ // accounts, the split Task 1786 exists to prevent.
4196
+ houseAccountId: conn.houseAccountId,
4115
4197
  isValidAccount: (id) => isValidAccountId(id)
4116
4198
  });
4117
4199
  return resolveInboundPersistAccount({
@@ -4600,6 +4682,8 @@ function monitorInbound(conn) {
4600
4682
  // Task 1850 — the account SCOPE is the platform UUID, never the
4601
4683
  // dirname. See resolveConversationPersistAccount.
4602
4684
  accountId: conn.platformAccountId,
4685
+ // Task 2227 — the account of the number messaged decides the arm.
4686
+ houseAccountId: conn.houseAccountId,
4603
4687
  isValidAccount: (id) => isValidAccountId(id)
4604
4688
  });
4605
4689
  const persistAccountId = resolveInboundPersistAccount({
@@ -5030,12 +5114,18 @@ async function handleInboundMessage(conn, msg) {
5030
5114
  config: whatsAppConfig,
5031
5115
  accountConfig: whatsAppConfig.accounts?.[conn.accountId],
5032
5116
  accountId: conn.platformAccountId,
5117
+ // Task 2227 — the account of the number messaged decides the arm.
5118
+ houseAccountId: conn.houseAccountId,
5033
5119
  isValidAccount: (id) => isValidAccountId(id),
5034
5120
  resolvePersonByPhone
5035
5121
  });
5036
5122
  }
5037
5123
  console.error(
5038
- `${TAG17} inbound account=${conn.accountId} from=${senderPhone} group=${isGroup} access=${accessResult.allowed ? "allowed" : "blocked"}(${accessResult.reason}) agent=${accessResult.agentType}` + (extracted.mediaType ? ` media=${extracted.mediaType}` : "") + (extracted.quotedMessage ? ` replyTo=${extracted.quotedMessage.id}` : "")
5124
+ `${TAG17} inbound account=${conn.accountId} from=${senderPhone} group=${isGroup} access=${accessResult.allowed ? "allowed" : "blocked"}(${accessResult.reason}) agent=${accessResult.agentType} effectiveAccount=${accessResult.effectiveAccountId ?? ""} destAccount=${conn.platformAccountId}` + // Task 2235 an inherited policy behaves exactly like a set one until the
5125
+ // house changes, so the verdict has to say which it was. Emitted only for the
5126
+ // arms a policy field actually decided; the self-phone and account-manager
5127
+ // arms consult none, and stamping them would assert something untrue.
5128
+ (accessResult.policySource ? ` policySource=${accessResult.policySource} policyField=${accessResult.policyField}` : "") + (extracted.mediaType ? ` media=${extracted.mediaType}` : "") + (extracted.quotedMessage ? ` replyTo=${extracted.quotedMessage.id}` : "")
5039
5129
  );
5040
5130
  if (!accessResult.allowed && accessResult.reason === "account-manager-unresolved") {
5041
5131
  console.error(
@@ -5174,6 +5264,7 @@ export {
5174
5264
  readConversationSummaries,
5175
5265
  readAllConversations,
5176
5266
  enumerateValidAccountIds,
5267
+ isProvisionedAccount,
5177
5268
  resolveHouseOrSoleAccountId,
5178
5269
  getAccountsDirFromEnv,
5179
5270
  validateAccountIdEnv,
@@ -5198,6 +5289,8 @@ export {
5198
5289
  getAuthAgeMs,
5199
5290
  clearAuth,
5200
5291
  discardAuthDirSync,
5292
+ listCredentialAccountIdsAtRoot,
5293
+ listCredentialSelfPhones,
5201
5294
  startVersionDriftCensus,
5202
5295
  drainCredsSaveQueue,
5203
5296
  createWaSocket,
@@ -5219,7 +5312,9 @@ export {
5219
5312
  readLidMap,
5220
5313
  managedAccountFor,
5221
5314
  managerPhonesForAccount,
5315
+ resolveAccountConfig,
5222
5316
  isAdminPhone,
5317
+ buildPolicyInheritance,
5223
5318
  shouldDispatchInbound,
5224
5319
  formatSenderPhone,
5225
5320
  checkAccessRateLimit,
@@ -5251,6 +5346,7 @@ export {
5251
5346
  writeChatMetadataMerged,
5252
5347
  groupEntriesFromUpdates,
5253
5348
  resolvePlatformAccountId,
5349
+ resolveHouseAccountId,
5254
5350
  warnNonUuidAccount,
5255
5351
  isHouseManagedService,
5256
5352
  isCustomerTurnSuppressed,
@@ -30,7 +30,7 @@ import {
30
30
  startConnection,
31
31
  stopConnection,
32
32
  storeMessage
33
- } from "./chunk-SVB5NZ64.js";
33
+ } from "./chunk-AJC3SQSF.js";
34
34
  import "./chunk-BP7LH7MC.js";
35
35
  import "./chunk-PFF6I7KP.js";
36
36
  export {
@@ -5,12 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Activity — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/activity-ClI-RgJu.js"></script>
8
+ <script type="module" crossorigin src="/assets/activity-0IcMRF5a.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CltuBf4Z.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-BEwQMRMo.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-D5GApZ_n.js">
12
- <link rel="modulepreload" crossorigin href="/assets/triangle-alert-vAaSDhVq.js">
13
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DM5Y9eio.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B6Ns2Z43.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-BQy9Ob22.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/triangle-alert-DI_VASJO.js">
13
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-CZBZ3iV8.css">
14
14
  <link rel="stylesheet" href="/brand-defaults.css">
15
15
  </head>
16
16
  <body>
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Agents — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/agents-BO8YBj8d.js"></script>
8
+ <script type="module" crossorigin src="/assets/agents-xjw-fJjo.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CltuBf4Z.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-BEwQMRMo.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-D5GApZ_n.js">
12
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DM5Y9eio.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-B6Ns2Z43.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-BQy9Ob22.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-CZBZ3iV8.css">
13
13
  <link rel="stylesheet" href="/brand-defaults.css">
14
14
  </head>
15
15
  <body>
@@ -1 +1 @@
1
- import{o as e}from"./chunk-CltuBf4Z.js";import{B as t,H as n,J as r,R as i,W as a,g as o}from"./useSubAccountSwitcher-BEwQMRMo.js";import{k as s}from"./useVoiceRecorder-CiDOh8PG.js";import{D as c,E as l,O as u}from"./AdminShell-D5GApZ_n.js";import{t as d}from"./CdpScreencastSurface-BbekDUFw.js";var f=e(r(),1);function p(e=`admin`){let[t,n]=(0,f.useState)(`loading`),[r,i]=(0,f.useState)(``),[o,c]=(0,f.useState)(``),[l,d]=(0,f.useState)(``),[p,m]=(0,f.useState)(!1),[h,g]=(0,f.useState)(!1),[_,v]=(0,f.useState)(!1),[y,b]=(0,f.useState)(!1),[x,S]=(0,f.useState)(!1),[C,w]=(0,f.useState)(null),[T,E]=(0,f.useState)(null),[D,O]=(0,f.useState)(void 0),[k,A]=(0,f.useState)(null),[j,M]=(0,f.useState)(void 0),[N,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(void 0),z=(0,f.useRef)(void 0),[B,V]=(0,f.useState)(!1),[H,U]=(0,f.useState)(!0);(0,f.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&V(!0)}).catch(()=>{})},[]);let W=(0,f.useRef)(null),G=(0,f.useRef)(null);(0,f.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let r=await t.json();w(r.session_key),I(r.sessionId??null),O(r.businessName),A(r.role??null),M(r.userName===void 0?null:r.userName),P(r.avatar??null);let i=s(r.thinkingView);return z.current=i,R(i),n(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(r=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check returned ${i.status} after retries`),n(`set-pin`);return}let a=await i.json();if(!a.pin_configured){n(`set-pin`);return}U(!!a.claude_authenticated);let o=!1;try{o=new URLSearchParams(window.location.search).get(`connect`)===`claude`}catch{}if(o){try{let e=new URL(window.location.href);e.searchParams.delete(`connect`),window.history.replaceState(null,``,e.pathname+e.search+e.hash)}catch{}if(!a.claude_authenticated){n(`connect-claude`);return}}if(await e())return;n(`enter-pin`)}catch(e){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check failed:`,e),n(`set-pin`)}}t()},[]),(0,f.useEffect)(()=>{t===`chat`&&C&&fetch(`/api/admin/claude-info?session_key=${encodeURIComponent(C)}`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&E(e)}).catch(()=>{})},[t,C]);let K=(0,f.useRef)(null);(0,f.useEffect)(()=>{if(t!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();U(t.auth_status!==`dead`&&t.auth_status!==`missing`)}}catch{}if(C)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(C)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(t===`remote-auth-required`){a(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),K.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[t,C]),(0,f.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(U(!0),n(`enter-pin`))}).catch(()=>{})},[t]);async function q(e,t){g(!0);try{let r=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...t?{accountId:t}:{}})});if(!r.ok){let e=await r.json().catch(()=>({}));if(r.status===401&&e?.code===`remote-auth-required`){a(`enter-pin`,`/api/admin/session`);return}d(e.error||`Invalid PIN`);return}let o=await r.json();w(o.session_key),I(o.sessionId??null),O(o.businessName),A(o.role??null),M(o.userName===void 0?null:o.userName),P(o.avatar??null);let c=s(o.thinkingView);z.current=c,R(c);try{sessionStorage.setItem(`maxy-admin-session-key`,o.session_key)}catch{}i(``),n(`chat`)}catch(e){console.error(`[admin] connection error:`,e),d(`Could not connect.`)}finally{g(!1)}}let J=(0,f.useCallback)(async e=>{if(e.preventDefault(),h)return;d(``);let t=o.trim();if(!t){d(`Please enter your name.`);return}if(r.length<4){d(`PIN must be at least 4 characters.`);return}let s=r;g(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:s,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===401&&t?.code===`remote-auth-required`){a(`set-pin`,`/api/onboarding/set-pin`);return}if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let r=await e.json();r.pin_configured&&r.claude_authenticated?n(`enter-pin`):r.pin_configured?n(`connect-claude`):d(t.error||`Failed to set PIN.`)}else n(`enter-pin`)}catch{n(`enter-pin`)}return}d(t.error||`Failed to set PIN.`);return}let r=await fetch(`/api/health`);if((r.ok?await r.json():null)?.claude_authenticated){await q(s);return}i(``),n(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),d(`Could not connect.`)}finally{g(!1)}},[r,h,o]),Y=(0,f.useCallback)(async e=>{e.preventDefault(),d(``),await q(r)},[r]),X=(0,f.useCallback)(async()=>{S(!0);try{if(!await u())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;U(!1),w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return n(`connect-claude`),!0}finally{S(!1)}},[]),Z=(0,f.useCallback)(()=>{w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}i(``),d(``),n(`enter-pin`)},[]);return(0,f.useEffect)(()=>{K.current=Z},[Z]),{appState:t,setAppState:n,pin:r,setPin:i,operatorName:o,setOperatorName:c,pinError:l,setPinError:d,showPin:p,setShowPin:m,pinLoading:h,authPolling:_,setAuthPolling:v,authLoading:y,setAuthLoading:b,disconnecting:x,cacheKey:C,setCacheKey:w,claudeInfo:T,setClaudeInfo:E,businessName:D,role:k,userName:j,userAvatar:N,sessionId:F,setSessionId:I,expandAll:L,setExpandAll:R,expandAllDefaultRef:z,remoteAuthEnabled:B,claudeConnected:H,pinInputRef:W,setPinFormRef:G,handleSetPin:J,handleLogin:Y,handleDisconnect:X,handleLogout:Z}}var m=n();function h({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,f.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,m.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,m.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function g(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:g,setOperatorName:_}=e;return(0,m.jsx)(`div`,{className:`connect-page`,children:(0,m.jsxs)(`div`,{className:`connect-content`,children:[(0,m.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,m.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,i.productName]}),(0,m.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,i.productName,` who you are, then choose a PIN.`]}),(0,m.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,m.jsxs)(`div`,{className:`pin-input-row`,children:[(0,m.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:g,onChange:e=>_(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,m.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,m.jsxs)(`div`,{className:`pin-input-row`,children:[(0,m.jsx)(h,{inputRef:d,value:n,onChange:r,onComplete:()=>{},showPin:a}),(0,m.jsx)(l,{variant:`send`,type:`submit`,disabled:!n||!g.trim(),loading:s,"aria-label":`Set PIN`,children:(0,m.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,m.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,m.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,m.jsx)(c,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,m.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function _(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:u,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:g}=e;return(0,m.jsxs)(`div`,{className:`connect-page`,children:[p&&g&&(0,m.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:g,children:`Sign out`}),(0,m.jsxs)(`div`,{className:`connect-content`,children:[(0,m.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,m.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,m.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,m.jsxs)(`div`,{className:`pin-input-row`,children:[(0,m.jsx)(h,{inputRef:d,value:n,onChange:r,onComplete:()=>{},showPin:a,autoFocus:!0}),(0,m.jsx)(l,{variant:`send`,type:`submit`,disabled:!n,loading:s,children:(0,m.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,m.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,m.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,m.jsx)(`div`,{className:`pin-options`,children:(0,m.jsx)(c,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})})]}),u&&(0,m.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function v(e){let{authPolling:n,setAuthPolling:r,authLoading:a,setAuthLoading:o,pinError:s,setPinError:c,setAppState:u}=e,[p,h]=(0,f.useState)(!1),[g,_]=(0,f.useState)(!1),[v,y]=(0,f.useState)(``),[b,x]=(0,f.useState)(``),[S,C]=(0,f.useState)(``),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(null),[O,k]=(0,f.useState)(!1);(0,f.useEffect)(()=>{try{D(sessionStorage.getItem(`maxy-admin-session-key`))}catch{}k(!0)},[]);async function A(){C(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`paste-code`,code:b})})).json();e.accepted?(C(`Code submitted. Finishing sign-in…`),x(``)):C(e.error||`Could not submit code.`)}catch(e){console.error(`[admin] paste-code error:`,e),C(`Could not submit code.`)}}async function j(){_(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?h(!0):e.error&&c(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),c(`Could not launch browser.`)}_(!1)}async function M(){o(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){r(!0),h(!0),o(!1),y(e.transport||``);for(let e=0;e<120;e++){await new Promise(e=>setTimeout(e,2e3));let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json();if(typeof e.authTargetId==`string`&&T(e.authTargetId),e.authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}}c(`Timed out waiting for sign-in. Try again.`),r(!1)}else e.error&&c(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),c(`Could not start auth flow.`)}o(!1)}async function N(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),r(!1),c(``)}return n||p?(0,m.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,m.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[n?(0,m.jsx)(`button`,{onClick:N,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,m.jsx)(`button`,{onClick:()=>h(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,m.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,m.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,m.jsx)(`p`,{className:`chat-intro`,children:n?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!n&&(0,m.jsx)(`div`,{style:{marginTop:`12px`},children:(0,m.jsx)(l,{variant:`primary`,onClick:M,disabled:a,children:a?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),n&&v===`native`&&(0,m.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,m.jsx)(`label`,{style:{fontSize:`12px`,color:`#999`,lineHeight:1.4},children:`If the browser didn't finish sign-in, paste the code or full redirect URL from Claude's page:`}),(0,m.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,m.jsx)(`input`,{type:`text`,value:b,onChange:e=>x(e.target.value),placeholder:`Paste code or redirect URL`,style:{flex:1,padding:`8px 10px`,fontSize:`13px`,border:`1px solid #ccc`,borderRadius:`6px`}}),(0,m.jsx)(l,{variant:`primary`,onClick:A,disabled:!b.trim(),children:`Submit`})]}),S&&(0,m.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:S})]})]}),(0,m.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:O&&(0,m.jsx)(d,{preferTargetId:w,cacheKey:E})}),s&&(0,m.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,m.jsx)(`div`,{className:`connect-page`,children:(0,m.jsxs)(`div`,{className:`connect-content`,children:[(0,m.jsxs)(`div`,{className:`connect-logos`,children:[(0,m.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,m.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,m.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,m.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,m.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,m.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,m.jsx)(`span`,{className:`connect-logo-label`,children:i.productName})]})]}),(0,m.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,i.productName]}),(0,m.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,m.jsx)(l,{variant:`primary`,onClick:M,disabled:a,children:a?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,m.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,m.jsx)(`button`,{onClick:j,disabled:g,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:g?`Launching…`:`Open browser first`}),s&&(0,m.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function y({auth:e}){return e.appState===`loading`?(0,m.jsx)(o,{surface:`gate`}):e.appState===`set-pin`?(0,m.jsx)(g,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,m.jsx)(v,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,m.jsx)(_,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):null}export{p as n,y as t};
1
+ import{o as e}from"./chunk-CltuBf4Z.js";import{B as t,H as n,J as r,R as i,W as a,g as o}from"./useSubAccountSwitcher-B6Ns2Z43.js";import{k as s}from"./useVoiceRecorder-CbVwXEjY.js";import{D as c,E as l,O as u}from"./AdminShell-BQy9Ob22.js";import{t as d}from"./CdpScreencastSurface-BrDZji8F.js";var f=e(r(),1);function p(e=`admin`){let[t,n]=(0,f.useState)(`loading`),[r,i]=(0,f.useState)(``),[o,c]=(0,f.useState)(``),[l,d]=(0,f.useState)(``),[p,m]=(0,f.useState)(!1),[h,g]=(0,f.useState)(!1),[_,v]=(0,f.useState)(!1),[y,b]=(0,f.useState)(!1),[x,S]=(0,f.useState)(!1),[C,w]=(0,f.useState)(null),[T,E]=(0,f.useState)(null),[D,O]=(0,f.useState)(void 0),[k,A]=(0,f.useState)(null),[j,M]=(0,f.useState)(void 0),[N,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(void 0),z=(0,f.useRef)(void 0),[B,V]=(0,f.useState)(!1),[H,U]=(0,f.useState)(!0);(0,f.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&V(!0)}).catch(()=>{})},[]);let W=(0,f.useRef)(null),G=(0,f.useRef)(null);(0,f.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let r=await t.json();w(r.session_key),I(r.sessionId??null),O(r.businessName),A(r.role??null),M(r.userName===void 0?null:r.userName),P(r.avatar??null);let i=s(r.thinkingView);return z.current=i,R(i),n(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(r=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check returned ${i.status} after retries`),n(`set-pin`);return}let a=await i.json();if(!a.pin_configured){n(`set-pin`);return}U(!!a.claude_authenticated);let o=!1;try{o=new URLSearchParams(window.location.search).get(`connect`)===`claude`}catch{}if(o){try{let e=new URL(window.location.href);e.searchParams.delete(`connect`),window.history.replaceState(null,``,e.pathname+e.search+e.hash)}catch{}if(!a.claude_authenticated){n(`connect-claude`);return}}if(await e())return;n(`enter-pin`)}catch(e){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check failed:`,e),n(`set-pin`)}}t()},[]),(0,f.useEffect)(()=>{t===`chat`&&C&&fetch(`/api/admin/claude-info?session_key=${encodeURIComponent(C)}`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&E(e)}).catch(()=>{})},[t,C]);let K=(0,f.useRef)(null);(0,f.useEffect)(()=>{if(t!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();U(t.auth_status!==`dead`&&t.auth_status!==`missing`)}}catch{}if(C)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(C)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(t===`remote-auth-required`){a(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),K.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[t,C]),(0,f.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(U(!0),n(`enter-pin`))}).catch(()=>{})},[t]);async function q(e,t){g(!0);try{let r=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...t?{accountId:t}:{}})});if(!r.ok){let e=await r.json().catch(()=>({}));if(r.status===401&&e?.code===`remote-auth-required`){a(`enter-pin`,`/api/admin/session`);return}d(e.error||`Invalid PIN`);return}let o=await r.json();w(o.session_key),I(o.sessionId??null),O(o.businessName),A(o.role??null),M(o.userName===void 0?null:o.userName),P(o.avatar??null);let c=s(o.thinkingView);z.current=c,R(c);try{sessionStorage.setItem(`maxy-admin-session-key`,o.session_key)}catch{}i(``),n(`chat`)}catch(e){console.error(`[admin] connection error:`,e),d(`Could not connect.`)}finally{g(!1)}}let J=(0,f.useCallback)(async e=>{if(e.preventDefault(),h)return;d(``);let t=o.trim();if(!t){d(`Please enter your name.`);return}if(r.length<4){d(`PIN must be at least 4 characters.`);return}let s=r;g(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:s,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===401&&t?.code===`remote-auth-required`){a(`set-pin`,`/api/onboarding/set-pin`);return}if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let r=await e.json();r.pin_configured&&r.claude_authenticated?n(`enter-pin`):r.pin_configured?n(`connect-claude`):d(t.error||`Failed to set PIN.`)}else n(`enter-pin`)}catch{n(`enter-pin`)}return}d(t.error||`Failed to set PIN.`);return}let r=await fetch(`/api/health`);if((r.ok?await r.json():null)?.claude_authenticated){await q(s);return}i(``),n(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),d(`Could not connect.`)}finally{g(!1)}},[r,h,o]),Y=(0,f.useCallback)(async e=>{e.preventDefault(),d(``),await q(r)},[r]),X=(0,f.useCallback)(async()=>{S(!0);try{if(!await u())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;U(!1),w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return n(`connect-claude`),!0}finally{S(!1)}},[]),Z=(0,f.useCallback)(()=>{w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}i(``),d(``),n(`enter-pin`)},[]);return(0,f.useEffect)(()=>{K.current=Z},[Z]),{appState:t,setAppState:n,pin:r,setPin:i,operatorName:o,setOperatorName:c,pinError:l,setPinError:d,showPin:p,setShowPin:m,pinLoading:h,authPolling:_,setAuthPolling:v,authLoading:y,setAuthLoading:b,disconnecting:x,cacheKey:C,setCacheKey:w,claudeInfo:T,setClaudeInfo:E,businessName:D,role:k,userName:j,userAvatar:N,sessionId:F,setSessionId:I,expandAll:L,setExpandAll:R,expandAllDefaultRef:z,remoteAuthEnabled:B,claudeConnected:H,pinInputRef:W,setPinFormRef:G,handleSetPin:J,handleLogin:Y,handleDisconnect:X,handleLogout:Z}}var m=n();function h({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,f.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,m.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,m.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function g(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:g,setOperatorName:_}=e;return(0,m.jsx)(`div`,{className:`connect-page`,children:(0,m.jsxs)(`div`,{className:`connect-content`,children:[(0,m.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,m.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,i.productName]}),(0,m.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,i.productName,` who you are, then choose a PIN.`]}),(0,m.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,m.jsxs)(`div`,{className:`pin-input-row`,children:[(0,m.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:g,onChange:e=>_(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,m.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,m.jsxs)(`div`,{className:`pin-input-row`,children:[(0,m.jsx)(h,{inputRef:d,value:n,onChange:r,onComplete:()=>{},showPin:a}),(0,m.jsx)(l,{variant:`send`,type:`submit`,disabled:!n||!g.trim(),loading:s,"aria-label":`Set PIN`,children:(0,m.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,m.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,m.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,m.jsx)(c,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,m.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function _(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:u,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:g}=e;return(0,m.jsxs)(`div`,{className:`connect-page`,children:[p&&g&&(0,m.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:g,children:`Sign out`}),(0,m.jsxs)(`div`,{className:`connect-content`,children:[(0,m.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,m.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,m.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,m.jsxs)(`div`,{className:`pin-input-row`,children:[(0,m.jsx)(h,{inputRef:d,value:n,onChange:r,onComplete:()=>{},showPin:a,autoFocus:!0}),(0,m.jsx)(l,{variant:`send`,type:`submit`,disabled:!n,loading:s,children:(0,m.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,m.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,m.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,m.jsx)(`div`,{className:`pin-options`,children:(0,m.jsx)(c,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})})]}),u&&(0,m.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function v(e){let{authPolling:n,setAuthPolling:r,authLoading:a,setAuthLoading:o,pinError:s,setPinError:c,setAppState:u}=e,[p,h]=(0,f.useState)(!1),[g,_]=(0,f.useState)(!1),[v,y]=(0,f.useState)(``),[b,x]=(0,f.useState)(``),[S,C]=(0,f.useState)(``),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(null),[O,k]=(0,f.useState)(!1);(0,f.useEffect)(()=>{try{D(sessionStorage.getItem(`maxy-admin-session-key`))}catch{}k(!0)},[]);async function A(){C(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`paste-code`,code:b})})).json();e.accepted?(C(`Code submitted. Finishing sign-in…`),x(``)):C(e.error||`Could not submit code.`)}catch(e){console.error(`[admin] paste-code error:`,e),C(`Could not submit code.`)}}async function j(){_(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?h(!0):e.error&&c(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),c(`Could not launch browser.`)}_(!1)}async function M(){o(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){r(!0),h(!0),o(!1),y(e.transport||``);for(let e=0;e<120;e++){await new Promise(e=>setTimeout(e,2e3));let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json();if(typeof e.authTargetId==`string`&&T(e.authTargetId),e.authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}}c(`Timed out waiting for sign-in. Try again.`),r(!1)}else e.error&&c(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),c(`Could not start auth flow.`)}o(!1)}async function N(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),r(!1),c(``)}return n||p?(0,m.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,m.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[n?(0,m.jsx)(`button`,{onClick:N,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,m.jsx)(`button`,{onClick:()=>h(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,m.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,m.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,m.jsx)(`p`,{className:`chat-intro`,children:n?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!n&&(0,m.jsx)(`div`,{style:{marginTop:`12px`},children:(0,m.jsx)(l,{variant:`primary`,onClick:M,disabled:a,children:a?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),n&&v===`native`&&(0,m.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,m.jsx)(`label`,{style:{fontSize:`12px`,color:`#999`,lineHeight:1.4},children:`If the browser didn't finish sign-in, paste the code or full redirect URL from Claude's page:`}),(0,m.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,m.jsx)(`input`,{type:`text`,value:b,onChange:e=>x(e.target.value),placeholder:`Paste code or redirect URL`,style:{flex:1,padding:`8px 10px`,fontSize:`13px`,border:`1px solid #ccc`,borderRadius:`6px`}}),(0,m.jsx)(l,{variant:`primary`,onClick:A,disabled:!b.trim(),children:`Submit`})]}),S&&(0,m.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:S})]})]}),(0,m.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:O&&(0,m.jsx)(d,{preferTargetId:w,cacheKey:E})}),s&&(0,m.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,m.jsx)(`div`,{className:`connect-page`,children:(0,m.jsxs)(`div`,{className:`connect-content`,children:[(0,m.jsxs)(`div`,{className:`connect-logos`,children:[(0,m.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,m.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,m.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,m.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,m.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,m.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,m.jsx)(`span`,{className:`connect-logo-label`,children:i.productName})]})]}),(0,m.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,i.productName]}),(0,m.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,m.jsx)(l,{variant:`primary`,onClick:M,disabled:a,children:a?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,m.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,m.jsx)(`button`,{onClick:j,disabled:g,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:g?`Launching…`:`Open browser first`}),s&&(0,m.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function y({auth:e}){return e.appState===`loading`?(0,m.jsx)(o,{surface:`gate`}):e.appState===`set-pin`?(0,m.jsx)(g,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,m.jsx)(v,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,m.jsx)(_,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):null}export{p as n,y as t};