bazilion 0.12.2 → 0.14.0

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 (217) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +795 -240
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.js +4555 -1280
  5. package/dist/daemon.js.map +1 -1
  6. package/dist/migrations/0001_init.sql +21 -0
  7. package/dist/web/client/assets/AgentTabs-BcmmwYJc.js +1 -0
  8. package/dist/web/client/assets/ConfigPage-BCLp-FUC.js +1 -0
  9. package/dist/web/client/assets/ConfirmDialog-CyL9A20V.js +1 -0
  10. package/dist/web/client/assets/FieldRow-D6REbYUa.js +1 -0
  11. package/dist/web/client/assets/Page-NV96O47A.js +1 -0
  12. package/dist/web/client/assets/ProductionTeamPolicyEditor-DBKnOezm.js +7 -0
  13. package/dist/web/client/assets/{ProfileCommunicationEditor-C43HvUe-.js → ProfileCommunicationEditor-4RK2laqO.js} +1 -1
  14. package/dist/web/client/assets/SectionTabs-4kCQXuFY.js +1 -0
  15. package/dist/web/client/assets/TeamTabs-CdtNEqt4.js +1 -0
  16. package/dist/web/client/assets/{TemplatesTabs-6Jd_xQj7.js → TemplatesTabs-CZyss2Y0.js} +1 -1
  17. package/dist/web/client/assets/UnsavedChangesGuard-CEoK-ZcN.js +1 -0
  18. package/dist/web/client/assets/_id-4ZS-w_Aj.js +1 -0
  19. package/dist/web/client/assets/{_id-AOAT0H_5.js → _id-DIqtdQij.js} +1 -1
  20. package/dist/web/client/assets/_id-DbcC2E7F.js +1 -0
  21. package/dist/web/client/assets/_id-f_r5M0p3.js +1 -0
  22. package/dist/web/client/assets/activity-CB9Ufth-.js +1 -0
  23. package/dist/web/client/assets/agents-D-JGXVg9.js +1 -0
  24. package/dist/web/client/assets/agents-DS2XafoA.js +1 -0
  25. package/dist/web/client/assets/approvals-Cke_mrJv.js +1 -0
  26. package/dist/web/client/assets/attention-PYwRM2wC.js +1 -0
  27. package/dist/web/client/assets/chevron-right-BG4OeFRQ.js +1 -0
  28. package/dist/web/client/assets/config-DF9Gqmfa.js +3 -0
  29. package/dist/web/client/assets/dm-sans-latin-400-normal-BwCSEQnW.woff +0 -0
  30. package/dist/web/client/assets/dm-sans-latin-400-normal-CW0RaeGs.woff2 +0 -0
  31. package/dist/web/client/assets/dm-sans-latin-500-normal-B9HHJjqV.woff2 +0 -0
  32. package/dist/web/client/assets/dm-sans-latin-500-normal-Dr3UlScf.woff +0 -0
  33. package/dist/web/client/assets/dm-sans-latin-600-normal-Aqo67rzb.woff2 +0 -0
  34. package/dist/web/client/assets/dm-sans-latin-600-normal-BmdmIIQ2.woff +0 -0
  35. package/dist/web/client/assets/dm-sans-latin-700-normal-CUSSCpQX.woff +0 -0
  36. package/dist/web/client/assets/dm-sans-latin-700-normal-DvUfVpUG.woff2 +0 -0
  37. package/dist/web/client/assets/dm-serif-display-latin-400-normal-C5_t9oOD.woff2 +0 -0
  38. package/dist/web/client/assets/dm-serif-display-latin-400-normal-_kVFYEpx.woff +0 -0
  39. package/dist/web/client/assets/{inbox-Bn1GbUsJ.js → inbox-DC_HdOfI.js} +1 -1
  40. package/dist/web/client/assets/index-Cofc7zhl.css +1 -0
  41. package/dist/web/client/assets/index-Cp6UHWr2.js +52 -0
  42. package/dist/web/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  43. package/dist/web/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  44. package/dist/web/client/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  45. package/dist/web/client/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  46. package/dist/web/client/assets/learning-BfrQ4YZY.js +1 -0
  47. package/dist/web/client/assets/login-D4n3AcBR.js +1 -0
  48. package/dist/web/client/assets/mcp-CnjQc_JJ.js +1 -0
  49. package/dist/web/client/assets/members-wxsVTJdW.js +1 -0
  50. package/dist/web/client/assets/memory-Du60O3pE.js +1 -0
  51. package/dist/web/client/assets/{policy-DaijITy7.js → policy-BOfnkJsL.js} +1 -1
  52. package/dist/web/client/assets/{preload-helper-mNuBjNXU.js → preload-helper-bztXdkDj.js} +1 -1
  53. package/dist/web/client/assets/routes-B9CuhzUW.js +1 -0
  54. package/dist/web/client/assets/services-DyvqJqM2.js +1 -0
  55. package/dist/web/client/assets/skills-DQo7ioW7.js +1 -0
  56. package/dist/web/client/assets/styles-B5vcgXln.css +2 -0
  57. package/dist/web/client/assets/{teams-D92R9Pb7.js → teams-DPggy97H.js} +1 -1
  58. package/dist/web/client/assets/teams-DdawcfNR.js +1 -0
  59. package/dist/web/client/assets/telegram-DcTeDpP5.js +1 -0
  60. package/dist/web/client/assets/tokens-CIEKwZXc.js +1 -0
  61. package/dist/web/client/assets/triggers-Bc2RrUPm.js +1 -0
  62. package/dist/web/client/assets/utils-B6KiDbIe.js +1 -0
  63. package/dist/web/client/assets/welcome-DlhNXUIa.js +1 -0
  64. package/dist/web/client/assets/wire-constants-BzdHSc6A.js +74 -0
  65. package/dist/web/client/assets/x-DAXGIe_Q.js +1 -0
  66. package/dist/web/server/assets/{AgentTabs-aXdsiiMp.js → AgentTabs-Dq8hDM2Q.js} +9 -2
  67. package/dist/web/server/assets/{ChatPane-Ba5wTsVk.js → ChatPane-CgSe7tsy.js} +81 -43
  68. package/dist/web/server/assets/{ConfigPage-BKlh5vOU.js → ConfigPage-CiQ-gxmJ.js} +3 -2
  69. package/dist/web/server/assets/ConfirmDialog-C-MPYYSU.js +99 -0
  70. package/dist/web/server/assets/FieldRow-DCOF07kl.js +160 -0
  71. package/dist/web/server/assets/{Page-LENulSXY.js → Page-Bz-ydB8j.js} +4 -10
  72. package/dist/web/server/assets/{ProductionTeamPolicyEditor-Y4mzFFvR.js → ProductionTeamPolicyEditor-DQSdP7Yx.js} +140 -123
  73. package/dist/web/server/assets/{SectionTabs-BJTPr5nU.js → SectionTabs-B2Yw81XN.js} +2 -2
  74. package/dist/web/server/assets/{Sidebar-DsRVCszF.js → Sidebar-DKyk7oIo.js} +563 -283
  75. package/dist/web/server/assets/{TeamTabs-zZzbP1t_.js → TeamTabs-Co3n2exj.js} +2 -6
  76. package/dist/web/server/assets/{TemplatesTabs-CcRxZhJe.js → TemplatesTabs-B0fA361R.js} +1 -1
  77. package/dist/web/server/assets/UnsavedChangesGuard-CiStXyBI.js +40 -0
  78. package/dist/web/server/assets/{_id-Dj1yZ3zJ.js → _id-BAA9KJBU.js} +4 -4
  79. package/dist/web/server/assets/{_id-LrvXU4Nr.js → _id-BM5m2FLT.js} +4 -4
  80. package/dist/web/server/assets/{_id-CwyGjJeP.js → _id-BYKpT2Tu.js} +4 -5
  81. package/dist/web/server/assets/{_id-BHYLL8M-.js → _id-BeKhPKw3.js} +350 -185
  82. package/dist/web/server/assets/{_id-C3HY4lWg.js → _id-BqWTB8Wl.js} +188 -86
  83. package/dist/web/server/assets/{_id-DinTp_7X.js → _id-BwvCtzlD.js} +3 -3
  84. package/dist/web/server/assets/{_id-D27T85mU.js → _id-DYU6uIBx.js} +4 -5
  85. package/dist/web/server/assets/{_id-IzadFZV9.js → _id-DvlDkk04.js} +4 -4
  86. package/dist/web/server/assets/{_id-BhOB8Umi.js → _id-DxCnEFpm.js} +4 -4
  87. package/dist/web/server/assets/{_id-tB47Vsfp.js → _id-HMy7jM3P.js} +3 -3
  88. package/dist/web/server/assets/{_id-D3Ap7zZA.js → _id-ndxFHx0t.js} +75 -71
  89. package/dist/web/server/assets/{_id-FcHdSocl.js → _id-sNu5aXZt.js} +5 -4
  90. package/dist/web/server/assets/{_tanstack-start-manifest_v-BGDBdnUs.js → _tanstack-start-manifest_v-C-OiOZeM.js} +118 -94
  91. package/dist/web/server/assets/{activity-DohitgwW.js → activity-9VP6QDTH.js} +3 -3
  92. package/dist/web/server/assets/{activity-BCI4mfNS.js → activity-BWv1goK6.js} +3 -3
  93. package/dist/web/server/assets/{activity-D9SMqBhy.js → activity-LjpblbDL.js} +3 -3
  94. package/dist/web/server/assets/{agents-C9xlWK0Z.js → agents-BDFGrU3o.js} +4 -4
  95. package/dist/web/server/assets/{agents-BY74v7fM.js → agents-BJAv919x.js} +3 -3
  96. package/dist/web/server/assets/{agents-BvttypqB.js → agents-CJk4pxKu.js} +3 -3
  97. package/dist/web/server/assets/{agents-CgZMHj80.js → agents-CYw1xHoY.js} +138 -16
  98. package/dist/web/server/assets/{agents-DZuFEj0D.js → agents-DfNKc_Q7.js} +52 -8
  99. package/dist/web/server/assets/{agents-BPKOshR5.js → agents-DjyQk94u.js} +4 -4
  100. package/dist/web/server/assets/{approvals-CWcFHlor.js → approvals-7JOoBchn.js} +3 -3
  101. package/dist/web/server/assets/{approvals-BGU-XGIO.js → approvals-BYi84gwl.js} +3 -3
  102. package/dist/web/server/assets/{approvals-DCaVw1Mz.js → approvals-Bz123liE.js} +59 -21
  103. package/dist/web/server/assets/{attention-BxkTf337.js → attention-B35JvhOL.js} +3 -3
  104. package/dist/web/server/assets/{attention-w21GQIGH.js → attention-C1pPWSXw.js} +3 -3
  105. package/dist/web/server/assets/{attention-CM-Ks1N9.js → attention-UhqPK_Ro.js} +3 -3
  106. package/dist/web/server/assets/{auth-byfSx6Ja.js → auth-7BHTH-KS.js} +5 -5
  107. package/dist/web/server/assets/{config-BDCJdtj2.js → config-BMiajTZP.js} +10 -5
  108. package/dist/web/server/assets/{config-1w2GiJUn.js → config-BlMkHStx.js} +3 -3
  109. package/dist/web/server/assets/config-ExacOzHX.js +958 -0
  110. package/dist/web/server/assets/{createServerRpc-pU-IQV2Y.js → createServerRpc-B7Yr1K8i.js} +1 -1
  111. package/dist/web/server/assets/{createSsrRpc-DFsIAfFd.js → createSsrRpc-6LHNEsSK.js} +1 -1
  112. package/dist/web/server/assets/{daemon-client-2NRMzlTr.js → daemon-client-CI5NHwNC.js} +16 -4
  113. package/dist/web/server/assets/{inbox-CzlKT9Wg.js → inbox-Dv55rGYq.js} +4 -4
  114. package/dist/web/server/assets/{inbox-BLUzA5sQ.js → inbox-RweGCV3D.js} +3 -3
  115. package/dist/web/server/assets/{inbox-ZvDNAjaM.js → inbox-cu3jLzNP.js} +4 -4
  116. package/dist/web/server/assets/{learning-B7PBkvER.js → learning-BaKM6qaw.js} +4 -4
  117. package/dist/web/server/assets/{learning-8zav4pIT.js → learning-C2upa1CE.js} +4 -4
  118. package/dist/web/server/assets/{learning-Cq7K2heb.js → learning-CbtNlqYo.js} +76 -23
  119. package/dist/web/server/assets/{login-CmWvxfTK.js → login-BNj3U6ok.js} +22 -12
  120. package/dist/web/server/assets/{login-Bx5LEyGP.js → login-Be8eP4Jp.js} +2 -2
  121. package/dist/web/server/assets/{mcp-DIWTogHM.js → mcp-B0goWO8Q.js} +3 -3
  122. package/dist/web/server/assets/{mcp-2pwT9HU8.js → mcp-BvnvlVFd.js} +3 -3
  123. package/dist/web/server/assets/mcp-CiBs8unU.js +332 -0
  124. package/dist/web/server/assets/members-BP3UTqu1.js +12 -0
  125. package/dist/web/server/assets/members-DHYTVgwb.js +100 -0
  126. package/dist/web/server/assets/members-DiYtr-zm.js +12 -0
  127. package/dist/web/server/assets/{memory-Dngc13Nw.js → memory-BqV-Afy1.js} +4 -4
  128. package/dist/web/server/assets/{memory-a8Kz57Kh.js → memory-CkXUgf5s.js} +150 -48
  129. package/dist/web/server/assets/{memory-pZ4pZT7p.js → memory-DTFEmfF3.js} +4 -4
  130. package/dist/web/server/assets/{policy-Bb-vEgqg.js → policy-18fdTFO4.js} +3 -3
  131. package/dist/web/server/assets/{policy-C30AeFIb.js → policy-BddK4xom.js} +3 -3
  132. package/dist/web/server/assets/{policy-BcGELcc9.js → policy-Bvvav8fh.js} +4 -4
  133. package/dist/web/server/assets/public-origin-xV0lm0Ty.js +25 -0
  134. package/dist/web/server/assets/router-pjH2t8Rl.js +813 -0
  135. package/dist/web/server/assets/{routes-B6cMLIPk.js → routes-BgHisAxH.js} +22 -5
  136. package/dist/web/server/assets/{routes-BrA-U_Hm.js → routes-COtkyZG1.js} +5 -5
  137. package/dist/web/server/assets/{routes-C19CMLZt.js → routes-DAU2g7Uz.js} +4 -4
  138. package/dist/web/server/assets/services-ClyGBU7W.js +83 -0
  139. package/dist/web/server/assets/{services-C4szdhPx.js → services-DgoU1udp.js} +3 -3
  140. package/dist/web/server/assets/{services-wG8I06oS.js → services-DozuJtzX.js} +3 -3
  141. package/dist/web/server/assets/{skills-BZdqiDig.js → skills-CYih9TJw.js} +47 -6
  142. package/dist/web/server/assets/{skills-a9VSWHWq.js → skills-DfGSJTCB.js} +3 -3
  143. package/dist/web/server/assets/{skills-C-UgkuCW.js → skills-Dw3cI3si.js} +3 -3
  144. package/dist/web/server/assets/start-D4Wq9iTa.js +70 -0
  145. package/dist/web/server/assets/{teams-OIkHuxy1.js → teams-BJuoNOTB.js} +3 -3
  146. package/dist/web/server/assets/{teams-CpQ0YgWf.js → teams-DF3RViAg.js} +3 -3
  147. package/dist/web/server/assets/{teams-DEpQR2QA.js → teams-DFnuc660.js} +3 -3
  148. package/dist/web/server/assets/{teams-DqfrEoH6.js → teams-DPnAX4wD.js} +4 -4
  149. package/dist/web/server/assets/{teams-jBtvnk59.js → teams-TV6nbEN_.js} +101 -10
  150. package/dist/web/server/assets/{teams-MjqgsmC3.js → teams-be05ci17.js} +3 -3
  151. package/dist/web/server/assets/{telegram-DNgCWebD.js → telegram-1AWL6lFw.js} +3 -3
  152. package/dist/web/server/assets/{telegram-XwyKSEtj.js → telegram-DbOFpTFm.js} +3 -3
  153. package/dist/web/server/assets/{telegram-CBF8SJzB.js → telegram-Dj4Wwhd6.js} +262 -43
  154. package/dist/web/server/assets/tokens-DDwtO15P.js +359 -0
  155. package/dist/web/server/assets/tokens-DjM8GsgS.js +19 -0
  156. package/dist/web/server/assets/{tokens-BnwFbV7T.js → tokens-_2hptHP6.js} +4 -4
  157. package/dist/web/server/assets/{triggers-BZPl5CHs.js → triggers-BvjYNmmY.js} +4 -4
  158. package/dist/web/server/assets/triggers-CHk9O3rU.js +367 -0
  159. package/dist/web/server/assets/{triggers-D79NoSXk.js → triggers-Nezfw-Bd.js} +4 -4
  160. package/dist/web/server/assets/utils-C_uf36nf.js +8 -0
  161. package/dist/web/server/assets/{welcome-DDB11L5j.js → welcome-B8nchXdF.js} +9 -8
  162. package/dist/web/server/server.js +29 -33
  163. package/dist/web-server.js +4 -0
  164. package/dist/web-server.js.map +1 -1
  165. package/dist/worker.js +1744 -362
  166. package/dist/worker.js.map +1 -1
  167. package/package.json +7 -6
  168. package/dist/web/client/assets/AgentTabs-R6gSjIj3.js +0 -1
  169. package/dist/web/client/assets/ConfigPage-BCwfgyjD.js +0 -1
  170. package/dist/web/client/assets/FieldRow-avAFLgYW.js +0 -1
  171. package/dist/web/client/assets/Page-CwNuDhWz.js +0 -1
  172. package/dist/web/client/assets/ProductionTeamPolicyEditor-CsWpTsy6.js +0 -7
  173. package/dist/web/client/assets/SectionTabs-DZzy01az.js +0 -1
  174. package/dist/web/client/assets/TeamTabs-DvqWieCq.js +0 -1
  175. package/dist/web/client/assets/_id-BUuz7Drv.js +0 -1
  176. package/dist/web/client/assets/_id-BegmVRmT.js +0 -1
  177. package/dist/web/client/assets/_id-BrA4Crh_.js +0 -1
  178. package/dist/web/client/assets/activity-n0Fw9_w3.js +0 -1
  179. package/dist/web/client/assets/agents-B33VQtbl.js +0 -1
  180. package/dist/web/client/assets/agents-C50pdxp7.js +0 -1
  181. package/dist/web/client/assets/approvals-DVW0hX8h.js +0 -1
  182. package/dist/web/client/assets/attention-B2490jcN.js +0 -1
  183. package/dist/web/client/assets/chevron-down-B0aNNOyn.js +0 -1
  184. package/dist/web/client/assets/config-CMMxxeX2.js +0 -3
  185. package/dist/web/client/assets/context-DcFzsfZ3.js +0 -1
  186. package/dist/web/client/assets/index-3nrK5iFr.js +0 -12
  187. package/dist/web/client/assets/learning-BUX1MFu2.js +0 -1
  188. package/dist/web/client/assets/login-CMWpGDKv.js +0 -1
  189. package/dist/web/client/assets/mcp-lZV08dqc.js +0 -1
  190. package/dist/web/client/assets/members-DAeaY2Cy.js +0 -1
  191. package/dist/web/client/assets/memory-HmMWxxdF.js +0 -1
  192. package/dist/web/client/assets/plus-CPzRJg1V.js +0 -1
  193. package/dist/web/client/assets/routes-BNk270AM.js +0 -1
  194. package/dist/web/client/assets/services-DtrpJrdo.js +0 -1
  195. package/dist/web/client/assets/skills-Cv93A3P3.js +0 -1
  196. package/dist/web/client/assets/styles-DMltY3su.css +0 -2
  197. package/dist/web/client/assets/teams-CCFnSNKi.js +0 -1
  198. package/dist/web/client/assets/telegram-BF1vdgDB.js +0 -1
  199. package/dist/web/client/assets/tokens-BXj6hWW-.js +0 -1
  200. package/dist/web/client/assets/triggers-NT24i4hZ.js +0 -1
  201. package/dist/web/client/assets/welcome-D0cy68eZ.js +0 -1
  202. package/dist/web/client/assets/wire-constants-BhVKOCQa.js +0 -74
  203. package/dist/web/server/assets/FieldRow-B4eTegH9.js +0 -94
  204. package/dist/web/server/assets/config-BmixCpz-.js +0 -372
  205. package/dist/web/server/assets/context-B-XDf6Ym.js +0 -12
  206. package/dist/web/server/assets/context-BXGo5Vfi.js +0 -12
  207. package/dist/web/server/assets/context-DrkrIWun.js +0 -47
  208. package/dist/web/server/assets/mcp-BJjLIdP0.js +0 -261
  209. package/dist/web/server/assets/members-CCv17cjQ.js +0 -46
  210. package/dist/web/server/assets/members-CW5aBe81.js +0 -12
  211. package/dist/web/server/assets/members-VdPwD6CE.js +0 -12
  212. package/dist/web/server/assets/router-CIVjTgNp.js +0 -537
  213. package/dist/web/server/assets/services-B9yBWDX0.js +0 -79
  214. package/dist/web/server/assets/start-WH8WzTL_.js +0 -4
  215. package/dist/web/server/assets/tokens-DPDMSN5O.js +0 -12
  216. package/dist/web/server/assets/tokens-yyTSfBSN.js +0 -186
  217. package/dist/web/server/assets/triggers-CSNNzRIi.js +0 -216
