@rubytech/create-maxy-code 0.1.306 → 0.1.308

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 (207) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/admin-access-password/__tests__/index.test.ts +114 -0
  3. package/payload/platform/lib/admin-access-password/dist/index.d.ts +40 -0
  4. package/payload/platform/lib/admin-access-password/dist/index.d.ts.map +1 -0
  5. package/payload/platform/lib/admin-access-password/dist/index.js +172 -0
  6. package/payload/platform/lib/admin-access-password/dist/index.js.map +1 -0
  7. package/payload/platform/lib/admin-access-password/src/index.ts +152 -0
  8. package/payload/platform/lib/admin-access-password/tsconfig.json +8 -0
  9. package/payload/platform/lib/models/dist/index.d.ts +6 -1
  10. package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
  11. package/payload/platform/lib/models/dist/index.js +11 -5
  12. package/payload/platform/lib/models/dist/index.js.map +1 -1
  13. package/payload/platform/lib/models/src/index.ts +10 -4
  14. package/payload/platform/package.json +2 -2
  15. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  16. package/payload/platform/plugins/admin/mcp/dist/index.js +60 -19
  17. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  18. package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +8 -2
  19. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +35 -14
  20. package/payload/platform/plugins/docs/references/admin-ui.md +33 -12
  21. package/payload/platform/plugins/docs/references/internals.md +1 -1
  22. package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
  23. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  24. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  25. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  26. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +3 -0
  27. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  28. package/payload/platform/services/claude-session-manager/dist/http-server.js +196 -1
  29. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  30. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +12 -0
  31. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  32. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +60 -1
  33. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts +13 -0
  35. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
  36. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +27 -3
  37. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.d.ts +8 -0
  39. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.d.ts.map +1 -1
  40. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.js +7 -0
  41. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.js.map +1 -1
  42. package/payload/platform/services/webchat-channel/dist/instructions.d.ts +8 -0
  43. package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -0
  44. package/payload/platform/services/webchat-channel/dist/instructions.js +44 -0
  45. package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -0
  46. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
  47. package/payload/platform/services/webchat-channel/dist/server.js +11 -18
  48. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
  49. package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
  50. package/payload/platform/services/whatsapp-channel/dist/server.js +34 -10
  51. package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
  52. package/payload/platform/services/whatsapp-channel/dist/targets.d.ts +9 -0
  53. package/payload/platform/services/whatsapp-channel/dist/targets.d.ts.map +1 -1
  54. package/payload/platform/services/whatsapp-channel/dist/targets.js +13 -0
  55. package/payload/platform/services/whatsapp-channel/dist/targets.js.map +1 -1
  56. package/payload/platform/templates/account.json +1 -1
  57. package/payload/server/{chunk-TUY3RB5G.js → chunk-FBGIHWWM.js} +197 -82
  58. package/payload/server/maxy-edge.js +1 -1
  59. package/payload/server/public/assets/AdminLoginScreens-BZIA9Z6o.js +1 -0
  60. package/payload/server/public/assets/AdminShell-iazLHsk7.js +1 -0
  61. package/payload/server/public/assets/Checkbox-8elc7oXU.js +1 -0
  62. package/payload/server/public/assets/admin-BEx6o3fa.js +1 -0
  63. package/payload/server/public/assets/{arc-BrTRjBIM.js → arc-DxSm8tli.js} +1 -1
  64. package/payload/server/public/assets/architecture-YZFGNWBL-6g9jRVgc.js +1 -0
  65. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DJ9on7sZ.js → architectureDiagram-Q4EWVU46-7JSAh0vL.js} +1 -1
  66. package/payload/server/public/assets/{audio-attachment-mime-j2VvxEtx.js → audio-attachment-mime-DzbKNqbH.js} +4 -4
  67. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CIcyQn0q.js → blockDiagram-DXYQGD6D-DLoVmHKD.js} +1 -1
  68. package/payload/server/public/assets/{jsx-runtime-DZkld3Wk.css → brand-CmMZe4RK.css} +1 -1
  69. package/payload/server/public/assets/brand-Dh5UlVO2.js +9 -0
  70. package/payload/server/public/assets/browser-D16sPVkI.js +1 -0
  71. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Dt5dh_GR.js → c4Diagram-AHTNJAMY-Nv1G0o9P.js} +1 -1
  72. package/payload/server/public/assets/channel-BgQLJanG.js +1 -0
  73. package/payload/server/public/assets/chat-x4PnXhkd.js +1 -0
  74. package/payload/server/public/assets/{chunk-2KRD3SAO-BUq3MqUy.js → chunk-2KRD3SAO-BpqPMhoA.js} +1 -1
  75. package/payload/server/public/assets/{chunk-336JU56O-CUzJH5Qt.js → chunk-336JU56O-DgXHlVU_.js} +2 -2
  76. package/payload/server/public/assets/chunk-426QAEUC-Dr_XVuUq.js +1 -0
  77. package/payload/server/public/assets/{chunk-4BX2VUAB-B4JUc3UA.js → chunk-4BX2VUAB-nwyZSZH8.js} +1 -1
  78. package/payload/server/public/assets/{chunk-4TB4RGXK-HRO9fIIs.js → chunk-4TB4RGXK-Tfxz9LHX.js} +1 -1
  79. package/payload/server/public/assets/{chunk-55IACEB6-MZdrLBuw.js → chunk-55IACEB6-6FMJQGXG.js} +1 -1
  80. package/payload/server/public/assets/{chunk-5FUZZQ4R-XcAN5zlM.js → chunk-5FUZZQ4R-g2FgZF3D.js} +1 -1
  81. package/payload/server/public/assets/{chunk-5PVQY5BW-PQ1GEsxo.js → chunk-5PVQY5BW-DtLwXsPH.js} +1 -1
  82. package/payload/server/public/assets/{chunk-67CJDMHE-BVvCaqGd.js → chunk-67CJDMHE-K91CP5ZU.js} +1 -1
  83. package/payload/server/public/assets/{chunk-7N4EOEYR-BlBbZdpM.js → chunk-7N4EOEYR-BGpCQhqK.js} +1 -1
  84. package/payload/server/public/assets/{chunk-AA7GKIK3-Ct-PgkGa.js → chunk-AA7GKIK3-jkDbInck.js} +1 -1
  85. package/payload/server/public/assets/{chunk-BSJP7CBP-DZRRfCSz.js → chunk-BSJP7CBP-mDosdzGs.js} +1 -1
  86. package/payload/server/public/assets/{chunk-CIAEETIT-BoGEJiXe.js → chunk-CIAEETIT-DhBxewpQ.js} +1 -1
  87. package/payload/server/public/assets/{chunk-EDXVE4YY-DiSmN31f.js → chunk-EDXVE4YY-B7c-9Emg.js} +1 -1
  88. package/payload/server/public/assets/{chunk-ENJZ2VHE-uhhokIvs.js → chunk-ENJZ2VHE-Cqhhncox.js} +1 -1
  89. package/payload/server/public/assets/{chunk-FMBD7UC4-CfCx5WI7.js → chunk-FMBD7UC4-BpDq6wj1.js} +1 -1
  90. package/payload/server/public/assets/{chunk-FOC6F5B3-Dj9E9gTu.js → chunk-FOC6F5B3-Ds02-ktu.js} +1 -1
  91. package/payload/server/public/assets/{chunk-ICPOFSXX-DcBs_FNy.js → chunk-ICPOFSXX-BTX5POFr.js} +2 -2
  92. package/payload/server/public/assets/{chunk-K5T4RW27-7-VefyJD.js → chunk-K5T4RW27-Du1PXXBU.js} +1 -1
  93. package/payload/server/public/assets/{chunk-KGLVRYIC-CqgTEVxm.js → chunk-KGLVRYIC-siasOAf8.js} +1 -1
  94. package/payload/server/public/assets/{chunk-LIHQZDEY-C0gzDXha.js → chunk-LIHQZDEY-xf1rbZtf.js} +1 -1
  95. package/payload/server/public/assets/{chunk-ORNJ4GCN-JXz23R1H.js → chunk-ORNJ4GCN-DeTLQ_LD.js} +1 -1
  96. package/payload/server/public/assets/{chunk-OYMX7WX6-C2snCNq9.js → chunk-OYMX7WX6-DQ7_oVJn.js} +1 -1
  97. package/payload/server/public/assets/chunk-QZHKN3VN-DF4o9HRJ.js +1 -0
  98. package/payload/server/public/assets/{chunk-U2HBQHQK-CXCU7M-M.js → chunk-U2HBQHQK-CXmFUKgn.js} +1 -1
  99. package/payload/server/public/assets/{chunk-X2U36JSP-CEdcSb28.js → chunk-X2U36JSP-Bj8-8Wkz.js} +1 -1
  100. package/payload/server/public/assets/{chunk-XPW4576I-Cckc75YS.js → chunk-XPW4576I-Con3TXqt.js} +1 -1
  101. package/payload/server/public/assets/{chunk-YZCP3GAM-4nN8AO7H.js → chunk-YZCP3GAM-Dx8BHGWf.js} +1 -1
  102. package/payload/server/public/assets/{chunk-ZZ45TVLE-DcoBc8-7.js → chunk-ZZ45TVLE-Dp4Q5Y-f.js} +1 -1
  103. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DAbPKU6u.js +1 -0
  104. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BKuFQLcv.js +1 -0
  105. package/payload/server/public/assets/clone-DnNHGhNe.js +1 -0
  106. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-BFFro_t9.js → cose-bilkent-S5V4N54A-pZiCv69E.js} +1 -1
  107. package/payload/server/public/assets/{dagre-CN5to_JM.js → dagre-CLqhEgbL.js} +1 -1
  108. package/payload/server/public/assets/{dagre-KV5264BT-WYrPwDg0.js → dagre-KV5264BT-BCxE8iyk.js} +1 -1
  109. package/payload/server/public/assets/data-DqG45sq0.js +1 -0
  110. package/payload/server/public/assets/{diagram-5BDNPKRD-Dz2CiboN.js → diagram-5BDNPKRD-slUEdZzz.js} +1 -1
  111. package/payload/server/public/assets/{diagram-G4DWMVQ6-r8h3Ip9O.js → diagram-G4DWMVQ6-DPcraMfu.js} +1 -1
  112. package/payload/server/public/assets/{diagram-MMDJMWI5-CECcpGtr.js → diagram-MMDJMWI5-DR6luhGK.js} +1 -1
  113. package/payload/server/public/assets/{diagram-TYMM5635-CHOcAyIP.js → diagram-TYMM5635-Jap1B4wA.js} +1 -1
  114. package/payload/server/public/assets/{erDiagram-SMLLAGMA-YIqKdPbS.js → erDiagram-SMLLAGMA-DJKUs2hO.js} +1 -1
  115. package/payload/server/public/assets/file-download-BvGS7Qmi.js +1 -0
  116. package/payload/server/public/assets/{flatten-DhYYI_lo.js → flatten-Cl1Bc3dR.js} +1 -1
  117. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-DaEvQWpj.js → flowDiagram-DWJPFMVM-C8W-ZZ9W.js} +1 -1
  118. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-x1hClEOB.js → ganttDiagram-T4ZO3ILL-DYCX4Xu2.js} +1 -1
  119. package/payload/server/public/assets/gitGraph-7Q5UKJZL-g7mvu6IY.js +1 -0
  120. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-C-sZsh6Z.js → gitGraphDiagram-UUTBAWPF-CZu_fpgS.js} +1 -1
  121. package/payload/server/public/assets/{graph-Uaa5heM5.js → graph-DKSjcpmR.js} +3 -3
  122. package/payload/server/public/assets/graph-labels-CVWPQgBV.js +1 -0
  123. package/payload/server/public/assets/{graphlib-CNkAqm2w.js → graphlib-Bdp7TA4y.js} +1 -1
  124. package/payload/server/public/assets/info-OMHHGYJF-DZqJuIkB.js +1 -0
  125. package/payload/server/public/assets/infoDiagram-42DDH7IO-cGfGccHz.js +2 -0
  126. package/payload/server/public/assets/{isEmpty-DGhq_DBP.js → isEmpty-D1pGOD1J.js} +1 -1
  127. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-wHE-RwzZ.js → ishikawaDiagram-UXIWVN3A-B7KfIX6z.js} +1 -1
  128. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DQB6iThz.js → journeyDiagram-VCZTEJTY-CSDwBfhF.js} +1 -1
  129. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Ck08vXSA.js → kanban-definition-6JOO6SKY-CWzcEKTr.js} +1 -1
  130. package/payload/server/public/assets/{line-Cdc2FBEU.js → line-BNQSlbYn.js} +1 -1
  131. package/payload/server/public/assets/{linear-DhtUm5H7.js → linear-BN6kGN93.js} +1 -1
  132. package/payload/server/public/assets/{mermaid-parser.core-CSYulPIL.js → mermaid-parser.core-CcFhkElq.js} +2 -2
  133. package/payload/server/public/assets/{mermaid.core-CP-hOmMh.js → mermaid.core-BsIeJ7Cc.js} +3 -3
  134. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-GxlkvV1Z.js → mindmap-definition-QFDTVHPH-CQVzj6D_.js} +1 -1
  135. package/payload/server/public/assets/operator-Cnzbhdh2.js +1 -0
  136. package/payload/server/public/assets/{ordinal-CibZU3PM.js → ordinal-CBZeH4Yp.js} +1 -1
  137. package/payload/server/public/assets/packet-4T2RLAQJ-Hn8rlHpy.js +1 -0
  138. package/payload/server/public/assets/page-CH8JQkQN.js +1 -0
  139. package/payload/server/public/assets/pie-ZZUOXDRM-BPGWVqBm.js +1 -0
  140. package/payload/server/public/assets/{pieDiagram-DEJITSTG-Di6kWh9c.js → pieDiagram-DEJITSTG-DnrQ9fyn.js} +1 -1
  141. package/payload/server/public/assets/{public-DBXfM02B.js → public-CA90VhI9.js} +3 -3
  142. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-iNHC5bkO.js → quadrantDiagram-34T5L4WZ-BQWlCyWi.js} +1 -1
  143. package/payload/server/public/assets/radar-PYXPWWZC-DMdLrj3E.js +1 -0
  144. package/payload/server/public/assets/{reduce-Da0RBva0.js → reduce-PuPlFPRX.js} +1 -1
  145. package/payload/server/public/assets/{requirementDiagram-MS252O5E-BBlLREXo.js → requirementDiagram-MS252O5E-Du_vZhU1.js} +1 -1
  146. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-qyDkP-Ca.js → sankeyDiagram-XADWPNL6-Cf6Z8GPQ.js} +1 -1
  147. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-C0MJuS0m.js → sequenceDiagram-FGHM5R23-CS8GVol8.js} +1 -1
  148. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-aHTrlosa.js → stateDiagram-FHFEXIEX-Bv1NW2F1.js} +1 -1
  149. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BGUCxPmp.js +1 -0
  150. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BlRZIxEp.js → timeline-definition-GMOUNBTQ-ClGYAsr0.js} +1 -1
  151. package/payload/server/public/assets/treeView-SZITEDCU-CWxofUbI.js +1 -0
  152. package/payload/server/public/assets/treemap-W4RFUUIX-Cfgb_ZG0.js +1 -0
  153. package/payload/server/public/assets/useSelectionMode-FIodJKzS.js +5 -0
  154. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-s76adysx.js → vennDiagram-DHZGUBPP-C2wTcxQT.js} +1 -1
  155. package/payload/server/public/assets/wardley-RL74JXVD-B45olYjj.js +1 -0
  156. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-xC8t2QGW.js → wardleyDiagram-NUSXRM2D-D86-ivEx.js} +1 -1
  157. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DRcHg-Wj.js → xychartDiagram-5P7HB3ND-Ba5WAN8P.js} +1 -1
  158. package/payload/server/public/browser.html +6 -6
  159. package/payload/server/public/chat.html +9 -10
  160. package/payload/server/public/data.html +5 -5
  161. package/payload/server/public/graph.html +8 -8
  162. package/payload/server/public/index.html +9 -10
  163. package/payload/server/public/operator.html +11 -12
  164. package/payload/server/public/public.html +7 -7
  165. package/payload/server/server.js +4235 -3522
  166. package/payload/server/public/assets/AdminLoginScreens-Cw882rmm.js +0 -1
  167. package/payload/server/public/assets/AdminShell-DpWl1uoY.js +0 -1
  168. package/payload/server/public/assets/Checkbox-DAWZItdK.js +0 -1
  169. package/payload/server/public/assets/Transcript-DbK2YA3K.js +0 -1
  170. package/payload/server/public/assets/admin-nQRdn79w.js +0 -1
  171. package/payload/server/public/assets/architecture-YZFGNWBL-DqQB3T6j.js +0 -1
  172. package/payload/server/public/assets/browser-CHWZDCXt.js +0 -1
  173. package/payload/server/public/assets/channel-NZeJdLVK.js +0 -1
  174. package/payload/server/public/assets/chat-BBK6ulFy.js +0 -1
  175. package/payload/server/public/assets/chunk-426QAEUC-DFKX5l0L.js +0 -1
  176. package/payload/server/public/assets/chunk-QZHKN3VN-BWCCN0AM.js +0 -1
  177. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DPlCQCX2.js +0 -1
  178. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CqkQq74h.js +0 -1
  179. package/payload/server/public/assets/clone-CSykdD1A.js +0 -1
  180. package/payload/server/public/assets/data-33mdnHv8.js +0 -1
  181. package/payload/server/public/assets/file-download-P_qlMCg5.js +0 -1
  182. package/payload/server/public/assets/gitGraph-7Q5UKJZL-V7Tx7_eY.js +0 -1
  183. package/payload/server/public/assets/graph-labels-rG63rHvl.js +0 -1
  184. package/payload/server/public/assets/info-OMHHGYJF-D3DqVPGn.js +0 -1
  185. package/payload/server/public/assets/infoDiagram-42DDH7IO-B_O-R0vN.js +0 -2
  186. package/payload/server/public/assets/jsx-runtime-sFVKdwlP.js +0 -9
  187. package/payload/server/public/assets/operator-CiDwt5I9.js +0 -1
  188. package/payload/server/public/assets/packet-4T2RLAQJ-BY7mgCTQ.js +0 -1
  189. package/payload/server/public/assets/page-BvkaS_tu.js +0 -1
  190. package/payload/server/public/assets/pie-ZZUOXDRM-B9f6jN54.js +0 -1
  191. package/payload/server/public/assets/radar-PYXPWWZC-BKS8JOUe.js +0 -1
  192. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-V2vo4BjY.js +0 -1
  193. package/payload/server/public/assets/treeView-SZITEDCU-bIKzyIdw.js +0 -1
  194. package/payload/server/public/assets/treemap-W4RFUUIX-CQycQ4H9.js +0 -1
  195. package/payload/server/public/assets/useSelectionMode-Dky-Stnf.js +0 -5
  196. package/payload/server/public/assets/wardley-RL74JXVD-COr9o-nG.js +0 -1
  197. /package/payload/server/public/assets/{_baseFor-BFYpZGkN.js → _baseFor-brRjpUOX.js} +0 -0
  198. /package/payload/server/public/assets/{array-CYkMkqnU.js → array-BGFCBI0e.js} +0 -0
  199. /package/payload/server/public/assets/{cytoscape.esm-DqlHsaog.js → cytoscape.esm-TvRJ2tGX.js} +0 -0
  200. /package/payload/server/public/assets/{defaultLocale-Beh6XjaL.js → defaultLocale-CRZydyG6.js} +0 -0
  201. /package/payload/server/public/assets/{dist-t9p-NJH2.js → dist-Dbh7HrZX.js} +0 -0
  202. /package/payload/server/public/assets/{init-Rr1s_RiX.js → init-B8gtcn7T.js} +0 -0
  203. /package/payload/server/public/assets/{katex-pVJiI_rc.js → katex-RxgSu_dy.js} +0 -0
  204. /package/payload/server/public/assets/{path-BAQ3hXlG.js → path-DZF-JdEe.js} +0 -0
  205. /package/payload/server/public/assets/{preload-helper-B_l5jfgx.js → preload-helper-CQ36nxok.js} +0 -0
  206. /package/payload/server/public/assets/{rough.esm-nHaDi0Kw.js → rough.esm-6CnTHTkH.js} +0 -0
  207. /package/payload/server/public/assets/{src-DuPQVw-H.js → src-BoaldmnP.js} +0 -0
