@rubytech/create-maxy-code 0.1.307 → 0.1.309

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 (206) hide show
  1. package/dist/__tests__/claude-ptys-slice.test.js +1 -1
  2. package/dist/__tests__/cloudflared-slice.test.js +1 -1
  3. package/dist/__tests__/macos-darwin-branch.test.js +4 -6
  4. package/package.json +1 -1
  5. package/payload/platform/lib/admin-access-password/__tests__/index.test.ts +142 -0
  6. package/payload/platform/lib/admin-access-password/dist/index.d.ts +49 -0
  7. package/payload/platform/lib/admin-access-password/dist/index.d.ts.map +1 -0
  8. package/payload/platform/lib/admin-access-password/dist/index.js +198 -0
  9. package/payload/platform/lib/admin-access-password/dist/index.js.map +1 -0
  10. package/payload/platform/lib/admin-access-password/src/index.ts +176 -0
  11. package/payload/platform/lib/admin-access-password/tsconfig.json +8 -0
  12. package/payload/platform/lib/models/dist/index.d.ts +13 -0
  13. package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
  14. package/payload/platform/lib/models/dist/index.js +20 -1
  15. package/payload/platform/lib/models/dist/index.js.map +1 -1
  16. package/payload/platform/lib/models/src/index.ts +19 -0
  17. package/payload/platform/package.json +2 -2
  18. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  19. package/payload/platform/plugins/admin/mcp/dist/index.js +63 -19
  20. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  21. package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +8 -2
  22. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +23 -3
  23. package/payload/platform/plugins/docs/references/admin-ui.md +21 -1
  24. package/payload/platform/plugins/docs/references/internals.md +1 -1
  25. package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
  26. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  27. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  28. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  29. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +4 -0
  30. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  31. package/payload/platform/services/claude-session-manager/dist/http-server.js +193 -1
  32. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  33. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +12 -0
  34. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  35. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +52 -1
  36. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  37. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +9 -3
  39. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
  40. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.d.ts +8 -0
  41. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.d.ts.map +1 -1
  42. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.js +7 -0
  43. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.js.map +1 -1
  44. package/payload/platform/services/webchat-channel/dist/instructions.d.ts +8 -0
  45. package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -0
  46. package/payload/platform/services/webchat-channel/dist/instructions.js +44 -0
  47. package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -0
  48. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
  49. package/payload/platform/services/webchat-channel/dist/server.js +11 -18
  50. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
  51. package/payload/server/{chunk-4QFPGAUZ.js → chunk-J6WDAWFJ.js} +190 -82
  52. package/payload/server/maxy-edge.js +1 -1
  53. package/payload/server/public/assets/AccessGate-CU4Qw6M6.js +1 -0
  54. package/payload/server/public/assets/AdminLoginScreens-DUpRIM1h.js +1 -0
  55. package/payload/server/public/assets/AdminShell-DkoQSsqo.js +1 -0
  56. package/payload/server/public/assets/{Checkbox-DoPOlZTV.js → Checkbox-DMA1hVhn.js} +1 -1
  57. package/payload/server/public/assets/OperatorConversations-BIHiyyxU.js +1 -0
  58. package/payload/server/public/assets/admin-BHvOMcCh.js +1 -0
  59. package/payload/server/public/assets/{arc-DxSm8tli.js → arc-Dl9QFDgW.js} +1 -1
  60. package/payload/server/public/assets/architecture-YZFGNWBL-Crq5RSDG.js +1 -0
  61. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-7JSAh0vL.js → architectureDiagram-Q4EWVU46-CNLQUVi9.js} +1 -1
  62. package/payload/server/public/assets/{audio-attachment-mime-BA10IzqQ.js → audio-attachment-mime-DOBET-W1.js} +3 -3
  63. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DLoVmHKD.js → blockDiagram-DXYQGD6D-B-QxfVjk.js} +1 -1
  64. package/payload/server/public/assets/brand-4F9ZXBF8.css +1 -0
  65. package/payload/server/public/assets/{brand-BaRMO3mZ.js → brand-C7kj0USi.js} +1 -1
  66. package/payload/server/public/assets/browser-eLSiC7_b.js +1 -0
  67. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Nv1G0o9P.js → c4Diagram-AHTNJAMY-NuYFvPDU.js} +1 -1
  68. package/payload/server/public/assets/channel-KT66MFN2.js +1 -0
  69. package/payload/server/public/assets/chat-DedpVKUl.js +1 -0
  70. package/payload/server/public/assets/{chunk-2KRD3SAO-BpqPMhoA.js → chunk-2KRD3SAO-l5VL1KQm.js} +1 -1
  71. package/payload/server/public/assets/{chunk-336JU56O-DgXHlVU_.js → chunk-336JU56O-C5gVznC2.js} +2 -2
  72. package/payload/server/public/assets/chunk-426QAEUC-CWMiOm8Y.js +1 -0
  73. package/payload/server/public/assets/{chunk-4BX2VUAB-nwyZSZH8.js → chunk-4BX2VUAB-BtMVz_Sq.js} +1 -1
  74. package/payload/server/public/assets/{chunk-4TB4RGXK-Tfxz9LHX.js → chunk-4TB4RGXK-C8-dmCuT.js} +1 -1
  75. package/payload/server/public/assets/{chunk-55IACEB6-6FMJQGXG.js → chunk-55IACEB6-C5gWvEJW.js} +1 -1
  76. package/payload/server/public/assets/{chunk-5FUZZQ4R-g2FgZF3D.js → chunk-5FUZZQ4R-BZ7VZoAC.js} +1 -1
  77. package/payload/server/public/assets/{chunk-5PVQY5BW-DtLwXsPH.js → chunk-5PVQY5BW-C_ajQOGC.js} +1 -1
  78. package/payload/server/public/assets/{chunk-67CJDMHE-K91CP5ZU.js → chunk-67CJDMHE-BJOR2dwK.js} +1 -1
  79. package/payload/server/public/assets/{chunk-7N4EOEYR-BGpCQhqK.js → chunk-7N4EOEYR-DvZLpquX.js} +1 -1
  80. package/payload/server/public/assets/{chunk-AA7GKIK3-jkDbInck.js → chunk-AA7GKIK3-h5tVsPlW.js} +1 -1
  81. package/payload/server/public/assets/{chunk-BSJP7CBP-mDosdzGs.js → chunk-BSJP7CBP-DLOF2-m3.js} +1 -1
  82. package/payload/server/public/assets/{chunk-CIAEETIT-DhBxewpQ.js → chunk-CIAEETIT-CQRQMPCf.js} +1 -1
  83. package/payload/server/public/assets/{chunk-EDXVE4YY-B7c-9Emg.js → chunk-EDXVE4YY-K9-EfuM2.js} +1 -1
  84. package/payload/server/public/assets/{chunk-ENJZ2VHE-Cqhhncox.js → chunk-ENJZ2VHE-DVoy6NvU.js} +1 -1
  85. package/payload/server/public/assets/{chunk-FMBD7UC4-BpDq6wj1.js → chunk-FMBD7UC4-CQn_2o2b.js} +1 -1
  86. package/payload/server/public/assets/{chunk-FOC6F5B3-Ds02-ktu.js → chunk-FOC6F5B3-CuN73goS.js} +1 -1
  87. package/payload/server/public/assets/{chunk-ICPOFSXX-BTX5POFr.js → chunk-ICPOFSXX-CKhl9J-H.js} +2 -2
  88. package/payload/server/public/assets/{chunk-K5T4RW27-Du1PXXBU.js → chunk-K5T4RW27-CBskuQmq.js} +1 -1
  89. package/payload/server/public/assets/{chunk-KGLVRYIC-siasOAf8.js → chunk-KGLVRYIC-Chtjt8xK.js} +1 -1
  90. package/payload/server/public/assets/{chunk-LIHQZDEY-xf1rbZtf.js → chunk-LIHQZDEY-EOBiBNSH.js} +1 -1
  91. package/payload/server/public/assets/{chunk-ORNJ4GCN-DeTLQ_LD.js → chunk-ORNJ4GCN-uPPq-5MN.js} +1 -1
  92. package/payload/server/public/assets/{chunk-OYMX7WX6-DQ7_oVJn.js → chunk-OYMX7WX6-BRzbxJOT.js} +1 -1
  93. package/payload/server/public/assets/chunk-QZHKN3VN-DCzpF46A.js +1 -0
  94. package/payload/server/public/assets/{chunk-U2HBQHQK-CXmFUKgn.js → chunk-U2HBQHQK-Bndyn5nF.js} +1 -1
  95. package/payload/server/public/assets/{chunk-X2U36JSP-Bj8-8Wkz.js → chunk-X2U36JSP-BspGBHXW.js} +1 -1
  96. package/payload/server/public/assets/{chunk-XPW4576I-Con3TXqt.js → chunk-XPW4576I-HgXQ2k9h.js} +1 -1
  97. package/payload/server/public/assets/{chunk-YZCP3GAM-Dx8BHGWf.js → chunk-YZCP3GAM-C7oTyCnw.js} +1 -1
  98. package/payload/server/public/assets/{chunk-ZZ45TVLE-Dp4Q5Y-f.js → chunk-ZZ45TVLE-CufWa7QL.js} +1 -1
  99. package/payload/server/public/assets/classDiagram-6PBFFD2Q-QOU4HzJJ.js +1 -0
  100. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DcOUai3Z.js +1 -0
  101. package/payload/server/public/assets/clone-CHh05KN-.js +1 -0
  102. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-pZiCv69E.js → cose-bilkent-S5V4N54A-BM3yEbF-.js} +1 -1
  103. package/payload/server/public/assets/{dagre-CLqhEgbL.js → dagre-C7WHNZO8.js} +1 -1
  104. package/payload/server/public/assets/{dagre-KV5264BT-BCxE8iyk.js → dagre-KV5264BT-bcZx3l06.js} +1 -1
  105. package/payload/server/public/assets/data-BcoBY39U.js +1 -0
  106. package/payload/server/public/assets/{diagram-5BDNPKRD-slUEdZzz.js → diagram-5BDNPKRD-B7VotaMF.js} +1 -1
  107. package/payload/server/public/assets/{diagram-G4DWMVQ6-DPcraMfu.js → diagram-G4DWMVQ6-CWWvEsFx.js} +1 -1
  108. package/payload/server/public/assets/{diagram-MMDJMWI5-DR6luhGK.js → diagram-MMDJMWI5-DYHVkTYJ.js} +1 -1
  109. package/payload/server/public/assets/{diagram-TYMM5635-Jap1B4wA.js → diagram-TYMM5635-CHeB6Ama.js} +1 -1
  110. package/payload/server/public/assets/{dist-Dbh7HrZX.js → dist-CjjtmoWL.js} +1 -1
  111. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DJKUs2hO.js → erDiagram-SMLLAGMA-C9gog8QP.js} +1 -1
  112. package/payload/server/public/assets/{flatten-Cl1Bc3dR.js → flatten-QcJDm7yK.js} +1 -1
  113. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-C8W-ZZ9W.js → flowDiagram-DWJPFMVM-B2O9lKTh.js} +1 -1
  114. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DYCX4Xu2.js → ganttDiagram-T4ZO3ILL-DEa4AwbR.js} +1 -1
  115. package/payload/server/public/assets/gitGraph-7Q5UKJZL-BC-u4jgy.js +1 -0
  116. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CZu_fpgS.js → gitGraphDiagram-UUTBAWPF-BjXPQpBL.js} +1 -1
  117. package/payload/server/public/assets/{graph-D29p1FJH.js → graph-C7Hye_vp.js} +2 -2
  118. package/payload/server/public/assets/{graph-labels-DF3QVHkH.js → graph-labels-YYgGsEVd.js} +1 -1
  119. package/payload/server/public/assets/{graphlib-Bdp7TA4y.js → graphlib-CBevn2DP.js} +1 -1
  120. package/payload/server/public/assets/info-OMHHGYJF-DPUetTz-.js +1 -0
  121. package/payload/server/public/assets/infoDiagram-42DDH7IO-q2dl09-M.js +2 -0
  122. package/payload/server/public/assets/{isEmpty-D1pGOD1J.js → isEmpty-BO6BAEn7.js} +1 -1
  123. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B7KfIX6z.js → ishikawaDiagram-UXIWVN3A-CPLfpvqv.js} +1 -1
  124. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CSDwBfhF.js → journeyDiagram-VCZTEJTY-CTHe8MiD.js} +1 -1
  125. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CWzcEKTr.js → kanban-definition-6JOO6SKY-Bm9h1O3Y.js} +1 -1
  126. package/payload/server/public/assets/{line-BNQSlbYn.js → line-C31b0rtY.js} +1 -1
  127. package/payload/server/public/assets/{linear-BN6kGN93.js → linear-Cfm_8_pU.js} +1 -1
  128. package/payload/server/public/assets/{mermaid-parser.core-CcFhkElq.js → mermaid-parser.core-B3tGwOcE.js} +2 -2
  129. package/payload/server/public/assets/{mermaid.core-BsIeJ7Cc.js → mermaid.core-BM3s85ZW.js} +3 -3
  130. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CQVzj6D_.js → mindmap-definition-QFDTVHPH-CaGv_mIB.js} +1 -1
  131. package/payload/server/public/assets/operator-WsXhcbBF.js +1 -0
  132. package/payload/server/public/assets/{ordinal-CBZeH4Yp.js → ordinal-jLCwuvYg.js} +1 -1
  133. package/payload/server/public/assets/packet-4T2RLAQJ-BcfR-ZwA.js +1 -0
  134. package/payload/server/public/assets/page-BhHTnqv4.js +1 -0
  135. package/payload/server/public/assets/pie-ZZUOXDRM-BiKgZdNB.js +1 -0
  136. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DnrQ9fyn.js → pieDiagram-DEJITSTG-BhAXps4u.js} +1 -1
  137. package/payload/server/public/assets/public-ViXjC_dA.js +6 -0
  138. package/payload/server/public/assets/public-next-BKECyMz2.js +1 -0
  139. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BQWlCyWi.js → quadrantDiagram-34T5L4WZ-BWtTdNs8.js} +1 -1
  140. package/payload/server/public/assets/radar-PYXPWWZC-nvCjiW_J.js +1 -0
  141. package/payload/server/public/assets/{reduce-PuPlFPRX.js → reduce-Dmi_NdVH.js} +1 -1
  142. package/payload/server/public/assets/{requirementDiagram-MS252O5E-Du_vZhU1.js → requirementDiagram-MS252O5E-CWU0qCcP.js} +1 -1
  143. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cf6Z8GPQ.js → sankeyDiagram-XADWPNL6-DYvutQld.js} +1 -1
  144. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CS8GVol8.js → sequenceDiagram-FGHM5R23-Cir0hBWS.js} +1 -1
  145. package/payload/server/public/assets/{src-BoaldmnP.js → src-CwB968DO.js} +1 -1
  146. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-Bv1NW2F1.js → stateDiagram-FHFEXIEX-Be-h8YSS.js} +1 -1
  147. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CAnmjSj7.js +1 -0
  148. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-ClGYAsr0.js → timeline-definition-GMOUNBTQ-C3C4Wuyk.js} +1 -1
  149. package/payload/server/public/assets/treeView-SZITEDCU-BinXCVyM.js +1 -0
  150. package/payload/server/public/assets/treemap-W4RFUUIX-CSmh20Ze.js +1 -0
  151. package/payload/server/public/assets/{useSelectionMode-ghXuZicl.js → useSelectionMode-CG_Iel5F.js} +1 -1
  152. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-C2wTcxQT.js → vennDiagram-DHZGUBPP-mDclw0Sa.js} +1 -1
  153. package/payload/server/public/assets/wardley-RL74JXVD-BiCmRKWx.js +1 -0
  154. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-D86-ivEx.js → wardleyDiagram-NUSXRM2D-mvk-YA9g.js} +1 -1
  155. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-Ba5WAN8P.js → xychartDiagram-5P7HB3ND-9M7k1hmD.js} +1 -1
  156. package/payload/server/public/browser.html +8 -8
  157. package/payload/server/public/chat.html +11 -11
  158. package/payload/server/public/data.html +7 -7
  159. package/payload/server/public/graph.html +10 -10
  160. package/payload/server/public/index.html +10 -10
  161. package/payload/server/public/operator.html +13 -13
  162. package/payload/server/public/public-next.html +24 -0
  163. package/payload/server/public/public.html +9 -8
  164. package/payload/server/server.js +4450 -3781
  165. package/dist/__tests__/onboarding-state-readback.test.js +0 -61
  166. package/dist/__tests__/rss-sampler-installer.test.js +0 -27
  167. package/dist/onboarding-readback.js +0 -27
  168. package/payload/server/public/assets/AdminLoginScreens-BsC-EwAn.js +0 -1
  169. package/payload/server/public/assets/AdminShell-CiKKN22G.js +0 -1
  170. package/payload/server/public/assets/admin-DSwmdCKp.js +0 -1
  171. package/payload/server/public/assets/architecture-YZFGNWBL-6g9jRVgc.js +0 -1
  172. package/payload/server/public/assets/brand-C001cin3.css +0 -1
  173. package/payload/server/public/assets/browser-BKR1eJJb.js +0 -1
  174. package/payload/server/public/assets/channel-BgQLJanG.js +0 -1
  175. package/payload/server/public/assets/chat-DZXNRiy-.js +0 -1
  176. package/payload/server/public/assets/chunk-426QAEUC-Dr_XVuUq.js +0 -1
  177. package/payload/server/public/assets/chunk-QZHKN3VN-DF4o9HRJ.js +0 -1
  178. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DAbPKU6u.js +0 -1
  179. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BKuFQLcv.js +0 -1
  180. package/payload/server/public/assets/clone-DnNHGhNe.js +0 -1
  181. package/payload/server/public/assets/data-CuVmW1WN.js +0 -1
  182. package/payload/server/public/assets/file-download-4_hQmMwU.js +0 -1
  183. package/payload/server/public/assets/gitGraph-7Q5UKJZL-g7mvu6IY.js +0 -1
  184. package/payload/server/public/assets/info-OMHHGYJF-DZqJuIkB.js +0 -1
  185. package/payload/server/public/assets/infoDiagram-42DDH7IO-cGfGccHz.js +0 -2
  186. package/payload/server/public/assets/operator-CQRaBNN7.js +0 -1
  187. package/payload/server/public/assets/packet-4T2RLAQJ-Hn8rlHpy.js +0 -1
  188. package/payload/server/public/assets/page-Dz2F3QtB.js +0 -1
  189. package/payload/server/public/assets/pie-ZZUOXDRM-BPGWVqBm.js +0 -1
  190. package/payload/server/public/assets/public-B7BQwWpP.js +0 -6
  191. package/payload/server/public/assets/radar-PYXPWWZC-DMdLrj3E.js +0 -1
  192. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BGUCxPmp.js +0 -1
  193. package/payload/server/public/assets/treeView-SZITEDCU-CWxofUbI.js +0 -1
  194. package/payload/server/public/assets/treemap-W4RFUUIX-Cfgb_ZG0.js +0 -1
  195. package/payload/server/public/assets/wardley-RL74JXVD-B45olYjj.js +0 -1
  196. /package/payload/server/public/assets/{file-download-qc_xy7Az.css → OperatorConversations-qc_xy7Az.css} +0 -0
  197. /package/payload/server/public/assets/{_baseFor-brRjpUOX.js → _baseFor-D8P3gUw3.js} +0 -0
  198. /package/payload/server/public/assets/{array-BGFCBI0e.js → array-CLwNaqU1.js} +0 -0
  199. /package/payload/server/public/assets/{chunk-Pqm5yXtL.js → chunk-CAM3fms7.js} +0 -0
  200. /package/payload/server/public/assets/{cytoscape.esm-TvRJ2tGX.js → cytoscape.esm-mZ4wTuB7.js} +0 -0
  201. /package/payload/server/public/assets/{defaultLocale-CRZydyG6.js → defaultLocale-D_VMtRaY.js} +0 -0
  202. /package/payload/server/public/assets/{init-B8gtcn7T.js → init-vVpfz1D6.js} +0 -0
  203. /package/payload/server/public/assets/{katex-RxgSu_dy.js → katex-DaHGEgm7.js} +0 -0
  204. /package/payload/server/public/assets/{path-DZF-JdEe.js → path-CuyvWNAH.js} +0 -0
  205. /package/payload/server/public/assets/{preload-helper-CQ36nxok.js → preload-helper-TKOBYGYD.js} +0 -0
  206. /package/payload/server/public/assets/{rough.esm-6CnTHTkH.js → rough.esm-JX0wREDd.js} +0 -0