@@ -1,6 +1,7 @@
1
- import { t as Route } from "./telegram-XwyKSEtj.js";
1
+ import { t as Route } from "./telegram-DbOFpTFm.js";
2
2
  import { t as Button } from "./Button-Dsnw22OF.js";
3
- import { t as ConfigPage } from "./ConfigPage-BKlh5vOU.js";
3
+ import { t as ConfirmDialog } from "./ConfirmDialog-C-MPYYSU.js";
4
+ import { t as ConfigPage } from "./ConfigPage-CiQ-gxmJ.js";
4
5
  import { useEffect, useState } from "react";
5
6
  import { useRouter } from "@tanstack/react-router";
6
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -13,10 +14,16 @@ function TelegramIntegrationPage() {
13
14
  const [saving, setSaving] = useState(false);
14
15
  const [saveError, setSaveError] = useState(null);
15
16
  const [saveOk, setSaveOk] = useState(false);
17
+ const [confirmDisconnect, setConfirmDisconnect] = useState(false);
16
18
  const [health, setHealth] = useState(null);
17
19
  const [checking, setChecking] = useState(false);
18
20
  async function save(e) {
19
21
  e.preventDefault();
22
+ if (initial.configured && token.trim().length === 0) {
23
+ setSaveOk(false);
24
+ setSaveError(chatId.trim() === initial.chatId ? "Nothing changed. Paste a replacement token to update credentials." : "Paste the bot token again when changing the supergroup, so the existing secret is never cleared or reused silently.");
25
+ return;
26
+ }
20
27
  setSaving(true);
21
28
  setSaveError(null);
22
29
  setSaveOk(false);
@@ -43,18 +50,17 @@ function TelegramIntegrationPage() {
43
50
  }
44
51
  }
45
52
  async function disconnect() {
46
- if (!confirm("Clear the saved Telegram credentials?")) return;
47
- try {
48
- await fetch("/api/config/telegram", { method: "DELETE" });
49
- setToken("");
50
- setChatId("");
51
- setHealth(null);
52
- setSaveOk(false);
53
- setSaveError(null);
54
- await router.invalidate();
55
- } catch (e) {
56
- setSaveError(e.message);
53
+ const response = await fetch("/api/config/telegram", { method: "DELETE" });
54
+ if (!response.ok && response.status !== 204) {
55
+ const body = await response.json().catch(() => null);
56
+ throw new Error(body?.error ?? `Could not clear Telegram credentials (${response.status})`);
57
57
  }
58
+ setToken("");
59
+ setChatId("");
60
+ setHealth(null);
61
+ setSaveOk(false);
62
+ setSaveError(null);
63
+ await router.invalidate();
58
64
  }
59
65
  async function runHealth() {
60
66
  setChecking(true);
@@ -119,7 +125,10 @@ function TelegramIntegrationPage() {
119
125
  type: "password",
120
126
  autoComplete: "off",
121
127
  value: token,
122
- onChange: (e) => setToken(e.target.value),
128
+ onChange: (e) => {
129
+ setToken(e.target.value);
130
+ setSaveError(null);
131
+ },
123
132
  placeholder: initial.configured ? "(leave blank to keep stored value)" : "1234567890:ABC...",
124
133
  className: "w-full rounded-md border bg-background px-2 py-1.5 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30",
125
134
  required: !initial.configured
@@ -131,6 +140,10 @@ function TelegramIntegrationPage() {
131
140
  /* @__PURE__ */ jsx("em", { children: "Bot Settings → Team Privacy → Turn off" }),
132
141
  "."
133
142
  ]
143
+ }),
144
+ initial.configured && /* @__PURE__ */ jsx("p", {
145
+ className: "mt-1 text-xs text-muted-foreground",
146
+ children: "Blank preserves the stored token. To remove it, use clear credentials and confirm the integration shutdown."
134
147
  })
135
148
  ]
136
149
  }),