@@ -2756,23 +2756,9 @@ function websockifyLog(event, fields = {}) {
2756
2756
  console.error(`[websockify] ${formatKv({ event, ...fields })}`);
2757
2757
  }
2758
2758
 
2759
- // app/lib/password-strength.ts
2760
- function validatePasswordStrength(password) {
2761
- return [
2762
- { key: "length", label: "At least 8 characters", met: password.length >= 8 },
2763
- { key: "number", label: "Contains a number", met: /\d/.test(password) },
2764
- { key: "special", label: "Contains a special character", met: /[^A-Za-z0-9]/.test(password) },
2765
- { key: "whitespace", label: "No spaces", met: password.length > 0 && !/\s/.test(password) }
2766
- ];
2767
- }
2768
- function isPasswordValid(password) {
2769
- return validatePasswordStrength(password).every((r) => r.met);
2770
- }
2771
-
2772
- // app/lib/remote-auth.ts
2773
- import { scrypt, randomBytes, timingSafeEqual, createHmac } from "crypto";
2774
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
2775
- import { dirname } from "path";
2759
+ // ../lib/admin-access-password/src/index.ts
2760
+ import { scrypt, randomBytes, timingSafeEqual } from "crypto";
2761
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, renameSync, unlinkSync } from "fs";
2776
2762
  var SCRYPT_N = 16384;