@@ -11,4 +11,17 @@ export declare const MODEL_DISPLAY_NAMES: Record<string, string>;
11
11
  /** The dropdown label for a model id: friendly name when canonical, else the
12
12
  * raw id (never misrepresents an off-map persisted lever). */
13
13
  export declare function modelDisplayName(id: string): string;
14
+ /** The exact selectable model ids (no aliases). Server-side re-seat validation
15
+ * (Task 876) uses this so a body-supplied model can never reach the spawn argv
16
+ * unchecked — a removed model (e.g. claude-fable-5) or a bare alias ('opus')
17
+ * is rejected before the fork. */
18
+ export declare const SELECTABLE_MODELS: readonly string[];
19
+ export declare function isSelectableModel(id: string): boolean;
20
+ /** Strip Claude Code's `[1m]` context-extension suffix so a selectable id
21
+ * (`claude-opus-4-8[1m]`) compares equal to the live API/JSONL `message.model`
22
+ * (suffix stripped upstream → `claude-opus-4-8`). Ids without the suffix pass
23
+ * through. The /chat picker uses this to decide whether a chosen model is a
24
+ * real change from the running one — a raw `selected !== live` compare is
25
+ * always true for `[1m]` models. */
26
+ export declare function baseModelId(id: string): string;
14
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,wBAAwB,CAAC;AAChD,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIvD,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;qEAEqE;AACrE,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAItD,CAAC;AAEF;+DAC+D;AAC/D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,wBAAwB,CAAC;AAChD,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIvD,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;qEAEqE;AACrE,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAItD,CAAC;AAEF;+DAC+D;AAC/D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;mCAGmC;AACnC,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA4C,CAAC;AAC5F,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;qCAKqC;AACrC,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C"}
@@ -3,9 +3,11 @@
3
3
  // Templates, docs, and skills reference these values as strings;