@@ -144,7 +157,10 @@ function TelegramIntegrationPage() {
144
157
  /* @__PURE__ */ jsx("input", {
145
158
  type: "text",
146
159
  value: chatId,
147
- onChange: (e) => setChatId(e.target.value),
160
+ onChange: (e) => {
161
+ setChatId(e.target.value);
162
+ setSaveError(null);
163
+ },
148
164
  placeholder: "-1001234567890",
149
165
  className: "w-full rounded-md border bg-background px-2 py-1.5 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30",
150
166
  required: true
@@ -174,7 +190,7 @@ function TelegramIntegrationPage() {
174
190
  }),
175
191
  initial.configured && /* @__PURE__ */ jsx(Button, {
176
192
  variant: "danger",
177
- onClick: disconnect,
193
+ onClick: () => setConfirmDisconnect(true),
178
194
  children: "clear credentials"
179
195
  }),
180
196
  saveOk && /* @__PURE__ */ jsx("span", {
@@ -182,6 +198,7 @@ function TelegramIntegrationPage() {
182
198
  children: "saved ✓"
183
199
  }),
184
200
  saveError && /* @__PURE__ */ jsxs("span", {
201
+ role: "alert",
185
202
  className: "text-xs text-danger",
186
203
  children: ["error: ", saveError]
187
204
  })
@@ -222,7 +239,150 @@ function TelegramIntegrationPage() {
222
239
  health?.polling && /* @__PURE__ */ jsx(PollingState, { polling: health.polling })
223
240
  ]
224
241
  }),
225
- initial.configured && /* @__PURE__ */ jsx(AccessControlCard, {})
242
+ initial.configured && /* @__PURE__ */ jsx(OwnerPairingCard, {}),
243
+ initial.configured && /* @__PURE__ */ jsx(AccessControlCard, {}),
244
+ /* @__PURE__ */ jsx(ConfirmDialog, {
245
+ open: confirmDisconnect,
246
+ title: "Disconnect Telegram?",
247
+ description: /* @__PURE__ */ jsx("p", { children: "This permanently removes the saved bot token and supergroup ID. Telegram polling, ingress, and outbound delivery stop until new credentials are saved and pairing is completed again." }),
248
+ confirmLabel: "clear credentials and disconnect",
249
+ onConfirm: async () => {
250
+ try {
251
+ await disconnect();
252
+ } catch (error) {
253
+ setSaveError(error instanceof Error ? error.message : String(error));
254
+ throw error;
255
+ }
256
+ },
257
+ onOpenChange: setConfirmDisconnect
258
+ })
259
+ ]
260
+ });
261
+ }
262
+ function OwnerPairingCard() {
263
+ const [status, setStatus] = useState(null);
264
+ const [code, setCode] = useState(null);
265
+ const [err, setErr] = useState(null);
266
+ const [confirmReset, setConfirmReset] = useState(false);
267
+ const load = async () => {
268
+ const res = await fetch("/api/config/telegram/pairing");
269
+ if (!res.ok) throw new Error(res.statusText);
270
+ setStatus(await res.json());
271
+ };
272
+ useEffect(() => {
273
+ load().catch((e) => setErr(e.message));
274
+ }, []);
275
+ async function createChallenge() {
276
+ setErr(null);
277
+ const res = await fetch("/api/config/telegram/pairing/challenge", { method: "POST" });
278
+ const body = await res.json().catch(() => ({}));
279
+ if (!res.ok || !body.code) return setErr(body.error ?? res.statusText);
280
+ setCode(body.code);
281
+ setStatus(body);
282
+ }
283
+ async function cancelChallenge() {
284
+ const res = await fetch("/api/config/telegram/pairing/challenge", { method: "DELETE" });
285
+ if (!res.ok && res.status !== 204) {
286
+ const body = await res.json().catch(() => null);
287
+ throw new Error(body?.error ?? "Could not cancel the pairing code");
288
+ }
289
+ setCode(null);
290
+ await load();
291
+ }
292
+ async function resetOwner() {
293
+ const res = await fetch("/api/config/telegram/pairing/reset", {
294
+ method: "POST",
295
+ headers: { "content-type": "application/json" },
296
+ body: JSON.stringify({ confirm: true })
297
+ });
298
+ if (!res.ok) {
299
+ const body = await res.json().catch(() => null);
300
+ throw new Error(body?.error ?? "Could not reset Telegram owner");
301
+ }
302
+ setCode(null);
303
+ await load();
304
+ }
305
+ return /* @__PURE__ */ jsxs("section", {
306
+ className: "rounded-lg border bg-card p-5",
307
+ children: [
308
+ /* @__PURE__ */ jsx("h3", {
309
+ className: "text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-1",
310
+ children: "Owner pairing"
311
+ }),
312
+ /* @__PURE__ */ jsxs("p", {
313
+ className: "text-xs text-muted-foreground mb-3",
314
+ children: [
315
+ "Telegram stays closed until one owner consumes a short-lived code in the configured",
316
+ " ",
317
+ /* @__PURE__ */ jsx("code", {
318
+ className: "font-mono",
319
+ children: "⚙ bazilion"
320
+ }),
321
+ " service topic."
322
+ ]
323
+ }),
324
+ status?.paired ? /* @__PURE__ */ jsxs("div", {
325
+ className: "flex flex-wrap items-center gap-3",
326
+ children: [/* @__PURE__ */ jsx("span", {
327
+ className: "text-sm text-success",
328
+ children: "✓ owner paired"
329
+ }), /* @__PURE__ */ jsx(Button, {
330
+ variant: "danger",
331
+ onClick: () => setConfirmReset(true),
332
+ children: "reset owner"
333
+ })]
334
+ }) : /* @__PURE__ */ jsxs("div", {
335
+ className: "space-y-2",
336
+ children: [
337
+ /* @__PURE__ */ jsx("p", {
338
+ className: "text-sm text-warning",
339
+ children: "Unpaired — all Telegram ingress is closed."
340
+ }),
341
+ code ? /* @__PURE__ */ jsxs("div", {
342
+ className: "rounded-md border bg-muted/30 p-3 text-sm",
343
+ children: [
344
+ "Send ",
345
+ /* @__PURE__ */ jsxs("code", {
346
+ className: "font-mono",
347
+ children: ["/pair ", code]
348
+ }),
349
+ " in the service topic. This code is shown once and expires in ten minutes."
350
+ ]
351
+ }) : null,
352
+ /* @__PURE__ */ jsxs("div", {
353
+ className: "flex flex-wrap gap-2",
354
+ children: [/* @__PURE__ */ jsx(Button, {
355
+ variant: "primary",
356
+ onClick: createChallenge,
357
+ children: "generate pairing code"
358
+ }), status?.challengeActive && /* @__PURE__ */ jsx(Button, {
359
+ variant: "ghost",
360
+ onClick: () => void cancelChallenge().catch((error) => setErr(error instanceof Error ? error.message : String(error))),
361
+ children: "cancel code"
362
+ })]
363
+ })
364
+ ]
365
+ }),
366
+ err && /* @__PURE__ */ jsx("p", {
367
+ role: "alert",
368
+ className: "mt-2 text-xs text-danger",
369
+ children: err
370
+ }),
371
+ /* @__PURE__ */ jsx(ConfirmDialog, {
372
+ open: confirmReset,
373
+ title: "Revoke the paired Telegram owner?",
374
+ description: /* @__PURE__ */ jsx("p", { children: "This immediately revokes the current owner and closes all Telegram ingress. No one can use the bot until a new one-time pairing code is generated and consumed." }),
375
+ confirmLabel: "revoke owner and close ingress",
376
+ onConfirm: async () => {
377
+ try {
378
+ await resetOwner();
379
+ } catch (error) {
380
+ setErr(error instanceof Error ? error.message : String(error));
381
+ throw error;
382
+ }
383
+ },
384
+ onOpenChange: setConfirmReset
385
+ })
226
386
  ]
227
387
  });
228
388
  }