2777
2763
  var SCRYPT_R = 8;
2778
2764
  var SCRYPT_P = 1;
@@ -2785,56 +2771,155 @@ function scryptAsync(password, salt) {
2785
2771
  });
2786
2772
  });
2787
2773
  }
2788
- async function hashPassword(password) {
2774
+ async function hashAccessPassword(password) {
2789
2775
  const salt = randomBytes(32);
2790
2776
  const hash = await scryptAsync(password, salt);
2791
2777
  return `${salt.toString("hex")}:${hash.toString("hex")}`;
2792
2778
  }
2793
- async function verifyPassword(password, stored) {
2794
- const colonIndex = stored.indexOf(":");
2795
- if (colonIndex === -1) return { ok: false, why: "bad-hash-format", hashBytes: 0 };
2796
- const saltHex = stored.slice(0, colonIndex);
2797
- const hashHex = stored.slice(colonIndex + 1);
2798
- if (!saltHex || !hashHex) return { ok: false, why: "bad-hash-format", hashBytes: 0 };
2799
- const salt = Buffer.from(saltHex, "hex");
2800
- const storedHash = Buffer.from(hashHex, "hex");
2801
- if (storedHash.length !== SCRYPT_KEYLEN) {
2802
- return { ok: false, why: "hash-length", hashBytes: storedHash.length };
2803
- }
2779
+ async function matchesHash(password, stored) {
2780
+ const colon = stored.indexOf(":");
2781
+ if (colon === -1) return false;
2782
+ const salt = Buffer.from(stored.slice(0, colon), "hex");
2783
+ const storedHash = Buffer.from(stored.slice(colon + 1), "hex");
2784
+ if (storedHash.length !== SCRYPT_KEYLEN) return false;
2804
2785
  let computed;
2805
2786
  try {
2806
2787
  computed = await scryptAsync(password, salt);
2807
2788
  } catch {
2808
- return { ok: false, why: "scrypt-throw", hashBytes: storedHash.length };
2809
- }
2810
- if (timingSafeEqual(computed, storedHash)) {
2811
- return { ok: true, hashBytes: storedHash.length };
2789
+ return false;
2812
2790
  }
2813
- return { ok: false, why: "password-mismatch", hashBytes: storedHash.length };
2791
+ return timingSafeEqual(computed, storedHash);
2814
2792
  }
2815
- function isRemoteAuthConfigured() {
2816
- if (!existsSync2(REMOTE_PASSWORD_FILE)) return false;
2817
- const content = readFileSync2(REMOTE_PASSWORD_FILE, "utf-8").trim();
2818
- return content.length > 0 && content.includes(":");
2793
+ function readUsers(usersFile) {
2794
+ if (!existsSync2(usersFile)) return [];
2795
+ const raw2 = readFileSync2(usersFile, "utf-8").trim();
2796
+ if (!raw2) return [];
2797
+ const parsed = JSON.parse(raw2);
2798
+ if (!Array.isArray(parsed)) throw new Error("users.json is not an array");
2799
+ return parsed;
2800
+ }
2801
+ function writeUsersAtomic(usersFile, users) {
2802
+ const tmp = `${usersFile}.tmp-${process.pid}`;
2803
+ writeFileSync(tmp, JSON.stringify(users, null, 2) + "\n", { mode: 384 });
2804
+ renameSync(tmp, usersFile);
2819
2805
  }
2820
- function readPasswordHash() {
2806
+ async function setAccessPassword(userId, password, usersFile) {
2807
+ const users = readUsers(usersFile);
2808
+ const idx = users.findIndex((u) => u.userId === userId);
2809
+ if (idx === -1) throw new Error(`no users.json record for userId=${userId}`);
2810
+ users[idx] = { ...users[idx], accessHash: await hashAccessPassword(password) };
2811
+ writeUsersAtomic(usersFile, users);
2812
+ }
2813
+ async function verifyAccessPassword(password, usersFile) {
2814
+ let users;
2821
2815
  try {
2822
- if (!existsSync2(REMOTE_PASSWORD_FILE)) return null;
2823
- const content = readFileSync2(REMOTE_PASSWORD_FILE, "utf-8").trim();
2824
- if (!content || !content.includes(":")) return null;
2825
- return content;
2816
+ users = readUsers(usersFile);
2826
2817
  } catch {
2827
2818
  return null;
2828
2819
  }
2820
+ for (const u of users) {
2821
+ if (typeof u.accessHash === "string" && await matchesHash(password, u.accessHash)) {
2822
+ return u.userId;
2823
+ }
2824
+ }
2825
+ return null;
2826
+ }
2827
+ function anyAccessPasswordConfigured(usersFile) {
2828
+ let users;
2829
+ try {
2830
+ users = readUsers(usersFile);
2831
+ } catch {
2832
+ return false;
2833
+ }
2834
+ return users.some((u) => typeof u.accessHash === "string" && u.accessHash.length > 0);
2835
+ }
2836
+ function accessStoreUnreadable(usersFile) {
2837
+ if (!existsSync2(usersFile)) return false;
2838
+ try {
2839
+ readUsers(usersFile);
2840
+ return false;
2841
+ } catch {
2842
+ return true;
2843
+ }
2844
+ }
2845
+ function migrateLegacyRemotePassword(usersFile, legacyFile, ownerUserId) {
2846
+ if (!existsSync2(legacyFile)) return "noop-no-legacy";
2847
+ const legacy = readFileSync2(legacyFile, "utf-8").trim();
2848
+ const users = readUsers(usersFile);
2849
+ const idx = users.findIndex((u) => u.userId === ownerUserId);
2850
+ if (idx === -1) return "noop-no-owner";
2851
+ const existing = users[idx].accessHash;
2852
+ if (typeof existing === "string" && existing.length > 0) {
2853
+ unlinkSync(legacyFile);
2854
+ return "noop-owner-has-hash";
2855
+ }
2856
+ if (!legacy.includes(":")) {
2857
+ unlinkSync(legacyFile);
2858
+ return "noop-no-legacy";
2859
+ }
2860
+ users[idx] = { ...users[idx], accessHash: legacy };
2861
+ writeUsersAtomic(usersFile, users);
2862
+ unlinkSync(legacyFile);
2863
+ return "migrated";
2864
+ }
2865
+ function readLegacyRemoteHash(legacyFile) {
2866
+ if (!existsSync2(legacyFile)) return null;
2867
+ const raw2 = readFileSync2(legacyFile, "utf-8").trim();
2868
+ return raw2.includes(":") ? raw2 : null;
2869
+ }
2870
+
2871
+ // app/lib/password-strength.ts
2872
+ function validatePasswordStrength(password) {
2873
+ return [
2874
+ { key: "length", label: "At least 8 characters", met: password.length >= 8 },
2875
+ { key: "number", label: "Contains a number", met: /\d/.test(password) },
2876
+ { key: "special", label: "Contains a special character", met: /[^A-Za-z0-9]/.test(password) },
2877
+ { key: "whitespace", label: "No spaces", met: password.length > 0 && !/\s/.test(password) }
2878
+ ];
2879
+ }
2880
+ function isPasswordValid(password) {
2881
+ return validatePasswordStrength(password).every((r) => r.met);
2882
+ }
2883
+
2884
+ // app/lib/remote-auth.ts
2885
+ import { scrypt as scrypt2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2, createHmac } from "crypto";
2886
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
2887
+ import { dirname } from "path";
2888
+ var SCRYPT_N2 = 16384;
2889
+ var SCRYPT_R2 = 8;
2890
+ var SCRYPT_P2 = 1;
2891
+ var SCRYPT_KEYLEN2 = 64;
2892
+ function scryptAsync2(password, salt) {
2893
+ return new Promise((resolve7, reject) => {
2894
+ scrypt2(password, salt, SCRYPT_KEYLEN2, { N: SCRYPT_N2, r: SCRYPT_R2, p: SCRYPT_P2 }, (err, key) => {
2895
+ if (err) reject(err);
2896
+ else resolve7(key);
2897
+ });
2898
+ });
2899
+ }
2900
+ async function hashPassword(password) {
2901
+ const salt = randomBytes2(32);
2902
+ const hash = await scryptAsync2(password, salt);
2903
+ return `${salt.toString("hex")}:${hash.toString("hex")}`;
2904
+ }
2905
+ function isRemoteAuthConfigured() {
2906
+ if (anyAccessPasswordConfigured(USERS_FILE)) return true;
2907
+ if (accessStoreUnreadable(USERS_FILE)) return true;
2908
+ return readLegacyRemoteHash(REMOTE_PASSWORD_FILE) !== null;
2829
2909
  }
2830
2910
  async function setRemotePassword(password) {
2831
2911
  const hash = await hashPassword(password);
2832
- writeFileSync(REMOTE_PASSWORD_FILE, hash, "utf-8");
2912
+ writeFileSync2(REMOTE_PASSWORD_FILE, hash, "utf-8");
2833
2913
  }
2834
2914
  async function verifyRemotePassword(password) {
2835
- const stored = readPasswordHash();
2836
- if (!stored) return { ok: false, why: "no-password-file", hashBytes: 0 };
2837
- return verifyPassword(password, stored);
2915
+ const matchedUserId = await verifyAccessPassword(password, USERS_FILE);
2916
+ if (matchedUserId) return { ok: true, hashBytes: SCRYPT_KEYLEN2, userId: matchedUserId };
2917
+ const legacy = readLegacyRemoteHash(REMOTE_PASSWORD_FILE);
2918
+ if (legacy && await matchesHash(password, legacy)) {
2919
+ return { ok: true, hashBytes: SCRYPT_KEYLEN2, userId: null };
2920
+ }
2921
+ const configured = anyAccessPasswordConfigured(USERS_FILE) || legacy !== null;
2922
+ return { ok: false, why: configured ? "password-mismatch" : "no-password-file", hashBytes: 0 };
2838
2923
  }
2839
2924
  var SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
2840
2925
  var TOKEN_PREFIX = "v1.";
@@ -2844,20 +2929,20 @@ var cachedSecret = null;
2844
2929
  function getSecret() {
2845
2930
  if (cachedSecret) return cachedSecret;
2846
2931
  try {
2847
- const hex2 = readFileSync2(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
2932
+ const hex2 = readFileSync3(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
2848
2933
  if (hex2.length === SECRET_BYTES * 2) {
2849
2934
  cachedSecret = Buffer.from(hex2, "hex");
2850
2935
  return cachedSecret;
2851
2936
  }
2852
2937
  } catch {
2853
2938
  }
2854
- const fresh = randomBytes(SECRET_BYTES).toString("hex");
2939
+ const fresh = randomBytes2(SECRET_BYTES).toString("hex");
2855
2940
  try {
2856
2941
  mkdirSync2(dirname(REMOTE_SESSION_SECRET_FILE), { recursive: true, mode: 448 });
2857
- writeFileSync(REMOTE_SESSION_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
2942
+ writeFileSync2(REMOTE_SESSION_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
2858
2943
  } catch {
2859
2944
  }
2860
- const hex = readFileSync2(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
2945
+ const hex = readFileSync3(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
2861
2946
  cachedSecret = Buffer.from(hex, "hex");
2862
2947
  return cachedSecret;
2863
2948
  }
@@ -2872,7 +2957,7 @@ function signPayload(payloadJson, secret) {
2872
2957
  return base64urlEncode(createHmac("sha256", secret).update(payloadJson).digest());
2873
2958
  }
2874
2959
  function createRemoteSession(opts = {}) {
2875
- const payload = { c: opts.now ?? Date.now(), n: randomBytes(NONCE_BYTES).toString("hex") };
2960
+ const payload = { c: opts.now ?? Date.now(), n: randomBytes2(NONCE_BYTES).toString("hex") };
2876
2961
  const payloadJson = JSON.stringify(payload);
2877
2962
  const payloadB64 = base64urlEncode(Buffer.from(payloadJson, "utf-8"));
2878
2963
  const sig = signPayload(payloadJson, getSecret());
@@ -2895,7 +2980,7 @@ function parseToken(token) {
2895
2980
  const expected = signPayload(payloadJson, getSecret());
2896
2981
  const expectedBuf = Buffer.from(expected, "utf-8");
2897
2982
  const provBuf = Buffer.from(sigB64, "utf-8");
2898
- const signatureValid = expectedBuf.length === provBuf.length && timingSafeEqual(expectedBuf, provBuf);
2983
+ const signatureValid = expectedBuf.length === provBuf.length && timingSafeEqual2(expectedBuf, provBuf);
2899
2984
  let payload;
2900
2985
  try {
2901
2986
  payload = JSON.parse(payloadJson);
@@ -3473,13 +3558,13 @@ function classifyHost(host, operatorDomains2, isPublicHost) {
3473
3558
  import { watchFile } from "fs";
3474
3559
 
3475
3560
  // app/lib/operator-domains.ts
3476
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
3561
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
3477
3562
  import { dirname as dirname2, resolve as resolve3 } from "path";
3478
3563
  var OPERATOR_DOMAINS_PATH = resolve3(MAXY_DIR, "operator-domains.json");
3479
3564
  function loadOperatorDomains() {
3480
3565
  if (!existsSync3(OPERATOR_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
3481
3566
  try {
3482
- const parsed = JSON.parse(readFileSync3(OPERATOR_DOMAINS_PATH, "utf-8"));
3567
+ const parsed = JSON.parse(readFileSync4(OPERATOR_DOMAINS_PATH, "utf-8"));
3483
3568
  if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
3484
3569
  return new Set(parsed.filter((h) => typeof h === "string"));
3485
3570
  } catch {
@@ -3506,11 +3591,11 @@ function getOperatorDomains() {
3506
3591
 
3507
3592
  // app/lib/claude-agent/account.ts
3508
3593
  import { resolve as resolve4 } from "path";
3509
- import { readFileSync as readFileSync5, readdirSync, existsSync as existsSync5, statSync } from "fs";
3594
+ import { readFileSync as readFileSync6, readdirSync, existsSync as existsSync5, statSync } from "fs";
3510
3595
 
3511
3596
  // ../lib/brand-templating/src/index.ts
3512
3597
  import { join as join2 } from "path";
3513
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
3598
+ import { existsSync as existsSync4, readFileSync as readFileSync5 } from "fs";
3514
3599
  var PLACEHOLDER = "{{productName}}";
3515
3600
  var cachedProductName = null;
3516
3601
  function brandJsonPath() {
@@ -3530,7 +3615,7 @@ function getBrandProductName() {
3530
3615
  }
3531
3616
  let parsed;
3532
3617
  try {
3533
- parsed = JSON.parse(readFileSync4(path, "utf-8"));
3618
+ parsed = JSON.parse(readFileSync5(path, "utf-8"));
3534
3619
  } catch (err) {
3535
3620
  throw new Error(
3536
3621
  `[skill-loader] brand.json unreadable at ${path}: ${err instanceof Error ? err.message : String(err)}`
@@ -3594,7 +3679,7 @@ function listValidAccounts() {
3594
3679
  }
3595
3680
  let config;
3596
3681
  try {
3597
- config = JSON.parse(readFileSync5(configPath, "utf-8"));
3682
+ config = JSON.parse(readFileSync6(configPath, "utf-8"));
3598
3683
  } catch {
3599
3684
  console.error(
3600
3685
  `[platform] accounts-state CORRUPT-JSON id=${entry.name} \u2014 account.json failed to parse; treating as stub`
@@ -3610,7 +3695,7 @@ function resolveAccount() {
3610
3695
  let usersJsonUserId = null;
3611
3696
  if (existsSync5(USERS_FILE)) {
3612
3697
  try {
3613
- const raw2 = readFileSync5(USERS_FILE, "utf-8").trim();
3698
+ const raw2 = readFileSync6(USERS_FILE, "utf-8").trim();
3614
3699
  if (raw2) {
3615
3700
  const users = JSON.parse(raw2);
3616
3701
  if (users.length > 0) {
@@ -3626,7 +3711,7 @@ function resolveAccount() {
3626
3711
  if (!entry.isDirectory()) continue;
3627
3712
  const configPath = resolve4(ACCOUNTS_DIR, entry.name, "account.json");
3628
3713
  if (!existsSync5(configPath)) continue;
3629
- const raw2 = readFileSync5(configPath, "utf-8");
3714
+ const raw2 = readFileSync6(configPath, "utf-8");
3630
3715
  let config;
3631
3716
  try {
3632
3717
  config = JSON.parse(raw2);
@@ -3661,7 +3746,7 @@ function resolveAccount() {
3661
3746
  function readAgentFile(accountDir, agentName, filename) {
3662
3747
  const filePath = resolve4(accountDir, "agents", agentName, filename);
3663
3748
  if (!existsSync5(filePath)) return null;
3664
- const raw2 = readFileSync5(filePath, "utf-8");
3749
+ const raw2 = readFileSync6(filePath, "utf-8");
3665
3750
  if (filename.endsWith(".md")) {
3666
3751
  return substituteBrandPlaceholders(raw2, filePath);
3667
3752
  }
@@ -3690,7 +3775,7 @@ function resolveDefaultAgentSlug(accountDir) {
3690
3775
  }
3691
3776
  let config;
3692
3777
  try {
3693
- config = JSON.parse(readFileSync5(configPath, "utf-8"));
3778
+ config = JSON.parse(readFileSync6(configPath, "utf-8"));
3694
3779
  } catch (err) {
3695
3780
  console.error("[agent-resolve] failed to read account.json:", err);
3696
3781
  return null;
@@ -3765,14 +3850,14 @@ function resolveAgentConfig(accountDir, agentName) {
3765
3850
  const knowledgeMtime = statSync(knowledgePath).mtimeMs;
3766
3851
  const summaryMtime = statSync(summaryPath).mtimeMs;
3767
3852
  if (summaryMtime >= knowledgeMtime) {
3768
- knowledge = readFileSync5(summaryPath, "utf-8");
3853
+ knowledge = readFileSync6(summaryPath, "utf-8");
3769
3854
  } else {
3770
3855
  console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
3771
- knowledge = readFileSync5(knowledgePath, "utf-8");
3856
+ knowledge = readFileSync6(knowledgePath, "utf-8");
3772
3857
  }
3773
3858
  knowledgeBaked = true;
3774
3859
  } else if (hasKnowledge) {
3775
- knowledge = readFileSync5(knowledgePath, "utf-8");
3860
+ knowledge = readFileSync6(knowledgePath, "utf-8");
3776
3861
  knowledgeBaked = true;
3777
3862
  }
3778
3863
  let budget = null;
@@ -3808,7 +3893,7 @@ function resolveUserAccounts(userId) {
3808
3893
  if (!existsSync5(configPath)) continue;
3809
3894
  let config;
3810
3895
  try {
3811
- config = JSON.parse(readFileSync5(configPath, "utf-8"));
3896
+ config = JSON.parse(readFileSync6(configPath, "utf-8"));
3812
3897
  } catch {
3813
3898
  console.error(`[session] account.json corrupt at ${configPath} \u2014 skipping`);
3814
3899
  continue;
@@ -3893,8 +3978,8 @@ function getSessionKeyBySessionId(_sessionId) {
3893
3978
  // app/lib/claude-agent/plugin-manifest.ts
3894
3979
  import { resolve as resolve5, join as join3 } from "path";
3895
3980
  import {
3896
- readFileSync as readFileSync6,
3897
- writeFileSync as writeFileSync3,
3981
+ readFileSync as readFileSync7,
3982
+ writeFileSync as writeFileSync4,
3898
3983
  readdirSync as readdirSync2,
3899
3984
  existsSync as existsSync6,
3900
3985
  statSync as statSync2,
@@ -3915,7 +4000,7 @@ function readBundleSubPlugins(bundlePath) {
3915
4000
  if (!existsSync6(bundlePath)) return [];
3916
4001
  let raw2;
3917
4002
  try {
3918
- raw2 = readFileSync6(bundlePath, "utf-8");
4003
+ raw2 = readFileSync7(bundlePath, "utf-8");
3919
4004
  } catch {
3920
4005
  return [];
3921
4006
  }
@@ -3988,8 +4073,8 @@ function reapDuplicateFlatPremiumSubs(bundles, stagingRoot, pluginsDir) {
3988
4073
  const flatDir = resolve5(pluginsDir, sub);
3989
4074
  const flatManifest = resolve5(flatDir, "PLUGIN.md");
3990
4075
  if (!existsSync6(premiumManifest) || !existsSync6(flatManifest)) continue;
3991
- const premiumSha = createHash2("sha256").update(readFileSync6(premiumManifest)).digest("hex");
3992
- const flatSha = createHash2("sha256").update(readFileSync6(flatManifest)).digest("hex");
4076
+ const premiumSha = createHash2("sha256").update(readFileSync7(premiumManifest)).digest("hex");
4077
+ const flatSha = createHash2("sha256").update(readFileSync7(flatManifest)).digest("hex");
3993
4078
  if (isBundle) {
3994
4079
  if (premiumSha === flatSha) {
3995
4080
  try {
@@ -4051,10 +4136,10 @@ function reconcileEnabledPlugins(accountDir, config, accountId) {
4051
4136
  const merged = [...currentSet];
4052
4137
  const configPath = resolve5(accountDir, "account.json");
4053
4138
  try {
4054
- const raw2 = readFileSync6(configPath, "utf-8");
4139
+ const raw2 = readFileSync7(configPath, "utf-8");
4055
4140
  const parsed = JSON.parse(raw2);
4056
4141
  parsed.enabledPlugins = merged;
4057
- writeFileSync3(configPath, JSON.stringify(parsed, null, 2) + "\n");
4142
+ writeFileSync4(configPath, JSON.stringify(parsed, null, 2) + "\n");
4058
4143
  config.enabledPlugins = merged;
4059
4144
  } catch (err) {
4060
4145
  console.error(`${TAG} enabled-stamp write failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -4082,10 +4167,10 @@ function cleanupLeakedPremiumSubs(accountDir, config, accountId) {
4082
4167
  if (removed.length === 0) return;
4083
4168
  const configPath = resolve5(accountDir, "account.json");
4084
4169
  try {
4085
- const raw2 = readFileSync6(configPath, "utf-8");
4170
+ const raw2 = readFileSync7(configPath, "utf-8");
4086
4171
  const parsed = JSON.parse(raw2);
4087
4172
  parsed.enabledPlugins = kept;
4088
- writeFileSync3(configPath, JSON.stringify(parsed, null, 2) + "\n");
4173
+ writeFileSync4(configPath, JSON.stringify(parsed, null, 2) + "\n");
4089
4174
  config.enabledPlugins = kept;
4090
4175
  console.log(`${TAG} cleanup accountId=${accountId ?? "unknown"} removed=[${removed.join(",")}]`);
4091
4176
  } catch (err) {
@@ -4133,7 +4218,7 @@ function requirePortEnv(envName, options = {}) {
4133
4218
  // app/lib/neo4j-store.ts
4134
4219
  import neo4j from "neo4j-driver";
4135
4220
  import { randomUUID } from "crypto";
4136
- import { readFileSync as readFileSync7, readdirSync as readdirSync3, existsSync as existsSync7, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
4221
+ import { readFileSync as readFileSync8, readdirSync as readdirSync3, existsSync as existsSync7, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
4137
4222
  import { resolve as resolve6 } from "path";
4138
4223
  var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
4139
4224
  var driver = null;
@@ -4141,7 +4226,7 @@ function readPassword() {
4141
4226
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
4142
4227
  const passwordFile = resolve6(PLATFORM_ROOT3, "config/.neo4j-password");
4143
4228
  try {
4144
- return readFileSync7(passwordFile, "utf-8").trim();
4229
+ return readFileSync8(passwordFile, "utf-8").trim();
4145
4230
  } catch {
4146
4231
  throw new Error(
4147
4232
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -4963,6 +5048,32 @@ async function loadAdminUserName(accountId, userId) {
4963
5048
  await session.close();
4964
5049
  }
4965
5050
  }
5051
+ async function loadPersonNameByElementId(accountId, personId) {
5052
+ const session = getSession();
5053
+ try {
5054
+ const result = await session.run(
5055
+ `MATCH (p:Person {accountId: $accountId})
5056
+ WHERE elementId(p) = $personId
5057
+ RETURN p.givenName AS givenName, p.familyName AS familyName
5058
+ LIMIT 1`,
5059
+ { accountId, personId },
5060
+ { timeout: 2e3 }
5061
+ );
5062
+ if (result.records.length === 0) return null;
5063
+ const given = result.records[0].get("givenName");
5064
+ const family = result.records[0].get("familyName");
5065
+ if (!given || given.trim().length === 0) return null;
5066
+ const fam = family && family.trim().length > 0 ? family.trim() : null;
5067
+ return fam ? `${given.trim()} ${fam}` : given.trim();
5068
+ } catch (err) {
5069
+ console.error(
5070
+ `[admin-sessions-list] loadPersonNameByElementId failed: ${err instanceof Error ? err.message : String(err)}`
5071
+ );
5072
+ return null;
5073
+ } finally {
5074
+ await session.close();
5075
+ }
5076
+ }
4966
5077
  async function loadWhatsappSenderName(accountId, senderTelephone) {
4967
5078
  const session = getSession();
4968
5079
  try {
@@ -5164,7 +5275,7 @@ function loadEnabledPluginProfileKeys(accountId) {
5164
5275
  if (!existsSync7(accountFile)) return {};
5165
5276
  let enabled;
5166
5277
  try {
5167
- const raw2 = readFileSync7(accountFile, "utf-8");
5278
+ const raw2 = readFileSync8(accountFile, "utf-8");
5168
5279
  const parsed = JSON.parse(raw2);
5169
5280
  enabled = Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : [];
5170
5281
  } catch (err) {
@@ -5179,7 +5290,7 @@ function loadEnabledPluginProfileKeys(accountId) {
5179
5290
  if (!existsSync7(manifestPath)) continue;
5180
5291
  let manifest;
5181
5292
  try {
5182
- manifest = readFileSync7(manifestPath, "utf-8");
5293
+ manifest = readFileSync8(manifestPath, "utf-8");
5183
5294
  } catch {
5184
5295
  continue;
5185
5296
  }
@@ -5435,11 +5546,11 @@ async function projectAgent(accountId, accountDir, slug) {
5435
5546
  );
5436
5547
  return;
5437
5548
  }
5438
- config = JSON.parse(readFileSync7(configPath, "utf-8"));
5549
+ config = JSON.parse(readFileSync8(configPath, "utf-8"));
5439
5550
  for (const { filename, role } of AGENT_FILE_ROLES) {
5440
5551
  const filePath = resolve6(agentDir, filename);
5441
5552
  if (!existsSync7(filePath)) continue;
5442
- const body = readFileSync7(filePath, "utf-8");
5553
+ const body = readFileSync8(filePath, "utf-8");
5443
5554
  presentRoles.push({ role, body, edge: ROLE_TO_EDGE[role] });
5444
5555
  }
5445
5556
  } catch (err) {
@@ -5700,6 +5811,7 @@ export {
5700
5811
  LID_MAP_FILE,
5701
5812
  LOG_DIR,
5702
5813
  BIN_DIR,
5814
+ REMOTE_PASSWORD_FILE,
5703
5815
  INSTALL_OWNER_FILE,
5704
5816
  VISITOR_TOKEN_SECRET_FILE,
5705
5817
  CLAUDE_CREDENTIALS_FILE,
@@ -5708,6 +5820,8 @@ export {
5708
5820
  sanitizeClientCorrId,
5709
5821
  httpLog,
5710
5822
  websockifyLog,
5823
+ setAccessPassword,
5824
+ migrateLegacyRemotePassword,
5711
5825
  validatePasswordStrength,
5712
5826
  isPasswordValid,
5713
5827
  isRemoteAuthConfigured,
@@ -5784,6 +5898,7 @@ export {
5784
5898
  renameConversation,
5785
5899
  getUserTimezone,
5786
5900
  loadAdminUserName,
5901
+ loadPersonNameByElementId,
5787
5902
  loadWhatsappSenderName,
5788
5903
  writeAdminUserAndPerson,
5789
5904
  loadUserProfile,
@@ -16,7 +16,7 @@ import {
16
16
  sanitizeClientCorrId,
17
17
  vncLog,
18
18
  websockifyLog
19
- } from "./chunk-TUY3RB5G.js";
19
+ } from "./chunk-FBGIHWWM.js";
20
20
  import "./chunk-PFF6I7KP.js";
21
21
 
22
22
  // server/edge.ts
@@ -0,0 +1 @@
1
+ import{o as e}from"./chunk-Pqm5yXtL.js";import{a as t,o as n,t as r,u as i}from"./brand-Dh5UlVO2.js";import{c as a,p as o}from"./file-download-BvGS7Qmi.js";import{p as s}from"./AdminShell-iazLHsk7.js";import{r as c}from"./useSelectionMode-FIodJKzS.js";import{t as l}from"./Checkbox-8elc7oXU.js";new Set(`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/mpeg,audio/webm,audio/wav,.opus,.ogg,.m4a,.mp3,.wav,.webm`.split(`,`).filter(e=>!e.startsWith(`.`)));function u(e){switch(e){case`expanded`:return!0;case`collapsed`:return!1;default:return}}var d=`admin-landing-redirected`,f=`/graph`;function p(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var m=e(i(),1);function h(e=`admin`){let[t,n]=(0,m.useState)(`loading`),[r,i]=(0,m.useState)(``),[a,c]=(0,m.useState)(``),[l,h]=(0,m.useState)(``),[g,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(!1),[S,C]=(0,m.useState)(!1),[w,T]=(0,m.useState)(!1),[E,D]=(0,m.useState)(null),[O,k]=(0,m.useState)(null),[A,j]=(0,m.useState)(void 0),[M,N]=(0,m.useState)(null),[P,F]=(0,m.useState)(void 0),[I,L]=(0,m.useState)(null),[ee,R]=(0,m.useState)(null),[z,B]=(0,m.useState)([]),[V,H]=(0,m.useState)(!1),[U,W]=(0,m.useState)(void 0),G=(0,m.useRef)(void 0),[K,q]=(0,m.useState)(!1);(0,m.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&q(!0)}).catch(()=>{})},[]);let J=(0,m.useRef)(null),Y=(0,m.useRef)(null);(0,m.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();D(r.session_key),R(r.sessionId??null),j(r.businessName),N(r.role??null),F(r.userName===void 0?null:r.userName),L(r.avatar??null);let i=u(r.thinkingView);return G.current=i,W(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}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,m.useEffect)(()=>{t===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[t]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let n=!1;try{n=sessionStorage.getItem(d)===`1`}catch{}if(p({appState:t,alreadyRedirected:n,variant:e})){try{sessionStorage.setItem(d,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${f}`),window.location.replace(f)}},[t,e]);let X=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(t!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();if(t.auth_status===`dead`||t.auth_status===`missing`){n(`connect-claude`);return}}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(t===`remote-auth-required`){o(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),X.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[t,E]),(0,m.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&n(`enter-pin`)}).catch(()=>{})},[t]);async function Z(e,t){y(!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){h((await r.json().catch(()=>({}))).error||`Invalid PIN`);return}let a=await r.json();if(a.accounts&&!a.session_key){console.log(`[admin] account picker shown: userId=${a.userId} accountCount=${a.accounts.length}`),B(a.accounts),n(`account-picker`);return}D(a.session_key),R(a.sessionId??null),j(a.businessName),N(a.role??null),F(a.userName===void 0?null:a.userName),L(a.avatar??null);let o=u(a.thinkingView);if(G.current=o,W(o),t)try{sessionStorage.setItem(`maxy-account-id`,t)}catch{}try{sessionStorage.setItem(`maxy-admin-session-key`,a.session_key)}catch{}i(``),n(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1),H(!1)}}let Q=(0,m.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let t=a.trim();if(!t){h(`Please enter your name.`);return}if(r.length<4){h(`PIN must be at least 4 characters.`);return}let o=r;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));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`):h(t.error||`Failed to set PIN.`)}else n(`enter-pin`)}catch{n(`enter-pin`)}return}h(t.error||`Failed to set PIN.`);return}let r=await fetch(`/api/health`);if((r.ok?await r.json():null)?.claude_authenticated){await Z(o);return}i(``),n(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[r,v,a]),te=(0,m.useCallback)(async e=>{e.preventDefault(),h(``),await Z(r)},[r]),ne=(0,m.useCallback)(async()=>{T(!0);try{if(!await s())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(d)}catch{}return n(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,m.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(d)}catch{}i(``),h(``),n(`enter-pin`)},[]);return(0,m.useEffect)(()=>{X.current=$},[$]),{appState:t,setAppState:n,pin:r,setPin:i,operatorName:a,setOperatorName:c,pinError:l,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:ee,setSessionId:R,accounts:z,accountPickerLoading:V,expandAll:U,setExpandAll:W,expandAllDefaultRef:G,remoteAuthEnabled:K,pinInputRef:J,setPinFormRef:Y,handleSetPin:Q,handleLogin:te,handleAccountSelect:(0,m.useCallback)(async e=>{H(!0),h(``),await Z(r,e)},[r]),handleDisconnect:ne,handleLogout:$,handleChangePin:(0,m.useCallback)(async()=>{if(!r){h(`Enter your current PIN first.`);return}y(!0),h(``);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify({currentPin:r})});if(!e.ok){h((await e.json().catch(()=>({error:`Incorrect PIN.`}))).error||`Incorrect PIN.`);return}i(``),h(``),n(`set-pin`)}catch(e){console.error(`[admin-auth] change pin failed:`,e),h(e instanceof Error?e.message:String(e))}finally{y(!1)}},[r])}}var g=n();function _({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.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,g.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,g.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 v(e){let{pin:n,setPin:i,showPin:a,setShowPin:o,pinLoading:s,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:t,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,r.productName]}),(0,g.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,r.productName,` who you are, then choose a PIN.`]}),(0,g.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,g.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:n,onChange:i,onComplete:()=>{},showPin:a}),(0,g.jsx)(c,{variant:`send`,type:`submit`,disabled:!n||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(l,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function y(e){let{pin:n,setPin:i,showPin:a,setShowPin:o,pinLoading:s,pinError:u,pinInputRef:d,onSubmit:f,onChangePin:p,remoteAuthEnabled:m,onSignOutRemote:h}=e;return(0,g.jsxs)(`div`,{className:`connect-page`,children:[m&&h&&(0,g.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:h,children:`Sign out`}),(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:t,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:r.productName}),(0,g.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:n,onChange:i,onComplete:()=>{},showPin:a,autoFocus:!0}),(0,g.jsx)(c,{variant:`send`,type:`submit`,disabled:!n,loading:s,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsxs)(`div`,{className:`pin-options`,children:[(0,g.jsx)(l,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`}),(0,g.jsx)(c,{type:`button`,variant:`ghost`,onClick:p,children:`Change PIN`})]})]}),u&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function b(e){let{accounts:n,loading:i,error:o,onSelect:s}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:t,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:r.productName}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Select an account`}),(0,g.jsx)(`div`,{className:`account-picker-list`,children:n.map(e=>(0,g.jsxs)(`button`,{className:`account-picker-card`,onClick:()=>s(e.accountId),disabled:i,type:`button`,children:[(0,g.jsx)(`span`,{className:`account-picker-name`,children:e.businessName||e.accountId}),(0,g.jsx)(`span`,{className:`account-picker-role`,children:e.role}),i&&(0,g.jsx)(a,{className:`account-picker-spinner`,size:16})]},e.accountId))}),o&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:o})]})})}function x(e){let{authPolling:n,setAuthPolling:i,authLoading:a,setAuthLoading:o,pinError:s,setPinError:l,setAppState:u}=e,[d,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1);async function _(){h(!0),l(``);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?f(!0):e.error&&l(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),l(`Could not launch browser.`)}h(!1)}async function v(){o(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){i(!0),f(!0),o(!1);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}l(`Timed out waiting for sign-in. Try again.`),i(!1)}else e.error&&l(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),l(`Could not start auth flow.`)}o(!1)}async function y(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),i(!1),l(``)}return n||d?(0,g.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,g.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,g.jsx)(`button`,{onClick:y,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,g.jsx)(`button`,{onClick:()=>f(!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,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,g.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,g.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,g.jsx)(`div`,{style:{marginTop:`12px`},children:(0,g.jsx)(c,{variant:`primary`,onClick:v,disabled:a,children:a?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})})]}),(0,g.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,g.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsxs)(`div`,{className:`connect-logos`,children:[(0,g.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,g.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,g.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,g.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,g.jsx)(`img`,{src:t,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,g.jsx)(`span`,{className:`connect-logo-label`,children:r.productName})]})]}),(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,r.productName]}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,g.jsx)(c,{variant:`primary`,onClick:v,disabled:a,children:a?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,g.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,g.jsx)(`button`,{onClick:_,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function S({auth:e}){return e.appState===`loading`?(0,g.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,g.jsx)(v,{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,g.jsx)(x,{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,g.jsx)(y,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,onChangePin:e.handleChangePin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):e.appState===`account-picker`?(0,g.jsx)(b,{accounts:e.accounts,loading:e.accountPickerLoading,error:e.pinError,onSelect:e.handleAccountSelect}):null}export{h as n,S as t};