4
4
  // all TypeScript consumers import from here.
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MODEL_DISPLAY_NAMES = exports.MODEL_CONTEXT_WINDOW = exports.HAIKU_MODEL = exports.SONNET_MODEL = exports.OPUS_MODEL = void 0;
6
+ exports.SELECTABLE_MODELS = exports.MODEL_DISPLAY_NAMES = exports.MODEL_CONTEXT_WINDOW = exports.HAIKU_MODEL = exports.SONNET_MODEL = exports.OPUS_MODEL = void 0;
7
7
  exports.contextWindow = contextWindow;
8
8
  exports.modelDisplayName = modelDisplayName;
9
+ exports.isSelectableModel = isSelectableModel;
10
+ exports.baseModelId = baseModelId;
9
11
  // Opus defaults to the 1M-context variant ([1m] is Claude Code's
10
12
  // context-extension suffix, valid in settings.json "model" and agent
11
13
  // frontmatter); Sonnet/Haiku stay on the standard 200k window.
@@ -34,4 +36,21 @@ exports.MODEL_DISPLAY_NAMES = {
34
36
  function modelDisplayName(id) {
35
37
  return exports.MODEL_DISPLAY_NAMES[id] ?? id;
36
38
  }
39
+ /** The exact selectable model ids (no aliases). Server-side re-seat validation
40
+ * (Task 876) uses this so a body-supplied model can never reach the spawn argv
41
+ * unchecked — a removed model (e.g. claude-fable-5) or a bare alias ('opus')
42
+ * is rejected before the fork. */
43
+ exports.SELECTABLE_MODELS = [exports.OPUS_MODEL, exports.SONNET_MODEL, exports.HAIKU_MODEL];
44
+ function isSelectableModel(id) {
45
+ return exports.SELECTABLE_MODELS.includes(id);
46
+ }
47
+ /** Strip Claude Code's `[1m]` context-extension suffix so a selectable id
48
+ * (`claude-opus-4-8[1m]`) compares equal to the live API/JSONL `message.model`
49
+ * (suffix stripped upstream → `claude-opus-4-8`). Ids without the suffix pass
50
+ * through. The /chat picker uses this to decide whether a chosen model is a
51
+ * real change from the running one — a raw `selected !== live` compare is
52
+ * always true for `[1m]` models. */
53
+ function baseModelId(id) {
54
+ return id.replace(/\[1m\]$/, "");
55
+ }
37
56
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,0DAA0D;AAC1D,iEAAiE;AACjE,6CAA6C;;;AAgB7C,sCAEC;AAaD,4CAEC;AA/BD,iEAAiE;AACjE,qEAAqE;AACrE,+DAA+D;AAClD,QAAA,UAAU,GAAG,qBAAqB,CAAC;AACnC,QAAA,YAAY,GAAG,mBAAmB,CAAC;AACnC,QAAA,WAAW,GAAG,kBAAkB,CAAC;AAEjC,QAAA,oBAAoB,GAA2B;IAC1D,CAAC,kBAAU,CAAC,EAAE,SAAS;IACvB,CAAC,oBAAY,CAAC,EAAE,OAAO;IACvB,CAAC,mBAAW,CAAC,EAAE,OAAO;CACvB,CAAC;AAEF,wEAAwE;AACxE,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,4BAAoB,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC;AAChD,CAAC;AAED;;qEAEqE;AACxD,QAAA,mBAAmB,GAA2B;IACzD,CAAC,kBAAU,CAAC,EAAE,uBAAuB;IACrC,CAAC,oBAAY,CAAC,EAAE,YAAY;IAC5B,CAAC,mBAAW,CAAC,EAAE,WAAW;CAC3B,CAAC;AAEF;+DAC+D;AAC/D,SAAgB,gBAAgB,CAAC,EAAU;IACzC,OAAO,2BAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,0DAA0D;AAC1D,iEAAiE;AACjE,6CAA6C;;;AAgB7C,sCAEC;AAaD,4CAEC;AAOD,8CAEC;AAQD,kCAEC;AAlDD,iEAAiE;AACjE,qEAAqE;AACrE,+DAA+D;AAClD,QAAA,UAAU,GAAG,qBAAqB,CAAC;AACnC,QAAA,YAAY,GAAG,mBAAmB,CAAC;AACnC,QAAA,WAAW,GAAG,kBAAkB,CAAC;AAEjC,QAAA,oBAAoB,GAA2B;IAC1D,CAAC,kBAAU,CAAC,EAAE,SAAS;IACvB,CAAC,oBAAY,CAAC,EAAE,OAAO;IACvB,CAAC,mBAAW,CAAC,EAAE,OAAO;CACvB,CAAC;AAEF,wEAAwE;AACxE,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,4BAAoB,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC;AAChD,CAAC;AAED;;qEAEqE;AACxD,QAAA,mBAAmB,GAA2B;IACzD,CAAC,kBAAU,CAAC,EAAE,uBAAuB;IACrC,CAAC,oBAAY,CAAC,EAAE,YAAY;IAC5B,CAAC,mBAAW,CAAC,EAAE,WAAW;CAC3B,CAAC;AAEF;+DAC+D;AAC/D,SAAgB,gBAAgB,CAAC,EAAU;IACzC,OAAO,2BAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;;mCAGmC;AACtB,QAAA,iBAAiB,GAAsB,CAAC,kBAAU,EAAE,oBAAY,EAAE,mBAAW,CAAC,CAAC;AAC5F,SAAgB,iBAAiB,CAAC,EAAU;IAC1C,OAAO,yBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC;AAED;;;;;qCAKqC;AACrC,SAAgB,WAAW,CAAC,EAAU;IACpC,OAAO,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC"}
@@ -34,3 +34,22 @@ export const MODEL_DISPLAY_NAMES: Record<string, string> = {
34
34
  export function modelDisplayName(id: string): string {
35
35
  return MODEL_DISPLAY_NAMES[id] ?? id;
36
36
  }
37
+
38
+ /** The exact selectable model ids (no aliases). Server-side re-seat validation
39
+ * (Task 876) uses this so a body-supplied model can never reach the spawn argv
40
+ * unchecked — a removed model (e.g. claude-fable-5) or a bare alias ('opus')
41
+ * is rejected before the fork. */
42
+ export const SELECTABLE_MODELS: readonly string[] = [OPUS_MODEL, SONNET_MODEL, HAIKU_MODEL];
43
+ export function isSelectableModel(id: string): boolean {
44
+ return SELECTABLE_MODELS.includes(id);
45
+ }
46
+
47
+ /** Strip Claude Code's `[1m]` context-extension suffix so a selectable id
48
+ * (`claude-opus-4-8[1m]`) compares equal to the live API/JSONL `message.model`
49
+ * (suffix stripped upstream → `claude-opus-4-8`). Ids without the suffix pass
50
+ * through. The /chat picker uses this to decide whether a chosen model is a
51
+ * real change from the running one — a raw `selected !== live` compare is
52
+ * always true for `[1m]` models. */
53
+ export function baseModelId(id: string): string {
54
+ return id.replace(/\[1m\]$/, "");
55
+ }
@@ -6,8 +6,8 @@
6
6
  "services/*"
7
7
  ],
8
8
  "scripts": {
9
- "build": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json && tsc -p services/claude-session-manager/tsconfig.json && tsc -p services/whatsapp-channel/tsconfig.json && tsc -p services/webchat-channel/tsconfig.json && NODE_OPTIONS='--max-old-space-size=8192' tsc -b plugins/*/mcp/tsconfig.json",
10
- "build:lib": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json",
9
+ "build": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/admin-access-password/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json && tsc -p services/claude-session-manager/tsconfig.json && tsc -p services/whatsapp-channel/tsconfig.json && tsc -p services/webchat-channel/tsconfig.json && NODE_OPTIONS='--max-old-space-size=8192' tsc -b plugins/*/mcp/tsconfig.json",
10
+ "build:lib": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/admin-access-password/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json",
11
11
  "gen:canonical-tools": "node scripts/generate-canonical-tool-names.mjs",
12
12
  "build:memory": "tsc -p plugins/memory/mcp/tsconfig.json",
13
13
  "build:contacts": "tsc -p plugins/contacts/mcp/tsconfig.json",
@@ -78,6 +78,7 @@ tools:
78
78
  hidden:
79
79
  - remote-auth-status
80
80
  - remote-auth-set-password
81
+ - remote-auth-revoke-password
81
82
  - qr-generate
82
83
  - wifi
83
84
  always: true
@@ -9,6 +9,7 @@ import { resolve, join } from "node:path";
9
9
  import { execFileSync } from "node:child_process";
10
10
  import { appendFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
11
11
  import { writeAdminEntry, removeAdminFromAccount } from "../../../../lib/admins-write/dist/index.js";
12
+ import { setAccessPassword as setAccessPasswordHash, clearAccessPassword as clearAccessPasswordHash, accessPasswordCollides } from "../../../../lib/admin-access-password/dist/index.js";
12
13
  import { embed } from "../../../../lib/embed-client/dist/index.js";
13
14
  import { requirePortEnv } from "../../../../lib/require-port-env/dist/index.js";
14
15
  import { deviceUrlBlock } from "../../../../lib/device-url/dist/index.js";
@@ -181,7 +182,6 @@ async function currentEntitlement() {
181
182
  : undefined,
182
183
  });
183
184
  }
184
- const REMOTE_PASSWORD_FILE = resolve(CONFIG_DIR, ".remote-password");
185
185
  // Resolve account directory
186
186
  function getAccountDir() {
187
187
  if (!ACCOUNT_ID) {
@@ -2034,12 +2034,30 @@ eagerTool(server, "session-resume", "Resume a previous session. Loads the select
2034
2034
  return refuseNoAccount("session-resume");
2035
2035
  return { content: [{ type: "text", text: "resumed" }] };
2036
2036
  });
2037
- server.tool("remote-auth-set-password", "Set the remote access password. Hashes with scrypt and writes to the platform's brand-specific config directory with mode 0600. " +
2038
- "Validates strength (8+ chars, digit, special character, no spaces anywhere). " +
2039
- "Protects the admin interface when exposed over the tunnel has no effect on the public endpoint or the tunnel itself. " +
2040
- "Set before configuring the Cloudflare tunnel the post-restart `curl -I https://<admin-hostname>` verification fails if remote-auth is not configured.", { password: z.string() }, async ({ password }) => {
2037
+ server.tool("remote-auth-set-password", "Set an admin's remote access password the outer password the tunnel asks for before the PIN screen. " +
2038
+ "Each admin has their own; setting one does not affect any other admin's password. " +
2039
+ "Defaults to the calling admin; pass userId (from admin-list) to set another admin's. " +
2040
+ "Hashes with scrypt at mode 0600. Validates strength (8+ chars, digit, special character, no spaces anywhere). " +
2041
+ "Protects the admin interface when exposed over the tunnel — has no effect on the public endpoint or the tunnel itself.", {
2042
+ password: z.string(),
2043
+ userId: z.string().optional().describe("The admin to set the password for. Defaults to the calling admin. Use admin-list to find userIds."),
2044
+ }, async ({ password, userId }) => {
2041
2045
  if (!ACCOUNT_ID)
2042
2046
  return refuseNoAccount("remote-auth-set-password");
2047
+ const targetUserId = userId ?? process.env.USER_ID;
2048
+ if (!targetUserId) {
2049
+ return { content: [{ type: "text", text: "No target admin: pass userId, or run as an identified admin." }], isError: true };
2050
+ }
2051
+ let users;
2052
+ try {
2053
+ users = readUsersJson();
2054
+ }
2055
+ catch (err) {
2056
+ return { content: [{ type: "text", text: `${err instanceof Error ? err.message : String(err)}` }], isError: true };
2057
+ }
2058
+ if (!users.some((u) => u.userId === targetUserId)) {
2059
+ return { content: [{ type: "text", text: `No admin with userId ${targetUserId} on this device.` }], isError: true };
2060
+ }
2043
2061
  // Validate strength — same rules as the web server's validatePasswordStrength
2044
2062
  const checks = [
2045
2063
  { label: "at least 8 characters", met: password.length >= 8 },
@@ -2054,21 +2072,13 @@ server.tool("remote-auth-set-password", "Set the remote access password. Hashes
2054
2072
  isError: true,
2055
2073
  };
2056
2074
  }
2075
+ if (await accessPasswordCollides(password, USERS_FILE, targetUserId)) {
2076
+ return { content: [{ type: "text", text: `That password is already in use by another admin. Choose a different one.` }], isError: true };
2077
+ }
2057
2078
  try {
2058
- const { scrypt, randomBytes } = await import("node:crypto");
2059
- const salt = randomBytes(32);
2060
- const hash = await new Promise((res, rej) => {
2061
- scrypt(password, salt, 64, { N: 16384, r: 8, p: 1 }, (err, key) => {
2062
- if (err)
2063
- rej(err);
2064
- else
2065
- res(key);
2066
- });
2067
- });
2068
- const stored = `${salt.toString("hex")}:${hash.toString("hex")}`;
2069
- const pwPath = REMOTE_PASSWORD_FILE;
2070
- await writeFile(pwPath, stored, { mode: 0o600 });
2071
- return { content: [{ type: "text", text: "Remote access password set." }] };
2079
+ await setAccessPasswordHash(targetUserId, password, USERS_FILE);
2080
+ console.error(`[admin] remote-access-password set userId=${targetUserId.slice(0, 8)}`);
2081
+ return { content: [{ type: "text", text: `Remote access password set for userId ${targetUserId}.` }] };
2072
2082
  }
2073
2083
  catch (err) {
2074
2084
  return {
@@ -2077,6 +2087,40 @@ server.tool("remote-auth-set-password", "Set the remote access password. Hashes
2077
2087
  };
2078
2088
  }
2079
2089
  });
2090
+ server.tool("remote-auth-revoke-password", "Revoke an admin's remote access password so they can no longer obtain a NEW remote session (an already-open session lapses within 24h). " +
2091
+ "Does not affect any other admin's password and does not touch their PIN. Pass userId (from admin-list).", { userId: z.string().describe("The admin whose remote access password to revoke. Use admin-list to find userIds.") }, async ({ userId }) => {
2092
+ if (!ACCOUNT_ID)
2093
+ return refuseNoAccount("remote-auth-revoke-password");
2094
+ let users;
2095
+ try {
2096
+ users = readUsersJson();
2097
+ }
2098
+ catch (err) {
2099
+ return { content: [{ type: "text", text: `${err instanceof Error ? err.message : String(err)}` }], isError: true };
2100
+ }
2101
+ const target = users.find((u) => u.userId === userId);
2102
+ if (!target) {
2103
+ return { content: [{ type: "text", text: `No admin with userId ${userId} on this device.` }], isError: true };
2104
+ }
2105
+ if (!target.accessHash) {
2106
+ return { content: [{ type: "text", text: `userId ${userId} has no remote access password to revoke.` }] };
2107
+ }
2108
+ const withHash = users.filter((u) => typeof u.accessHash === "string" && u.accessHash.length > 0);
2109
+ if (withHash.length <= 1) {
2110
+ return { content: [{ type: "text", text: "Refusing to revoke the last remaining remote access password — the install would have no remote access. Set another admin's password first." }], isError: true };
2111
+ }
2112
+ try {
2113
+ clearAccessPasswordHash(userId, USERS_FILE);
2114
+ console.error(`[admin] remote-access-password revoked userId=${userId.slice(0, 8)}`);
2115
+ return { content: [{ type: "text", text: `Remote access password revoked for userId ${userId}.` }] };
2116
+ }
2117
+ catch (err) {
2118
+ return {
2119
+ content: [{ type: "text", text: `Failed to revoke: ${err instanceof Error ? err.message : String(err)}` }],
2120
+ isError: true,
2121
+ };
2122
+ }
2123
+ });
2080
2124
  // ===================================================================
2081
2125
  // Utility tools
2082
2126
  // ===================================================================