@@ -232,6 +392,7 @@ function AccessControlCard() {
232
392
  const [label, setLabel] = useState("");
233
393
  const [busy, setBusy] = useState(false);
234
394
  const [err, setErr] = useState(null);
395
+ const [removeTarget, setRemoveTarget] = useState(null);
235
396
  async function load() {
236
397
  try {
237
398
  const res = await fetch("/api/config/telegram/acl");
@@ -277,16 +438,12 @@ function AccessControlCard() {
277
438
  }
278
439
  async function remove(id) {
279
440
  setErr(null);
280
- try {
281
- const res = await fetch(`/api/config/telegram/acl/${id}`, { method: "DELETE" });
282
- if (!res.ok) {
283
- const j = await res.json().catch(() => ({}));
284
- throw new Error(j.error ?? res.statusText);
285
- }
286
- await load();
287
- } catch (e) {
288
- setErr(e.message);
441
+ const res = await fetch(`/api/config/telegram/acl/${id}`, { method: "DELETE" });
442
+ if (!res.ok) {
443
+ const j = await res.json().catch(() => ({}));
444
+ throw new Error(j.error ?? res.statusText);
289
445
  }
446
+ await load();
290
447
  }
291
448
  return /* @__PURE__ */ jsxs("section", {
292
449
  className: "rounded-lg border bg-card p-5",
@@ -298,7 +455,7 @@ function AccessControlCard() {
298
455
  /* @__PURE__ */ jsxs("p", {
299
456
  className: "text-xs text-muted-foreground mb-3",
300
457
  children: [
301
- "Allowlisted Telegram users can use the bot (commands + chat). While the list is empty the bot is open and the first person to message it becomes owner. Users find their id via",
458
+ "Allowlisted Telegram users can use the bot (commands + chat). An empty list is closed; ownership begins only through the one-time pairing flow. Users find their id via",
302
459
  " ",
303
460
  /* @__PURE__ */ jsx("code", {
304
461
  className: "font-mono",
@@ -312,7 +469,7 @@ function AccessControlCard() {
312
469
  children: "loading…"
313
470
  }) : users.length === 0 ? /* @__PURE__ */ jsx("p", {
314
471
  className: "text-xs text-warning mb-3",
315
- children: "Open — no allowlist yet. The first user to message the bot claims owner."
472
+ children: "Closed — no paired owner or allowlisted members."
316
473
  }) : /* @__PURE__ */ jsx("ul", {
317
474
  className: "mb-3 space-y-1 text-sm",
318
475
  children: users.map((u) => /* @__PURE__ */ jsxs("li", {
@@ -330,10 +487,10 @@ function AccessControlCard() {
330
487
  u.role
331
488
  ]
332
489
  }),
333
- u.role !== "owner" && /* @__PURE__ */ jsx("button", {
334
- type: "button",
335
- onClick: () => void remove(u.userId),
336
- className: "ghost-btn text-xs text-rose-baziu",
490
+ u.role !== "owner" && /* @__PURE__ */ jsx(Button, {
491
+ variant: "danger",
492
+ className: "text-xs",
493
+ onClick: () => setRemoveTarget(u),
337
494
  children: "remove"
338
495
  })
339
496
  ]
@@ -341,19 +498,33 @@ function AccessControlCard() {
341
498
  }),
342
499
  /* @__PURE__ */ jsxs("form", {
343
500
  onSubmit: add,
344
- className: "flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center",
501
+ className: "flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-end",
345
502
  children: [
346
- /* @__PURE__ */ jsx("input", {
347
- value: userId,
348
- onChange: (e) => setUserId(e.target.value),
349
- placeholder: "user id",
350
- className: "w-full rounded-md border bg-background px-2 py-1 font-mono text-sm sm:w-28"
503
+ /* @__PURE__ */ jsxs("label", {
504
+ className: "m-0 flex flex-col gap-1 text-xs font-medium text-foreground",
505
+ children: ["Telegram user ID", /* @__PURE__ */ jsx("input", {
506
+ value: userId,
507
+ onChange: (e) => setUserId(e.target.value),
508
+ placeholder: "123456789",
509
+ inputMode: "numeric",
510
+ className: "w-full rounded-md border bg-background px-2 py-1 font-mono text-sm sm:w-32"
511
+ })]
351
512
  }),
352
- /* @__PURE__ */ jsx("input", {
353
- value: label,
354
- onChange: (e) => setLabel(e.target.value),
355
- placeholder: "label (optional)",
356
- className: "w-full rounded-md border bg-background px-2 py-1 text-sm sm:w-40"
513
+ /* @__PURE__ */ jsxs("label", {
514
+ className: "m-0 flex flex-col gap-1 text-xs font-medium text-foreground",
515
+ children: [
516
+ "Label ",
517
+ /* @__PURE__ */ jsx("span", {
518
+ className: "font-normal text-muted-foreground",
519
+ children: "(optional)"
520
+ }),
521
+ /* @__PURE__ */ jsx("input", {
522
+ value: label,
523
+ onChange: (e) => setLabel(e.target.value),
524
+ placeholder: "e.g. Pat",
525
+ className: "w-full rounded-md border bg-background px-2 py-1 text-sm sm:w-40"
526
+ })
527
+ ]
357
528
  }),
358
529
  /* @__PURE__ */ jsx(Button, {
359
530
  variant: "ghost",
@@ -362,10 +533,36 @@ function AccessControlCard() {
362
533
  children: "add"
363
534
  }),
364
535
  err && /* @__PURE__ */ jsx("span", {
536
+ role: "alert",
365
537
  className: "text-xs text-danger",
366
538
  children: err
367
539
  })
368
540
  ]
541
+ }),
542
+ /* @__PURE__ */ jsx(ConfirmDialog, {
543
+ open: removeTarget !== null,
544
+ title: `Remove ${removeTarget?.label ?? removeTarget?.username ?? removeTarget?.userId ?? ""}?`,
545
+ description: /* @__PURE__ */ jsxs("p", { children: [
546
+ "Telegram user ",
547
+ /* @__PURE__ */ jsx("code", {
548
+ className: "font-mono",
549
+ children: removeTarget?.userId
550
+ }),
551
+ " immediately loses command and chat access. Their Telegram account is not changed, and they can be allowlisted again later."
552
+ ] }),
553
+ confirmLabel: "remove Telegram access",
554
+ onConfirm: async () => {
555
+ if (!removeTarget) return;
556
+ try {
557
+ await remove(removeTarget.userId);
558
+ } catch (error) {
559
+ setErr(error instanceof Error ? error.message : String(error));
560
+ throw error;
561
+ }
562
+ },
563
+ onOpenChange: (open) => {
564
+ if (!open) setRemoveTarget(null);
565
+ }
369
566
  })
370
567
  ]
371
568
  });
@@ -419,6 +616,7 @@ function MigrationBanner({ toChatId }) {
419
616
  children: busy ? "reconnecting…" : `Reconnect to ${toChatId}`
420
617
  }),
421
618
  err && /* @__PURE__ */ jsx("span", {
619
+ role: "alert",
422
620
  className: "ml-3 text-xs text-danger",
423
621
  children: err
424
622
  })
@@ -452,6 +650,7 @@ function PollingState({ polling }) {
452
650
  ]
453
651
  }),
454
652
  polling.error && /* @__PURE__ */ jsxs("p", {
653
+ role: "alert",
455
654
  className: "text-danger",
456
655
  children: ["error: ", polling.error]
457
656
  })
@@ -460,6 +659,7 @@ function PollingState({ polling }) {
460
659
  }
461
660
  function PreflightResult({ health }) {
462
661
  if (health.error) return /* @__PURE__ */ jsxs("div", {
662
+ role: "alert",
463
663
  className: "rounded-md border border-danger/25 bg-danger/10 px-3 py-2 text-sm",
464
664
  children: [
465
665
  /* @__PURE__ */ jsxs("p", {
@@ -477,11 +677,15 @@ function PreflightResult({ health }) {
477
677
  ]
478
678
  });
479
679
  if (!health.preflight) return /* @__PURE__ */ jsx("p", {
680
+ role: "status",
480
681
  className: "text-xs text-muted-foreground italic",
481
682
  children: "No preflight data."
482
683
  });
483
684
  const p = health.preflight;
484
685
  return /* @__PURE__ */ jsxs("ul", {
686
+ role: "status",
687
+ "aria-live": "polite",
688
+ "aria-atomic": "true",
485
689
  className: "space-y-1.5",
486
690
  children: [
487
691
  /* @__PURE__ */ jsxs(Check, {
@@ -508,6 +712,21 @@ function PreflightResult({ health }) {
508
712
  ok: p.privacyModeOff,
509
713
  label: "Privacy Mode is OFF",
510
714
  children: p.privacyModeOff ? "can_read_all_group_messages: true" : "BotFather → /mybots → select bot → Bot Settings → Team Privacy → Turn off"
715
+ }),
716
+ /* @__PURE__ */ jsx(Check, {
717
+ ok: p.chatIsPrivate,
718
+ label: "Supergroup is private",
719
+ children: p.chatIsPrivate ? "no public @username" : "public groups expose topic content to readers"
720
+ }),
721
+ /* @__PURE__ */ jsx(Check, {
722
+ ok: p.memberCount === 2,
723
+ label: "Expected membership",
724
+ children: p.memberCount === null ? "member count unavailable — verify one owner plus the bot manually" : `${p.memberCount} members reported; secure posture is one owner plus the bot`
725
+ }),
726
+ p.ownerPresent !== null && /* @__PURE__ */ jsx(Check, {
727
+ ok: p.ownerPresent,
728
+ label: "Paired owner is present",
729
+ children: p.ownerPresent ? "owner membership confirmed" : "owner missing — Telegram ingress is degraded"
511
730
  })
512
731
  ]
513
732
  });