cognova 0.2.7 → 0.2.9

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 (175) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{Bb9LNSu_.js → -JdScH3W.js} +1 -1
  3. package/.output/public/_nuxt/{A5lrd5_j.js → 0EY9Msdx.js} +1 -1
  4. package/.output/public/_nuxt/{BsXPllgv.js → 1lOC4Si0.js} +1 -1
  5. package/.output/public/_nuxt/{CeDxLTxX.js → 1zIQX9mh.js} +1 -1
  6. package/.output/public/_nuxt/{D3V98LVR.js → 4Qy4OdWt.js} +1 -1
  7. package/.output/public/_nuxt/{MdebRWqA.js → 4nN41Tyd.js} +1 -1
  8. package/.output/public/_nuxt/{BrICHPil.js → 5MZBbx-H.js} +1 -1
  9. package/.output/public/_nuxt/{Brqrl-cH.js → 6lIxuL6n.js} +1 -1
  10. package/.output/public/_nuxt/AUdD1uDD.js +1 -0
  11. package/.output/public/_nuxt/{B9Kd_0HK.js → B-513wJW.js} +1 -1
  12. package/.output/public/_nuxt/{CNwGp6eP.js → B1vDCixB.js} +1 -1
  13. package/.output/public/_nuxt/{deSeNTOh.js → B2MVZlI-.js} +1 -1
  14. package/.output/public/_nuxt/{CVr40yKH.js → B5JDxHxC.js} +1 -1
  15. package/.output/public/_nuxt/{CvMqUdkl.js → B63LIwsW.js} +3 -3
  16. package/.output/public/_nuxt/{C5nfaH9w.js → B6bnHNWY.js} +1 -1
  17. package/.output/public/_nuxt/{BaJEGr8G.js → B6wYZD_K.js} +1 -1
  18. package/.output/public/_nuxt/{_16_b82K.js → B8Ou5yh2.js} +1 -1
  19. package/.output/public/_nuxt/{BaVaTug8.js → BE4Ndhrq.js} +1 -1
  20. package/.output/public/_nuxt/{CphXSvBo.js → BES6FzF5.js} +1 -1
  21. package/.output/public/_nuxt/{BmTCDcNm.js → BE_OHTBv.js} +1 -1
  22. package/.output/public/_nuxt/{CBrXB4hk.js → BJ8jbKuq.js} +1 -1
  23. package/.output/public/_nuxt/{vM-wdhkZ.js → BNBGEa-U.js} +1 -1
  24. package/.output/public/_nuxt/{XzRnkkwG.js → BOGXUgGg.js} +1 -1
  25. package/.output/public/_nuxt/BQ1T6zWA.js +1 -0
  26. package/.output/public/_nuxt/{Bb1B0ntt.js → BVc_fOF1.js} +1 -1
  27. package/.output/public/_nuxt/{B-5roYpk.js → BX6vcvkp.js} +1 -1
  28. package/.output/public/_nuxt/{CLZS246x.js → BYIq3eP8.js} +1 -1
  29. package/.output/public/_nuxt/{B_28CKij.js → BZqdzrSw.js} +2 -2
  30. package/.output/public/_nuxt/{D-wVwRIx.js → BaYtugUf.js} +1 -1
  31. package/.output/public/_nuxt/{EgYyfo1g.js → Be5L93GM.js} +3 -3
  32. package/.output/public/_nuxt/{BLszW9T3.js → BfECQayu.js} +1 -1
  33. package/.output/public/_nuxt/{Ci-MVdCd.js → BgG2k-zy.js} +1 -1
  34. package/.output/public/_nuxt/BhnONkIm.js +1 -0
  35. package/.output/public/_nuxt/{BjFs8Ujb.js → BjI5wb_q.js} +1 -1
  36. package/.output/public/_nuxt/{CK5Ef4YR.js → Bk9-HxOg.js} +1 -1
  37. package/.output/public/_nuxt/{MzEmU9ER.js → BltasKce.js} +1 -1
  38. package/.output/public/_nuxt/{BvuV9uCn.js → Bp9kHdw6.js} +1 -1
  39. package/.output/public/_nuxt/{CnW8zyuA.js → Bsdcw5gr.js} +1 -1
  40. package/.output/public/_nuxt/{Zjvb5YJR.js → BsnhHCOa.js} +1 -1
  41. package/.output/public/_nuxt/{DMsHLHmB.js → BwJVN9k0.js} +1 -1
  42. package/.output/public/_nuxt/{CgQKyBSS.js → BwVt3BzR.js} +1 -1
  43. package/.output/public/_nuxt/{Bc0NIKN7.js → BwdxQyyo.js} +1 -1
  44. package/.output/public/_nuxt/{CfWDee_q.js → BzTjmQCD.js} +1 -1
  45. package/.output/public/_nuxt/{RRoc4m9d.js → C1FhgWcI.js} +1 -1
  46. package/.output/public/_nuxt/{DvgLoqaC.js → C2DZeD9G.js} +1 -1
  47. package/.output/public/_nuxt/{B43p0So7.js → C3JOLqW1.js} +1 -1
  48. package/.output/public/_nuxt/{atVSHCxP.js → C4ScCUjy.js} +1 -1
  49. package/.output/public/_nuxt/{Bn8loaeQ.js → C6HEirAm.js} +1 -1
  50. package/.output/public/_nuxt/{BLL1JLwq.js → C6UTTaCP.js} +1 -1
  51. package/.output/public/_nuxt/{DNpsjOxN.js → C8gtQaKB.js} +1 -1
  52. package/.output/public/_nuxt/{BhOIdu3Z.js → C8tXHRIo.js} +1 -1
  53. package/.output/public/_nuxt/{DaiWSWdm.js → C8wa4Wh4.js} +1 -1
  54. package/.output/public/_nuxt/{DZdh7_lh.js → CDradKPE.js} +1 -1
  55. package/.output/public/_nuxt/{DB3y_21M.js → CEJh-OAl.js} +1 -1
  56. package/.output/public/_nuxt/CGfVTQUF.js +1 -0
  57. package/.output/public/_nuxt/{Dx2Tgm6S.js → CGgZuPnb.js} +1 -1
  58. package/.output/public/_nuxt/{CwaMSU1O.js → CH8kNq6W.js} +1 -1
  59. package/.output/public/_nuxt/{NlScC3GW.js → CIJ2MJdc.js} +1 -1
  60. package/.output/public/_nuxt/{CzTTKfet.js → CIUZAp6g.js} +1 -1
  61. package/.output/public/_nuxt/{CwCEQ4Dw.js → CXBOHJ2W.js} +1 -1
  62. package/.output/public/_nuxt/{BJ_GgKV0.js → CY3x8iy3.js} +1 -1
  63. package/.output/public/_nuxt/{ByfSJZV6.js → CaLO8sre.js} +1 -1
  64. package/.output/public/_nuxt/{jeu3Xx8e.js → CbTu13wM.js} +1 -1
  65. package/.output/public/_nuxt/{CjYUi9c8.js → CfO_d5gC.js} +1 -1
  66. package/.output/public/_nuxt/{DpYns7cT.js → Clr3MHUr.js} +1 -1
  67. package/.output/public/_nuxt/{1Hz98MKF.js → Cmdr5BNz.js} +1 -1
  68. package/.output/public/_nuxt/{DZ_azKLI.js → Cmj-BR0q.js} +1 -1
  69. package/.output/public/_nuxt/{CSQ-nblB.js → Cn83lLUb.js} +1 -1
  70. package/.output/public/_nuxt/{BdCB2PoJ.js → CqMgz85Z.js} +1 -1
  71. package/.output/public/_nuxt/{Dkzqkzki.js → CrW6y2-s.js} +1 -1
  72. package/.output/public/_nuxt/{DAs574wU.js → CrjNndEO.js} +1 -1
  73. package/.output/public/_nuxt/{CB8_A8N4.js → Cs_udj6A.js} +1 -1
  74. package/.output/public/_nuxt/{qW7F87d8.js → CsbHYpNi.js} +3 -3
  75. package/.output/public/_nuxt/{DuOsLoVR.js → CwKe2KkK.js} +1 -1
  76. package/.output/public/_nuxt/{Db5XIfWS.js → CwOUYOe5.js} +1 -1
  77. package/.output/public/_nuxt/{0J8pJb0Z.js → CybU4a95.js} +1 -1
  78. package/.output/public/_nuxt/{WWNeb45u.js → CziltI1u.js} +1 -1
  79. package/.output/public/_nuxt/{DgPiIWA2.js → CzurfTnt.js} +1 -1
  80. package/.output/public/_nuxt/{DAFasgHH.js → D-O8wAju.js} +1 -1
  81. package/.output/public/_nuxt/{CJ85o8FK.js → D1t0272g.js} +1 -1
  82. package/.output/public/_nuxt/D3RROe4s.js +1 -0
  83. package/.output/public/_nuxt/{Cedv1M65.js → D5G5UL_g.js} +1 -1
  84. package/.output/public/_nuxt/{1IuG3yiQ.js → D76Dw8rw.js} +1 -1
  85. package/.output/public/_nuxt/{w3t8WD8v.js → D7DTZ0iS.js} +1 -1
  86. package/.output/public/_nuxt/{C6Kc4XvS.js → D7WbsJsa.js} +1 -1
  87. package/.output/public/_nuxt/D7iYVmH6.js +1 -0
  88. package/.output/public/_nuxt/{CXuKrnTA.js → D8gh62A0.js} +1 -1
  89. package/.output/public/_nuxt/{CW8xtqwN.js → DA2RowFe.js} +1 -1
  90. package/.output/public/_nuxt/{4bC1z31I.js → DBKxzQ3U.js} +1 -1
  91. package/.output/public/_nuxt/DBuW01Fx.js +1 -0
  92. package/.output/public/_nuxt/{B7-0ADn3.js → DCL9gWFw.js} +1 -1
  93. package/.output/public/_nuxt/{NBE83ZQn.js → DGJKfutb.js} +1 -1
  94. package/.output/public/_nuxt/{B5OWqWCh.js → DHScQdvh.js} +1 -1
  95. package/.output/public/_nuxt/{BTk5mgdf.js → DI1FIvaM.js} +1 -1
  96. package/.output/public/_nuxt/{0LyRrTRM.js → DJ4pqxg-.js} +1 -1
  97. package/.output/public/_nuxt/{DImdNj-F.js → DJoRBCVm.js} +1 -1
  98. package/.output/public/_nuxt/{DfpSaqgV.js → DLuRYg2p.js} +1 -1
  99. package/.output/public/_nuxt/DMy2sxuC.js +1 -0
  100. package/.output/public/_nuxt/{BJi2ZHtT.js → DQd-GXKJ.js} +1 -1
  101. package/.output/public/_nuxt/{CpC3C9gj.js → DSgubznn.js} +1 -1
  102. package/.output/public/_nuxt/{BZFXnEwe.js → DSynhNOO.js} +1 -1
  103. package/.output/public/_nuxt/{BsPj3ifk.js → DTrFhdRO.js} +1 -1
  104. package/.output/public/_nuxt/{BNlugvM3.js → DTu0K_pX.js} +1 -1
  105. package/.output/public/_nuxt/{DV0JMebZ.js → DUDbJONU.js} +1 -1
  106. package/.output/public/_nuxt/{C14DGwaT.js → DYu_NYj3.js} +1 -1
  107. package/.output/public/_nuxt/{Bf34lExB.js → D_tCgCFX.js} +1 -1
  108. package/.output/public/_nuxt/{pkbwpgSD.js → DdXVAzIg.js} +1 -1
  109. package/.output/public/_nuxt/DfIqFkyp.js +1 -0
  110. package/.output/public/_nuxt/{BoPAYize.js → Dj2opPDu.js} +1 -1
  111. package/.output/public/_nuxt/{Drr-RSSP.js → DjmFlCHK.js} +1 -1
  112. package/.output/public/_nuxt/{DgKeJf5C.js → DkhxRAb3.js} +1 -1
  113. package/.output/public/_nuxt/DlSJ4TF_.js +1 -0
  114. package/.output/public/_nuxt/{S4a_N6rD.js → DmmQUhEb.js} +1 -1
  115. package/.output/public/_nuxt/{CG0fS-BQ.js → DvATBMPl.js} +1 -1
  116. package/.output/public/_nuxt/{CxJr4mB0.js → DwAJIRGg.js} +1 -1
  117. package/.output/public/_nuxt/{CjRmY2OQ.js → FYOLNuMV.js} +1 -1
  118. package/.output/public/_nuxt/Gy6_ehml.js +1 -0
  119. package/.output/public/_nuxt/{zBoPDS4z.js → HPOXd4gt.js} +1 -1
  120. package/.output/public/_nuxt/{HCCuOAgZ.js → HlbU_z9a.js} +1 -1
  121. package/.output/public/_nuxt/{DsKy-gee.js → JQV21WEV.js} +1 -1
  122. package/.output/public/_nuxt/{JJIcQEna.js → NusIKwmA.js} +1 -1
  123. package/.output/public/_nuxt/{HC3657Xq.js → OrcbFmB1.js} +1 -1
  124. package/.output/public/_nuxt/{fTEmwfo4.js → Oy4_RPEZ.js} +1 -1
  125. package/.output/public/_nuxt/{Dpp5cOwJ.js → Pa936BQP.js} +1 -1
  126. package/.output/public/_nuxt/PzQHm02e.js +1 -0
  127. package/.output/public/_nuxt/{Dysa6np_.js → REP2-rzf.js} +1 -1
  128. package/.output/public/_nuxt/{-2wkydbj.js → RRbnMIVe.js} +1 -1
  129. package/.output/public/_nuxt/{CzqLfT8k.js → TGVM5w2K.js} +1 -1
  130. package/.output/public/_nuxt/UbZP7wjm.js +1 -0
  131. package/.output/public/_nuxt/{BW-E-Sar.js → XJYoLoTi.js} +1 -1
  132. package/.output/public/_nuxt/{CrjKigv8.js → a9_LvIZ4.js} +1 -1
  133. package/.output/public/_nuxt/builds/latest.json +1 -1
  134. package/.output/public/_nuxt/builds/meta/613faa5d-8ace-45e0-8274-b611cc4fd1ad.json +1 -0
  135. package/.output/public/_nuxt/entry.DkvuF_CR.css +1 -0
  136. package/.output/public/_nuxt/{CwJR22-0.js → fVkHtgGF.js} +1 -1
  137. package/.output/public/_nuxt/{sdvIKLwS.js → hm3ShyaF.js} +1 -1
  138. package/.output/public/_nuxt/{CqiOV9n1.js → k16puyWi.js} +1 -1
  139. package/.output/public/_nuxt/{B8Kve-DH.js → myNwwtfj.js} +1 -1
  140. package/.output/public/_nuxt/{DxR8g9So.js → nTCVPCKg.js} +1 -1
  141. package/.output/public/_nuxt/{DytaiikM.js → pHQcHl8n.js} +1 -1
  142. package/.output/public/_nuxt/{Cebw7Q7c.js → pNqWPbXW.js} +1 -1
  143. package/.output/public/_nuxt/{Cow1TrPj.js → qWWnsfRV.js} +1 -1
  144. package/.output/public/_nuxt/{DCco_rlV.js → rRYEvKFu.js} +1 -1
  145. package/.output/public/_nuxt/{hqpqUuXS.js → svWfwR0T.js} +1 -1
  146. package/.output/public/_nuxt/{BMLwzSDu.js → wgX1ldgZ.js} +1 -1
  147. package/.output/public/_nuxt/{CEfkp9Rl.js → xrh9hzzH.js} +2 -2
  148. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  149. package/.output/server/chunks/build/server.mjs +1 -1
  150. package/.output/server/chunks/build/{settings-DuT6LGJZ.mjs → settings-B2KXoGcz.mjs} +1679 -203
  151. package/.output/server/chunks/build/settings-B2KXoGcz.mjs.map +1 -0
  152. package/.output/server/chunks/build/styles.mjs +4 -4
  153. package/.output/server/chunks/nitro/nitro.mjs +922 -866
  154. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  155. package/.output/server/package.json +1 -1
  156. package/app/pages/settings.vue +581 -6
  157. package/package.json +1 -1
  158. package/server/api/skills/import.post.ts +1 -1
  159. package/server/bridge/adapters/telegram.ts +84 -9
  160. package/.output/public/_nuxt/B-YQztaH.js +0 -1
  161. package/.output/public/_nuxt/B1gFtqXK.js +0 -1
  162. package/.output/public/_nuxt/BTfZ7nek.js +0 -1
  163. package/.output/public/_nuxt/BbPnqQJ0.js +0 -1
  164. package/.output/public/_nuxt/BhSWIRpp.js +0 -1
  165. package/.output/public/_nuxt/By6kmkhJ.js +0 -1
  166. package/.output/public/_nuxt/C4XVJnNJ.js +0 -1
  167. package/.output/public/_nuxt/CkvyAKbu.js +0 -1
  168. package/.output/public/_nuxt/D2f7BlK2.js +0 -1
  169. package/.output/public/_nuxt/D2lmhTjQ.js +0 -1
  170. package/.output/public/_nuxt/D64-rCSQ.js +0 -1
  171. package/.output/public/_nuxt/DGP2JJt8.js +0 -1
  172. package/.output/public/_nuxt/builds/meta/9863fe43-d78c-4b29-a1e8-e6de61119507.json +0 -1
  173. package/.output/public/_nuxt/entry._7ZkP07A.css +0 -1
  174. package/.output/public/_nuxt/f7zDjk6q.js +0 -1
  175. package/.output/server/chunks/build/settings-DuT6LGJZ.mjs.map +0 -1
@@ -5,14 +5,14 @@ import { _ as _sfc_main$a } from './Tabs-B6vgKDY9.mjs';
5
5
  import { _ as _sfc_main$6 } from './Form-X6hlUv6q.mjs';
6
6
  import { _ as _sfc_main$7 } from './FormField-Caux_FCv.mjs';
7
7
  import { _ as _sfc_main$8 } from './Input-CV2hlBHo.mjs';
8
- import { _ as _sfc_main$e } from './Separator-CYbxFNTe.mjs';
9
- import { _ as _sfc_main$c } from './Table-DCwTlhCj.mjs';
8
+ import { _ as _sfc_main$b } from './Separator-CYbxFNTe.mjs';
9
+ import { _ as _sfc_main$e } from './Table-DCwTlhCj.mjs';
10
10
  import { _ as _sfc_main$4 } from './Skeleton-DZqsQzFi.mjs';
11
- import { _ as _sfc_main$b } from './Switch-GWdksmY6.mjs';
11
+ import { _ as _sfc_main$c } from './Switch-GWdksmY6.mjs';
12
12
  import { _ as _sfc_main$5 } from './Modal-Z_SoWhh-.mjs';
13
13
  import { _ as _sfc_main$9 } from './Select-BB1oLrCD.mjs';
14
- import { defineComponent, reactive, ref, watch, mergeProps, withCtx, createVNode, unref, isRef, createTextVNode, toDisplayString, createBlock, openBlock, Fragment, renderList, createCommentVNode, useSSRContext } from 'vue';
15
- import { ssrRenderComponent, ssrInterpolate } from 'vue/server-renderer';
14
+ import { defineComponent, reactive, ref, watch, mergeProps, withCtx, createVNode, unref, isRef, createTextVNode, toDisplayString, createBlock, createCommentVNode, openBlock, Fragment, renderList, withModifiers, useSSRContext } from 'vue';
15
+ import { ssrRenderComponent, ssrInterpolate, ssrRenderList, ssrIncludeBooleanAttr } from 'vue/server-renderer';
16
16
  import { T as defaultNotificationPreferences } from '../nitro/nitro.mjs';
17
17
  import { u as useAuth } from './useAuth-rW9toE_m.mjs';
18
18
  import { u as useNotificationBus } from './useNotificationBus-BG5JNQf1.mjs';
@@ -234,6 +234,36 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
234
234
  year: "numeric"
235
235
  });
236
236
  }
237
+ const appUrl = ref("");
238
+ const appUrlSaving = ref(false);
239
+ async function saveAppUrl() {
240
+ appUrlSaving.value = true;
241
+ try {
242
+ if (appUrl.value) {
243
+ const exists = secretsData.value.some((s) => s.key === "APP_URL");
244
+ if (exists) {
245
+ await $fetch("/api/secrets/APP_URL", {
246
+ method: "PUT",
247
+ body: { value: appUrl.value, description: "Public URL for webhooks and auth callbacks" }
248
+ });
249
+ } else {
250
+ await $fetch("/api/secrets", {
251
+ method: "POST",
252
+ body: { key: "APP_URL", value: appUrl.value, description: "Public URL for webhooks and auth callbacks" }
253
+ });
254
+ }
255
+ } else {
256
+ const exists = secretsData.value.some((s) => s.key === "APP_URL");
257
+ if (exists)
258
+ await $fetch("/api/secrets/APP_URL", { method: "DELETE" });
259
+ }
260
+ toast.add({ title: "Public URL saved", description: "Restart running integrations for changes to take effect.", color: "success" });
261
+ await fetchSecrets();
262
+ } catch {
263
+ toast.add({ title: "Failed to save URL", color: "error" });
264
+ }
265
+ appUrlSaving.value = false;
266
+ }
237
267
  const notifPrefs = ref({ ...defaultNotificationPreferences });
238
268
  const notifLoading = ref(false);
239
269
  const notifSaving = ref(false);
@@ -290,6 +320,62 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
290
320
  platform: "telegram",
291
321
  name: ""
292
322
  });
323
+ const bridgeConfigModal = ref(false);
324
+ const editingBridge = ref(null);
325
+ const bridgeConfigSaving = ref(false);
326
+ const bridgeConfigForm = reactive({
327
+ name: "",
328
+ // Telegram
329
+ botUsername: "",
330
+ allowedChatIds: "",
331
+ // Discord
332
+ listenMode: "mentions",
333
+ guildId: "",
334
+ channelId: "",
335
+ // iMessage
336
+ strategy: "imsg",
337
+ allowedNumbers: "",
338
+ blueBubblesUrl: "",
339
+ // Google
340
+ enabledServices: [],
341
+ account: "",
342
+ // Email
343
+ imapHost: "",
344
+ imapPort: "",
345
+ smtpHost: "",
346
+ smtpPort: "",
347
+ emailAddress: ""
348
+ });
349
+ const discordListenModeOptions = [
350
+ { value: "mentions", label: "Mentions & DMs" },
351
+ { value: "dm", label: "DMs only" },
352
+ { value: "all", label: "All messages" }
353
+ ];
354
+ const imessageStrategyOptions = [
355
+ { value: "imsg", label: "Local (imsg CLI)" },
356
+ { value: "bluebubbles", label: "BlueBubbles" }
357
+ ];
358
+ const googleServiceOptions = [
359
+ { value: "gmail", label: "Gmail" },
360
+ { value: "calendar", label: "Calendar" },
361
+ { value: "drive", label: "Drive" },
362
+ { value: "contacts", label: "Contacts" },
363
+ { value: "tasks", label: "Tasks" }
364
+ ];
365
+ const platformNamePlaceholders = {
366
+ telegram: "My Telegram Bot",
367
+ discord: "My Discord Bot",
368
+ imessage: "iMessage Bridge",
369
+ google: "Google Suite",
370
+ email: "Work Email"
371
+ };
372
+ const platformRequiredSecrets = {
373
+ telegram: ["TELEGRAM_BOT_TOKEN"],
374
+ discord: ["DISCORD_BOT_TOKEN"],
375
+ imessage: [],
376
+ google: [],
377
+ email: []
378
+ };
293
379
  const platformOptions = [
294
380
  { value: "telegram", label: "Telegram", icon: "i-lucide-send" },
295
381
  { value: "discord", label: "Discord", icon: "i-lucide-message-circle" },
@@ -297,6 +383,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
297
383
  { value: "google", label: "Google Suite", icon: "i-lucide-mail" },
298
384
  { value: "email", label: "Email (IMAP)", icon: "i-lucide-at-sign" }
299
385
  ];
386
+ function getMissingSecrets(platform) {
387
+ const required = platformRequiredSecrets[platform];
388
+ if (!required.length) return [];
389
+ const existing = new Set(secretsData.value.map((s) => s.key));
390
+ return required.filter((k) => !existing.has(k));
391
+ }
300
392
  const healthColors = {
301
393
  connected: "text-success",
302
394
  disconnected: "text-dimmed",
@@ -313,6 +405,102 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
313
405
  }
314
406
  bridgesLoading.value = false;
315
407
  }
408
+ function openBridgeConfig(bridge) {
409
+ editingBridge.value = bridge;
410
+ bridgeConfigForm.name = bridge.name;
411
+ const config = bridge.config ? JSON.parse(bridge.config) : {};
412
+ bridgeConfigForm.botUsername = "";
413
+ bridgeConfigForm.allowedChatIds = "";
414
+ bridgeConfigForm.listenMode = "mentions";
415
+ bridgeConfigForm.guildId = "";
416
+ bridgeConfigForm.channelId = "";
417
+ bridgeConfigForm.strategy = "imsg";
418
+ bridgeConfigForm.allowedNumbers = "";
419
+ bridgeConfigForm.blueBubblesUrl = "";
420
+ bridgeConfigForm.enabledServices = [];
421
+ bridgeConfigForm.account = "";
422
+ bridgeConfigForm.imapHost = "";
423
+ bridgeConfigForm.imapPort = "";
424
+ bridgeConfigForm.smtpHost = "";
425
+ bridgeConfigForm.smtpPort = "";
426
+ bridgeConfigForm.emailAddress = "";
427
+ switch (bridge.platform) {
428
+ case "telegram":
429
+ bridgeConfigForm.botUsername = config.botUsername || "";
430
+ bridgeConfigForm.allowedChatIds = (config.allowedChatIds || []).join(", ");
431
+ break;
432
+ case "discord":
433
+ bridgeConfigForm.listenMode = config.listenMode || "mentions";
434
+ bridgeConfigForm.guildId = config.guildId || "";
435
+ bridgeConfigForm.channelId = config.channelId || "";
436
+ break;
437
+ case "imessage":
438
+ bridgeConfigForm.strategy = config.strategy || "imsg";
439
+ bridgeConfigForm.allowedNumbers = (config.allowedNumbers || []).join(", ");
440
+ bridgeConfigForm.blueBubblesUrl = config.blueBubblesUrl || "";
441
+ break;
442
+ case "google":
443
+ bridgeConfigForm.enabledServices = config.enabledServices || [];
444
+ bridgeConfigForm.account = config.account || "";
445
+ break;
446
+ case "email":
447
+ bridgeConfigForm.imapHost = config.imapHost || "";
448
+ bridgeConfigForm.imapPort = config.imapPort?.toString() || "";
449
+ bridgeConfigForm.smtpHost = config.smtpHost || "";
450
+ bridgeConfigForm.smtpPort = config.smtpPort?.toString() || "";
451
+ bridgeConfigForm.emailAddress = config.emailAddress || "";
452
+ break;
453
+ }
454
+ bridgeConfigModal.value = true;
455
+ }
456
+ async function handleBridgeConfigSave() {
457
+ if (!editingBridge.value) return;
458
+ const platform = editingBridge.value.platform;
459
+ let config = {};
460
+ if (editingBridge.value.config)
461
+ config = JSON.parse(editingBridge.value.config);
462
+ switch (platform) {
463
+ case "telegram":
464
+ config.botUsername = bridgeConfigForm.botUsername || void 0;
465
+ config.allowedChatIds = bridgeConfigForm.allowedChatIds ? bridgeConfigForm.allowedChatIds.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
466
+ break;
467
+ case "discord":
468
+ config.listenMode = bridgeConfigForm.listenMode;
469
+ config.guildId = bridgeConfigForm.guildId || void 0;
470
+ config.channelId = bridgeConfigForm.channelId || void 0;
471
+ break;
472
+ case "imessage":
473
+ config.strategy = bridgeConfigForm.strategy;
474
+ config.allowedNumbers = bridgeConfigForm.allowedNumbers ? bridgeConfigForm.allowedNumbers.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
475
+ config.blueBubblesUrl = bridgeConfigForm.blueBubblesUrl || void 0;
476
+ break;
477
+ case "google":
478
+ config.enabledServices = bridgeConfigForm.enabledServices;
479
+ config.account = bridgeConfigForm.account || void 0;
480
+ break;
481
+ case "email":
482
+ config.imapHost = bridgeConfigForm.imapHost || void 0;
483
+ config.imapPort = bridgeConfigForm.imapPort ? Number(bridgeConfigForm.imapPort) : void 0;
484
+ config.smtpHost = bridgeConfigForm.smtpHost || void 0;
485
+ config.smtpPort = bridgeConfigForm.smtpPort ? Number(bridgeConfigForm.smtpPort) : void 0;
486
+ config.emailAddress = bridgeConfigForm.emailAddress || void 0;
487
+ break;
488
+ }
489
+ bridgeConfigSaving.value = true;
490
+ try {
491
+ await $fetch(`/api/bridges/${editingBridge.value.id}`, {
492
+ method: "PUT",
493
+ body: { name: bridgeConfigForm.name, config }
494
+ });
495
+ toast.add({ title: "Integration updated", color: "success" });
496
+ bridgeConfigModal.value = false;
497
+ await fetchBridges();
498
+ } catch (err) {
499
+ const error = err;
500
+ toast.add({ title: "Failed to update integration", description: error.data?.message, color: "error" });
501
+ }
502
+ bridgeConfigSaving.value = false;
503
+ }
316
504
  function openCreateBridge() {
317
505
  bridgeForm.platform = "telegram";
318
506
  bridgeForm.name = "";
@@ -323,6 +511,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
323
511
  toast.add({ title: "Name is required", color: "error" });
324
512
  return;
325
513
  }
514
+ const missing = getMissingSecrets(bridgeForm.platform);
515
+ if (missing.length) {
516
+ toast.add({
517
+ title: "Missing required secrets",
518
+ description: `Add ${missing.join(", ")} in the Secrets tab first.`,
519
+ color: "error"
520
+ });
521
+ return;
522
+ }
326
523
  bridgeSaving.value = true;
327
524
  try {
328
525
  await $fetch("/api/bridges", {
@@ -461,11 +658,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
461
658
  const _component_UFormField = _sfc_main$7;
462
659
  const _component_UInput = _sfc_main$8;
463
660
  const _component_UButton = _sfc_main$8$1;
464
- const _component_USeparator = _sfc_main$e;
465
- const _component_UTable = _sfc_main$c;
661
+ const _component_USeparator = _sfc_main$b;
662
+ const _component_UTable = _sfc_main$e;
466
663
  const _component_UIcon = _sfc_main$d;
467
664
  const _component_USkeleton = _sfc_main$4;
468
- const _component_USwitch = _sfc_main$b;
665
+ const _component_USwitch = _sfc_main$c;
469
666
  const _component_UModal = _sfc_main$5;
470
667
  const _component_USelect = _sfc_main$9;
471
668
  _push(ssrRenderComponent(_component_UDashboardPanel, mergeProps({
@@ -925,6 +1122,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
925
1122
  }),
926
1123
  _: 1
927
1124
  }, _parent3, _scopeId2));
1125
+ if (getMissingSecrets(unref(bridgeForm).platform).length) {
1126
+ _push3(`<div class="flex items-start gap-2 rounded-lg bg-error/10 border border-error/20 p-3 text-sm"${_scopeId2}>`);
1127
+ _push3(ssrRenderComponent(_component_UIcon, {
1128
+ name: "i-lucide-alert-triangle",
1129
+ class: "size-4 mt-0.5 text-error shrink-0"
1130
+ }, null, _parent3, _scopeId2));
1131
+ _push3(`<div${_scopeId2}><p class="font-medium text-error"${_scopeId2}> Missing required secrets </p><p class="text-dimmed mt-1"${_scopeId2}> Add the following in Settings → Secrets before creating: </p><ul class="mt-1 space-y-0.5"${_scopeId2}><!--[-->`);
1132
+ ssrRenderList(getMissingSecrets(unref(bridgeForm).platform), (key) => {
1133
+ _push3(`<li${_scopeId2}><code class="text-xs bg-elevated px-1.5 py-0.5 rounded"${_scopeId2}>${ssrInterpolate(key)}</code></li>`);
1134
+ });
1135
+ _push3(`<!--]--></ul></div></div>`);
1136
+ } else {
1137
+ _push3(`<!---->`);
1138
+ }
928
1139
  _push3(ssrRenderComponent(_component_UFormField, {
929
1140
  label: "Name",
930
1141
  name: "name"
@@ -934,7 +1145,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
934
1145
  _push4(ssrRenderComponent(_component_UInput, {
935
1146
  modelValue: unref(bridgeForm).name,
936
1147
  "onUpdate:modelValue": ($event) => unref(bridgeForm).name = $event,
937
- placeholder: "My Telegram Bot",
1148
+ placeholder: platformNamePlaceholders[unref(bridgeForm).platform],
938
1149
  class: "w-full"
939
1150
  }, null, _parent4, _scopeId3));
940
1151
  } else {
@@ -942,9 +1153,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
942
1153
  createVNode(_component_UInput, {
943
1154
  modelValue: unref(bridgeForm).name,
944
1155
  "onUpdate:modelValue": ($event) => unref(bridgeForm).name = $event,
945
- placeholder: "My Telegram Bot",
1156
+ placeholder: platformNamePlaceholders[unref(bridgeForm).platform],
946
1157
  class: "w-full"
947
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1158
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "placeholder"])
948
1159
  ];
949
1160
  }
950
1161
  }),
@@ -968,6 +1179,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
968
1179
  }, _parent3, _scopeId2));
969
1180
  _push3(ssrRenderComponent(_component_UButton, {
970
1181
  loading: unref(bridgeSaving),
1182
+ disabled: getMissingSecrets(unref(bridgeForm).platform).length > 0,
971
1183
  onClick: handleBridgeCreate
972
1184
  }, {
973
1185
  default: withCtx((_3, _push4, _parent4, _scopeId3) => {
@@ -1000,6 +1212,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1000
1212
  ]),
1001
1213
  _: 1
1002
1214
  }),
1215
+ getMissingSecrets(unref(bridgeForm).platform).length ? (openBlock(), createBlock("div", {
1216
+ key: 0,
1217
+ class: "flex items-start gap-2 rounded-lg bg-error/10 border border-error/20 p-3 text-sm"
1218
+ }, [
1219
+ createVNode(_component_UIcon, {
1220
+ name: "i-lucide-alert-triangle",
1221
+ class: "size-4 mt-0.5 text-error shrink-0"
1222
+ }),
1223
+ createVNode("div", null, [
1224
+ createVNode("p", { class: "font-medium text-error" }, " Missing required secrets "),
1225
+ createVNode("p", { class: "text-dimmed mt-1" }, " Add the following in Settings → Secrets before creating: "),
1226
+ createVNode("ul", { class: "mt-1 space-y-0.5" }, [
1227
+ (openBlock(true), createBlock(Fragment, null, renderList(getMissingSecrets(unref(bridgeForm).platform), (key) => {
1228
+ return openBlock(), createBlock("li", { key }, [
1229
+ createVNode("code", { class: "text-xs bg-elevated px-1.5 py-0.5 rounded" }, toDisplayString(key), 1)
1230
+ ]);
1231
+ }), 128))
1232
+ ])
1233
+ ])
1234
+ ])) : createCommentVNode("", true),
1003
1235
  createVNode(_component_UFormField, {
1004
1236
  label: "Name",
1005
1237
  name: "name"
@@ -1008,9 +1240,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1008
1240
  createVNode(_component_UInput, {
1009
1241
  modelValue: unref(bridgeForm).name,
1010
1242
  "onUpdate:modelValue": ($event) => unref(bridgeForm).name = $event,
1011
- placeholder: "My Telegram Bot",
1243
+ placeholder: platformNamePlaceholders[unref(bridgeForm).platform],
1012
1244
  class: "w-full"
1013
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1245
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "placeholder"])
1014
1246
  ]),
1015
1247
  _: 1
1016
1248
  }),
@@ -1026,13 +1258,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1026
1258
  }, 8, ["onClick"]),
1027
1259
  createVNode(_component_UButton, {
1028
1260
  loading: unref(bridgeSaving),
1261
+ disabled: getMissingSecrets(unref(bridgeForm).platform).length > 0,
1029
1262
  onClick: handleBridgeCreate
1030
1263
  }, {
1031
1264
  default: withCtx(() => [
1032
1265
  createTextVNode(" Create ")
1033
1266
  ]),
1034
1267
  _: 1
1035
- }, 8, ["loading"])
1268
+ }, 8, ["loading", "disabled"])
1036
1269
  ])
1037
1270
  ])
1038
1271
  ];
@@ -1120,189 +1353,1054 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1120
1353
  }),
1121
1354
  _: 1
1122
1355
  }, _parent2, _scopeId));
1123
- } else {
1124
- return [
1125
- createVNode(_component_UDashboardNavbar, { title: "Settings" }, {
1126
- right: withCtx(() => [
1127
- createVNode(_component_UColorModeButton)
1128
- ]),
1129
- _: 1
1130
- }),
1131
- createVNode("div", { class: "p-6" }, [
1132
- createVNode(_component_ClientOnly, null, {
1133
- fallback: withCtx(() => [
1134
- createVNode("div", { class: "space-y-8 max-w-xl mx-auto py-6" }, [
1135
- createVNode(_component_USkeleton, { class: "h-10 w-full" }),
1136
- createVNode("div", { class: "space-y-4" }, [
1137
- createVNode(_component_USkeleton, { class: "h-5 w-20" }),
1138
- createVNode(_component_USkeleton, { class: "h-10 w-full" }),
1139
- createVNode(_component_USkeleton, { class: "h-10 w-28" })
1140
- ])
1356
+ _push2(ssrRenderComponent(_component_UModal, {
1357
+ open: unref(bridgeConfigModal),
1358
+ "onUpdate:open": ($event) => isRef(bridgeConfigModal) ? bridgeConfigModal.value = $event : null
1359
+ }, {
1360
+ header: withCtx((_2, _push3, _parent3, _scopeId2) => {
1361
+ if (_push3) {
1362
+ _push3(`<div class="flex items-center gap-2"${_scopeId2}>`);
1363
+ _push3(ssrRenderComponent(_component_UIcon, {
1364
+ name: platformOptions.find((p) => p.value === unref(editingBridge)?.platform)?.icon || "i-lucide-plug",
1365
+ class: "size-5"
1366
+ }, null, _parent3, _scopeId2));
1367
+ _push3(`<h3 class="text-lg font-semibold"${_scopeId2}> Configure ${ssrInterpolate(unref(editingBridge)?.name)}</h3></div>`);
1368
+ } else {
1369
+ return [
1370
+ createVNode("div", { class: "flex items-center gap-2" }, [
1371
+ createVNode(_component_UIcon, {
1372
+ name: platformOptions.find((p) => p.value === unref(editingBridge)?.platform)?.icon || "i-lucide-plug",
1373
+ class: "size-5"
1374
+ }, null, 8, ["name"]),
1375
+ createVNode("h3", { class: "text-lg font-semibold" }, " Configure " + toDisplayString(unref(editingBridge)?.name), 1)
1141
1376
  ])
1142
- ]),
1143
- default: withCtx(() => [
1144
- createVNode(_component_UTabs, {
1145
- items: tabs,
1146
- "default-value": "account",
1147
- class: "w-full mx-auto",
1148
- ui: { list: "max-w-xl" }
1377
+ ];
1378
+ }
1379
+ }),
1380
+ body: withCtx((_2, _push3, _parent3, _scopeId2) => {
1381
+ if (_push3) {
1382
+ _push3(`<div class="space-y-4"${_scopeId2}>`);
1383
+ if (unref(editingBridge) && platformRequiredSecrets[unref(editingBridge).platform].length) {
1384
+ _push3(`<div class="flex items-start gap-2 rounded-lg bg-elevated p-3 text-sm"${_scopeId2}>`);
1385
+ _push3(ssrRenderComponent(_component_UIcon, {
1386
+ name: "i-lucide-info",
1387
+ class: "size-4 mt-0.5 text-dimmed shrink-0"
1388
+ }, null, _parent3, _scopeId2));
1389
+ _push3(`<span class="text-dimmed"${_scopeId2}> Requires <!--[-->`);
1390
+ ssrRenderList(platformRequiredSecrets[unref(editingBridge).platform], (key, i) => {
1391
+ _push3(`<!--[--><code class="bg-elevated px-1 py-0.5 rounded text-xs"${_scopeId2}>${ssrInterpolate(key)}</code>`);
1392
+ if (i < platformRequiredSecrets[unref(editingBridge).platform].length - 1) {
1393
+ _push3(`<!--[-->, <!--]-->`);
1394
+ } else {
1395
+ _push3(`<!---->`);
1396
+ }
1397
+ _push3(`<!--]-->`);
1398
+ });
1399
+ _push3(`<!--]--> in the Secrets tab. </span></div>`);
1400
+ } else {
1401
+ _push3(`<!---->`);
1402
+ }
1403
+ _push3(ssrRenderComponent(_component_UFormField, {
1404
+ label: "Name",
1405
+ name: "name"
1406
+ }, {
1407
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1408
+ if (_push4) {
1409
+ _push4(ssrRenderComponent(_component_UInput, {
1410
+ modelValue: unref(bridgeConfigForm).name,
1411
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).name = $event,
1412
+ placeholder: "Integration name",
1413
+ class: "w-full"
1414
+ }, null, _parent4, _scopeId3));
1415
+ } else {
1416
+ return [
1417
+ createVNode(_component_UInput, {
1418
+ modelValue: unref(bridgeConfigForm).name,
1419
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).name = $event,
1420
+ placeholder: "Integration name",
1421
+ class: "w-full"
1422
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1423
+ ];
1424
+ }
1425
+ }),
1426
+ _: 1
1427
+ }, _parent3, _scopeId2));
1428
+ if (unref(editingBridge)?.platform === "telegram") {
1429
+ _push3(`<!--[-->`);
1430
+ _push3(ssrRenderComponent(_component_UFormField, {
1431
+ label: "Bot Username",
1432
+ name: "botUsername",
1433
+ hint: "Without the @ prefix"
1149
1434
  }, {
1150
- account: withCtx(() => [
1151
- createVNode("div", { class: "space-y-8 max-w-2xl mx-auto py-6" }, [
1152
- createVNode("div", null, [
1153
- createVNode("h3", { class: "text-lg font-semibold mb-4" }, " Profile "),
1154
- createVNode(_component_UForm, {
1155
- state: unref(profileState),
1156
- class: "space-y-4",
1157
- onSubmit: handleProfileSubmit
1158
- }, {
1159
- default: withCtx(() => [
1160
- createVNode(_component_UFormField, {
1161
- label: "Name",
1162
- name: "name"
1163
- }, {
1164
- default: withCtx(() => [
1165
- createVNode(_component_UInput, {
1166
- modelValue: unref(profileState).name,
1167
- "onUpdate:modelValue": ($event) => unref(profileState).name = $event,
1168
- placeholder: "Your name",
1169
- class: "w-full"
1170
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1171
- ]),
1172
- _: 1
1173
- }),
1174
- createVNode(_component_UButton, {
1175
- type: "submit",
1176
- loading: unref(profileLoading)
1177
- }, {
1178
- default: withCtx(() => [
1179
- createTextVNode(" Save Name ")
1180
- ]),
1181
- _: 1
1182
- }, 8, ["loading"])
1183
- ]),
1184
- _: 1
1185
- }, 8, ["state"])
1186
- ]),
1187
- createVNode(_component_USeparator),
1188
- createVNode("div", null, [
1189
- createVNode("h3", { class: "text-lg font-semibold mb-4" }, " Email Address "),
1190
- createVNode(_component_UForm, {
1191
- state: unref(emailState),
1192
- class: "space-y-4",
1193
- onSubmit: handleEmailSubmit
1194
- }, {
1195
- default: withCtx(() => [
1196
- createVNode(_component_UFormField, {
1197
- label: "Email",
1198
- name: "newEmail"
1199
- }, {
1200
- default: withCtx(() => [
1201
- createVNode(_component_UInput, {
1202
- modelValue: unref(emailState).newEmail,
1203
- "onUpdate:modelValue": ($event) => unref(emailState).newEmail = $event,
1204
- type: "email",
1205
- placeholder: "your@email.com",
1206
- class: "w-full"
1207
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1208
- ]),
1209
- _: 1
1210
- }),
1211
- createVNode(_component_UButton, {
1212
- type: "submit",
1213
- loading: unref(emailLoading)
1214
- }, {
1215
- default: withCtx(() => [
1216
- createTextVNode(" Change Email ")
1217
- ]),
1218
- _: 1
1219
- }, 8, ["loading"])
1220
- ]),
1221
- _: 1
1222
- }, 8, ["state"])
1223
- ]),
1224
- createVNode(_component_USeparator),
1225
- createVNode("div", null, [
1226
- createVNode("h3", { class: "text-lg font-semibold mb-4" }, " Change Password "),
1227
- createVNode(_component_UForm, {
1228
- state: unref(passwordState),
1229
- class: "space-y-4",
1230
- onSubmit: handlePasswordSubmit
1231
- }, {
1232
- default: withCtx(() => [
1233
- createVNode(_component_UFormField, {
1234
- label: "Current Password",
1235
- name: "currentPassword"
1236
- }, {
1237
- default: withCtx(() => [
1238
- createVNode(_component_UInput, {
1239
- modelValue: unref(passwordState).currentPassword,
1240
- "onUpdate:modelValue": ($event) => unref(passwordState).currentPassword = $event,
1241
- type: "password",
1242
- class: "w-full"
1243
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1244
- ]),
1245
- _: 1
1246
- }),
1247
- createVNode(_component_UFormField, {
1248
- label: "New Password",
1249
- name: "newPassword"
1250
- }, {
1251
- default: withCtx(() => [
1252
- createVNode(_component_UInput, {
1253
- modelValue: unref(passwordState).newPassword,
1254
- "onUpdate:modelValue": ($event) => unref(passwordState).newPassword = $event,
1255
- type: "password",
1256
- class: "w-full"
1257
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1258
- ]),
1259
- _: 1
1260
- }),
1261
- createVNode(_component_UFormField, {
1262
- label: "Confirm New Password",
1263
- name: "confirmPassword"
1264
- }, {
1265
- default: withCtx(() => [
1266
- createVNode(_component_UInput, {
1267
- modelValue: unref(passwordState).confirmPassword,
1268
- "onUpdate:modelValue": ($event) => unref(passwordState).confirmPassword = $event,
1269
- type: "password",
1270
- class: "w-full"
1271
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
1272
- ]),
1273
- _: 1
1274
- }),
1275
- createVNode(_component_UButton, {
1276
- type: "submit",
1277
- loading: unref(passwordLoading)
1278
- }, {
1279
- default: withCtx(() => [
1280
- createTextVNode(" Change Password ")
1281
- ]),
1282
- _: 1
1283
- }, 8, ["loading"])
1284
- ]),
1285
- _: 1
1286
- }, 8, ["state"])
1287
- ])
1288
- ])
1289
- ]),
1290
- secrets: withCtx(() => [
1291
- createVNode("div", { class: "py-6" }, [
1292
- createVNode("div", { class: "flex items-center justify-between mb-6" }, [
1293
- createVNode("div", null, [
1294
- createVNode("h3", { class: "text-lg font-semibold" }, " Secrets "),
1295
- createVNode("p", { class: "text-sm text-dimmed" }, " Encrypted key-value store for skills and integrations. ")
1296
- ]),
1297
- createVNode(_component_UButton, {
1298
- icon: "i-lucide-plus",
1299
- onClick: openCreateSecret
1300
- }, {
1301
- default: withCtx(() => [
1302
- createTextVNode(" Add Secret ")
1303
- ]),
1304
- _: 1
1305
- })
1435
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1436
+ if (_push4) {
1437
+ _push4(ssrRenderComponent(_component_UInput, {
1438
+ modelValue: unref(bridgeConfigForm).botUsername,
1439
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).botUsername = $event,
1440
+ placeholder: "my_bot",
1441
+ class: "w-full"
1442
+ }, null, _parent4, _scopeId3));
1443
+ } else {
1444
+ return [
1445
+ createVNode(_component_UInput, {
1446
+ modelValue: unref(bridgeConfigForm).botUsername,
1447
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).botUsername = $event,
1448
+ placeholder: "my_bot",
1449
+ class: "w-full"
1450
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1451
+ ];
1452
+ }
1453
+ }),
1454
+ _: 1
1455
+ }, _parent3, _scopeId2));
1456
+ _push3(ssrRenderComponent(_component_UFormField, {
1457
+ label: "Allowed Chat IDs",
1458
+ name: "allowedChatIds",
1459
+ hint: "Comma-separated. Leave empty for all."
1460
+ }, {
1461
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1462
+ if (_push4) {
1463
+ _push4(ssrRenderComponent(_component_UInput, {
1464
+ modelValue: unref(bridgeConfigForm).allowedChatIds,
1465
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedChatIds = $event,
1466
+ placeholder: "123456, -100789",
1467
+ class: "w-full"
1468
+ }, null, _parent4, _scopeId3));
1469
+ } else {
1470
+ return [
1471
+ createVNode(_component_UInput, {
1472
+ modelValue: unref(bridgeConfigForm).allowedChatIds,
1473
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedChatIds = $event,
1474
+ placeholder: "123456, -100789",
1475
+ class: "w-full"
1476
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1477
+ ];
1478
+ }
1479
+ }),
1480
+ _: 1
1481
+ }, _parent3, _scopeId2));
1482
+ _push3(`<!--]-->`);
1483
+ } else {
1484
+ _push3(`<!---->`);
1485
+ }
1486
+ if (unref(editingBridge)?.platform === "discord") {
1487
+ _push3(`<!--[-->`);
1488
+ _push3(ssrRenderComponent(_component_UFormField, {
1489
+ label: "Listen Mode",
1490
+ name: "listenMode"
1491
+ }, {
1492
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1493
+ if (_push4) {
1494
+ _push4(ssrRenderComponent(_component_USelect, {
1495
+ modelValue: unref(bridgeConfigForm).listenMode,
1496
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).listenMode = $event,
1497
+ items: discordListenModeOptions,
1498
+ "value-key": "value",
1499
+ class: "w-full"
1500
+ }, null, _parent4, _scopeId3));
1501
+ } else {
1502
+ return [
1503
+ createVNode(_component_USelect, {
1504
+ modelValue: unref(bridgeConfigForm).listenMode,
1505
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).listenMode = $event,
1506
+ items: discordListenModeOptions,
1507
+ "value-key": "value",
1508
+ class: "w-full"
1509
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1510
+ ];
1511
+ }
1512
+ }),
1513
+ _: 1
1514
+ }, _parent3, _scopeId2));
1515
+ _push3(ssrRenderComponent(_component_UFormField, {
1516
+ label: "Server ID",
1517
+ name: "guildId",
1518
+ hint: "Optional. Limit to one server."
1519
+ }, {
1520
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1521
+ if (_push4) {
1522
+ _push4(ssrRenderComponent(_component_UInput, {
1523
+ modelValue: unref(bridgeConfigForm).guildId,
1524
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).guildId = $event,
1525
+ placeholder: "Discord server ID",
1526
+ class: "w-full"
1527
+ }, null, _parent4, _scopeId3));
1528
+ } else {
1529
+ return [
1530
+ createVNode(_component_UInput, {
1531
+ modelValue: unref(bridgeConfigForm).guildId,
1532
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).guildId = $event,
1533
+ placeholder: "Discord server ID",
1534
+ class: "w-full"
1535
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1536
+ ];
1537
+ }
1538
+ }),
1539
+ _: 1
1540
+ }, _parent3, _scopeId2));
1541
+ _push3(ssrRenderComponent(_component_UFormField, {
1542
+ label: "Channel ID",
1543
+ name: "channelId",
1544
+ hint: "Optional. Limit to one channel (for 'all' mode)."
1545
+ }, {
1546
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1547
+ if (_push4) {
1548
+ _push4(ssrRenderComponent(_component_UInput, {
1549
+ modelValue: unref(bridgeConfigForm).channelId,
1550
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).channelId = $event,
1551
+ placeholder: "Discord channel ID",
1552
+ class: "w-full"
1553
+ }, null, _parent4, _scopeId3));
1554
+ } else {
1555
+ return [
1556
+ createVNode(_component_UInput, {
1557
+ modelValue: unref(bridgeConfigForm).channelId,
1558
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).channelId = $event,
1559
+ placeholder: "Discord channel ID",
1560
+ class: "w-full"
1561
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1562
+ ];
1563
+ }
1564
+ }),
1565
+ _: 1
1566
+ }, _parent3, _scopeId2));
1567
+ _push3(`<!--]-->`);
1568
+ } else {
1569
+ _push3(`<!---->`);
1570
+ }
1571
+ if (unref(editingBridge)?.platform === "imessage") {
1572
+ _push3(`<!--[-->`);
1573
+ _push3(ssrRenderComponent(_component_UFormField, {
1574
+ label: "Strategy",
1575
+ name: "strategy"
1576
+ }, {
1577
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1578
+ if (_push4) {
1579
+ _push4(ssrRenderComponent(_component_USelect, {
1580
+ modelValue: unref(bridgeConfigForm).strategy,
1581
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).strategy = $event,
1582
+ items: imessageStrategyOptions,
1583
+ "value-key": "value",
1584
+ class: "w-full"
1585
+ }, null, _parent4, _scopeId3));
1586
+ } else {
1587
+ return [
1588
+ createVNode(_component_USelect, {
1589
+ modelValue: unref(bridgeConfigForm).strategy,
1590
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).strategy = $event,
1591
+ items: imessageStrategyOptions,
1592
+ "value-key": "value",
1593
+ class: "w-full"
1594
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1595
+ ];
1596
+ }
1597
+ }),
1598
+ _: 1
1599
+ }, _parent3, _scopeId2));
1600
+ if (unref(bridgeConfigForm).strategy === "bluebubbles" && !unref(secretsData).some((s) => s.key === "BLUEBUBBLES_PASSWORD")) {
1601
+ _push3(`<div class="flex items-start gap-2 rounded-lg bg-error/10 border border-error/20 p-3 text-sm"${_scopeId2}>`);
1602
+ _push3(ssrRenderComponent(_component_UIcon, {
1603
+ name: "i-lucide-alert-triangle",
1604
+ class: "size-4 mt-0.5 text-error shrink-0"
1605
+ }, null, _parent3, _scopeId2));
1606
+ _push3(`<span class="text-dimmed"${_scopeId2}> BlueBubbles requires secret <code class="text-xs bg-elevated px-1.5 py-0.5 rounded"${_scopeId2}>BLUEBUBBLES_PASSWORD</code> in the Secrets tab. </span></div>`);
1607
+ } else {
1608
+ _push3(`<!---->`);
1609
+ }
1610
+ if (unref(bridgeConfigForm).strategy === "bluebubbles") {
1611
+ _push3(ssrRenderComponent(_component_UFormField, {
1612
+ label: "BlueBubbles URL",
1613
+ name: "blueBubblesUrl"
1614
+ }, {
1615
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1616
+ if (_push4) {
1617
+ _push4(ssrRenderComponent(_component_UInput, {
1618
+ modelValue: unref(bridgeConfigForm).blueBubblesUrl,
1619
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).blueBubblesUrl = $event,
1620
+ placeholder: "http://192.168.1.100:1234",
1621
+ class: "w-full"
1622
+ }, null, _parent4, _scopeId3));
1623
+ } else {
1624
+ return [
1625
+ createVNode(_component_UInput, {
1626
+ modelValue: unref(bridgeConfigForm).blueBubblesUrl,
1627
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).blueBubblesUrl = $event,
1628
+ placeholder: "http://192.168.1.100:1234",
1629
+ class: "w-full"
1630
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1631
+ ];
1632
+ }
1633
+ }),
1634
+ _: 1
1635
+ }, _parent3, _scopeId2));
1636
+ } else {
1637
+ _push3(`<!---->`);
1638
+ }
1639
+ _push3(ssrRenderComponent(_component_UFormField, {
1640
+ label: "Allowed Numbers",
1641
+ name: "allowedNumbers",
1642
+ hint: "Comma-separated. Leave empty for all."
1643
+ }, {
1644
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1645
+ if (_push4) {
1646
+ _push4(ssrRenderComponent(_component_UInput, {
1647
+ modelValue: unref(bridgeConfigForm).allowedNumbers,
1648
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedNumbers = $event,
1649
+ placeholder: "+15551234567, +15559876543",
1650
+ class: "w-full"
1651
+ }, null, _parent4, _scopeId3));
1652
+ } else {
1653
+ return [
1654
+ createVNode(_component_UInput, {
1655
+ modelValue: unref(bridgeConfigForm).allowedNumbers,
1656
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedNumbers = $event,
1657
+ placeholder: "+15551234567, +15559876543",
1658
+ class: "w-full"
1659
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1660
+ ];
1661
+ }
1662
+ }),
1663
+ _: 1
1664
+ }, _parent3, _scopeId2));
1665
+ _push3(`<!--]-->`);
1666
+ } else {
1667
+ _push3(`<!---->`);
1668
+ }
1669
+ if (unref(editingBridge)?.platform === "google") {
1670
+ _push3(`<!--[-->`);
1671
+ _push3(ssrRenderComponent(_component_UFormField, {
1672
+ label: "Enabled Services",
1673
+ name: "enabledServices"
1674
+ }, {
1675
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1676
+ if (_push4) {
1677
+ _push4(`<div class="space-y-2"${_scopeId3}><!--[-->`);
1678
+ ssrRenderList(googleServiceOptions, (svc) => {
1679
+ _push4(`<label class="flex items-center gap-2 cursor-pointer"${_scopeId3}><input type="checkbox"${ssrIncludeBooleanAttr(unref(bridgeConfigForm).enabledServices.includes(svc.value)) ? " checked" : ""} class="rounded"${_scopeId3}><span class="text-sm"${_scopeId3}>${ssrInterpolate(svc.label)}</span></label>`);
1680
+ });
1681
+ _push4(`<!--]--></div>`);
1682
+ } else {
1683
+ return [
1684
+ createVNode("div", { class: "space-y-2" }, [
1685
+ (openBlock(), createBlock(Fragment, null, renderList(googleServiceOptions, (svc) => {
1686
+ return createVNode("label", {
1687
+ key: svc.value,
1688
+ class: "flex items-center gap-2 cursor-pointer"
1689
+ }, [
1690
+ createVNode("input", {
1691
+ type: "checkbox",
1692
+ checked: unref(bridgeConfigForm).enabledServices.includes(svc.value),
1693
+ class: "rounded",
1694
+ onChange: ($event) => unref(bridgeConfigForm).enabledServices.includes(svc.value) ? unref(bridgeConfigForm).enabledServices = unref(bridgeConfigForm).enabledServices.filter((s) => s !== svc.value) : unref(bridgeConfigForm).enabledServices.push(svc.value)
1695
+ }, null, 40, ["checked", "onChange"]),
1696
+ createVNode("span", { class: "text-sm" }, toDisplayString(svc.label), 1)
1697
+ ]);
1698
+ }), 64))
1699
+ ])
1700
+ ];
1701
+ }
1702
+ }),
1703
+ _: 1
1704
+ }, _parent3, _scopeId2));
1705
+ _push3(ssrRenderComponent(_component_UFormField, {
1706
+ label: "Google Account",
1707
+ name: "account",
1708
+ hint: "Email used with gogcli"
1709
+ }, {
1710
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1711
+ if (_push4) {
1712
+ _push4(ssrRenderComponent(_component_UInput, {
1713
+ modelValue: unref(bridgeConfigForm).account,
1714
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).account = $event,
1715
+ placeholder: "user@gmail.com",
1716
+ class: "w-full"
1717
+ }, null, _parent4, _scopeId3));
1718
+ } else {
1719
+ return [
1720
+ createVNode(_component_UInput, {
1721
+ modelValue: unref(bridgeConfigForm).account,
1722
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).account = $event,
1723
+ placeholder: "user@gmail.com",
1724
+ class: "w-full"
1725
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1726
+ ];
1727
+ }
1728
+ }),
1729
+ _: 1
1730
+ }, _parent3, _scopeId2));
1731
+ _push3(`<!--]-->`);
1732
+ } else {
1733
+ _push3(`<!---->`);
1734
+ }
1735
+ if (unref(editingBridge)?.platform === "email") {
1736
+ _push3(`<!--[-->`);
1737
+ _push3(ssrRenderComponent(_component_UFormField, {
1738
+ label: "Email Address",
1739
+ name: "emailAddress"
1740
+ }, {
1741
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1742
+ if (_push4) {
1743
+ _push4(ssrRenderComponent(_component_UInput, {
1744
+ modelValue: unref(bridgeConfigForm).emailAddress,
1745
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).emailAddress = $event,
1746
+ placeholder: "user@example.com",
1747
+ class: "w-full"
1748
+ }, null, _parent4, _scopeId3));
1749
+ } else {
1750
+ return [
1751
+ createVNode(_component_UInput, {
1752
+ modelValue: unref(bridgeConfigForm).emailAddress,
1753
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).emailAddress = $event,
1754
+ placeholder: "user@example.com",
1755
+ class: "w-full"
1756
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1757
+ ];
1758
+ }
1759
+ }),
1760
+ _: 1
1761
+ }, _parent3, _scopeId2));
1762
+ _push3(`<div class="grid grid-cols-2 gap-4"${_scopeId2}>`);
1763
+ _push3(ssrRenderComponent(_component_UFormField, {
1764
+ label: "IMAP Host",
1765
+ name: "imapHost"
1766
+ }, {
1767
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1768
+ if (_push4) {
1769
+ _push4(ssrRenderComponent(_component_UInput, {
1770
+ modelValue: unref(bridgeConfigForm).imapHost,
1771
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapHost = $event,
1772
+ placeholder: "imap.example.com",
1773
+ class: "w-full"
1774
+ }, null, _parent4, _scopeId3));
1775
+ } else {
1776
+ return [
1777
+ createVNode(_component_UInput, {
1778
+ modelValue: unref(bridgeConfigForm).imapHost,
1779
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapHost = $event,
1780
+ placeholder: "imap.example.com",
1781
+ class: "w-full"
1782
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1783
+ ];
1784
+ }
1785
+ }),
1786
+ _: 1
1787
+ }, _parent3, _scopeId2));
1788
+ _push3(ssrRenderComponent(_component_UFormField, {
1789
+ label: "IMAP Port",
1790
+ name: "imapPort"
1791
+ }, {
1792
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1793
+ if (_push4) {
1794
+ _push4(ssrRenderComponent(_component_UInput, {
1795
+ modelValue: unref(bridgeConfigForm).imapPort,
1796
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapPort = $event,
1797
+ placeholder: "993",
1798
+ class: "w-full"
1799
+ }, null, _parent4, _scopeId3));
1800
+ } else {
1801
+ return [
1802
+ createVNode(_component_UInput, {
1803
+ modelValue: unref(bridgeConfigForm).imapPort,
1804
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapPort = $event,
1805
+ placeholder: "993",
1806
+ class: "w-full"
1807
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1808
+ ];
1809
+ }
1810
+ }),
1811
+ _: 1
1812
+ }, _parent3, _scopeId2));
1813
+ _push3(`</div><div class="grid grid-cols-2 gap-4"${_scopeId2}>`);
1814
+ _push3(ssrRenderComponent(_component_UFormField, {
1815
+ label: "SMTP Host",
1816
+ name: "smtpHost"
1817
+ }, {
1818
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1819
+ if (_push4) {
1820
+ _push4(ssrRenderComponent(_component_UInput, {
1821
+ modelValue: unref(bridgeConfigForm).smtpHost,
1822
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpHost = $event,
1823
+ placeholder: "smtp.example.com",
1824
+ class: "w-full"
1825
+ }, null, _parent4, _scopeId3));
1826
+ } else {
1827
+ return [
1828
+ createVNode(_component_UInput, {
1829
+ modelValue: unref(bridgeConfigForm).smtpHost,
1830
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpHost = $event,
1831
+ placeholder: "smtp.example.com",
1832
+ class: "w-full"
1833
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1834
+ ];
1835
+ }
1836
+ }),
1837
+ _: 1
1838
+ }, _parent3, _scopeId2));
1839
+ _push3(ssrRenderComponent(_component_UFormField, {
1840
+ label: "SMTP Port",
1841
+ name: "smtpPort"
1842
+ }, {
1843
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1844
+ if (_push4) {
1845
+ _push4(ssrRenderComponent(_component_UInput, {
1846
+ modelValue: unref(bridgeConfigForm).smtpPort,
1847
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpPort = $event,
1848
+ placeholder: "587",
1849
+ class: "w-full"
1850
+ }, null, _parent4, _scopeId3));
1851
+ } else {
1852
+ return [
1853
+ createVNode(_component_UInput, {
1854
+ modelValue: unref(bridgeConfigForm).smtpPort,
1855
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpPort = $event,
1856
+ placeholder: "587",
1857
+ class: "w-full"
1858
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1859
+ ];
1860
+ }
1861
+ }),
1862
+ _: 1
1863
+ }, _parent3, _scopeId2));
1864
+ _push3(`</div><!--]-->`);
1865
+ } else {
1866
+ _push3(`<!---->`);
1867
+ }
1868
+ _push3(`<div class="flex justify-end gap-2 pt-4"${_scopeId2}>`);
1869
+ _push3(ssrRenderComponent(_component_UButton, {
1870
+ variant: "ghost",
1871
+ onClick: ($event) => bridgeConfigModal.value = false
1872
+ }, {
1873
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1874
+ if (_push4) {
1875
+ _push4(` Cancel `);
1876
+ } else {
1877
+ return [
1878
+ createTextVNode(" Cancel ")
1879
+ ];
1880
+ }
1881
+ }),
1882
+ _: 1
1883
+ }, _parent3, _scopeId2));
1884
+ _push3(ssrRenderComponent(_component_UButton, {
1885
+ loading: unref(bridgeConfigSaving),
1886
+ onClick: handleBridgeConfigSave
1887
+ }, {
1888
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
1889
+ if (_push4) {
1890
+ _push4(` Save `);
1891
+ } else {
1892
+ return [
1893
+ createTextVNode(" Save ")
1894
+ ];
1895
+ }
1896
+ }),
1897
+ _: 1
1898
+ }, _parent3, _scopeId2));
1899
+ _push3(`</div></div>`);
1900
+ } else {
1901
+ return [
1902
+ createVNode("div", { class: "space-y-4" }, [
1903
+ unref(editingBridge) && platformRequiredSecrets[unref(editingBridge).platform].length ? (openBlock(), createBlock("div", {
1904
+ key: 0,
1905
+ class: "flex items-start gap-2 rounded-lg bg-elevated p-3 text-sm"
1906
+ }, [
1907
+ createVNode(_component_UIcon, {
1908
+ name: "i-lucide-info",
1909
+ class: "size-4 mt-0.5 text-dimmed shrink-0"
1910
+ }),
1911
+ createVNode("span", { class: "text-dimmed" }, [
1912
+ createTextVNode(" Requires "),
1913
+ (openBlock(true), createBlock(Fragment, null, renderList(platformRequiredSecrets[unref(editingBridge).platform], (key, i) => {
1914
+ return openBlock(), createBlock(Fragment, { key }, [
1915
+ createVNode("code", { class: "bg-elevated px-1 py-0.5 rounded text-xs" }, toDisplayString(key), 1),
1916
+ i < platformRequiredSecrets[unref(editingBridge).platform].length - 1 ? (openBlock(), createBlock(Fragment, { key: 0 }, [
1917
+ createTextVNode(", ")
1918
+ ], 64)) : createCommentVNode("", true)
1919
+ ], 64);
1920
+ }), 128)),
1921
+ createTextVNode(" in the Secrets tab. ")
1922
+ ])
1923
+ ])) : createCommentVNode("", true),
1924
+ createVNode(_component_UFormField, {
1925
+ label: "Name",
1926
+ name: "name"
1927
+ }, {
1928
+ default: withCtx(() => [
1929
+ createVNode(_component_UInput, {
1930
+ modelValue: unref(bridgeConfigForm).name,
1931
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).name = $event,
1932
+ placeholder: "Integration name",
1933
+ class: "w-full"
1934
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1935
+ ]),
1936
+ _: 1
1937
+ }),
1938
+ unref(editingBridge)?.platform === "telegram" ? (openBlock(), createBlock(Fragment, { key: 1 }, [
1939
+ createVNode(_component_UFormField, {
1940
+ label: "Bot Username",
1941
+ name: "botUsername",
1942
+ hint: "Without the @ prefix"
1943
+ }, {
1944
+ default: withCtx(() => [
1945
+ createVNode(_component_UInput, {
1946
+ modelValue: unref(bridgeConfigForm).botUsername,
1947
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).botUsername = $event,
1948
+ placeholder: "my_bot",
1949
+ class: "w-full"
1950
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1951
+ ]),
1952
+ _: 1
1953
+ }),
1954
+ createVNode(_component_UFormField, {
1955
+ label: "Allowed Chat IDs",
1956
+ name: "allowedChatIds",
1957
+ hint: "Comma-separated. Leave empty for all."
1958
+ }, {
1959
+ default: withCtx(() => [
1960
+ createVNode(_component_UInput, {
1961
+ modelValue: unref(bridgeConfigForm).allowedChatIds,
1962
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedChatIds = $event,
1963
+ placeholder: "123456, -100789",
1964
+ class: "w-full"
1965
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1966
+ ]),
1967
+ _: 1
1968
+ })
1969
+ ], 64)) : createCommentVNode("", true),
1970
+ unref(editingBridge)?.platform === "discord" ? (openBlock(), createBlock(Fragment, { key: 2 }, [
1971
+ createVNode(_component_UFormField, {
1972
+ label: "Listen Mode",
1973
+ name: "listenMode"
1974
+ }, {
1975
+ default: withCtx(() => [
1976
+ createVNode(_component_USelect, {
1977
+ modelValue: unref(bridgeConfigForm).listenMode,
1978
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).listenMode = $event,
1979
+ items: discordListenModeOptions,
1980
+ "value-key": "value",
1981
+ class: "w-full"
1982
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1983
+ ]),
1984
+ _: 1
1985
+ }),
1986
+ createVNode(_component_UFormField, {
1987
+ label: "Server ID",
1988
+ name: "guildId",
1989
+ hint: "Optional. Limit to one server."
1990
+ }, {
1991
+ default: withCtx(() => [
1992
+ createVNode(_component_UInput, {
1993
+ modelValue: unref(bridgeConfigForm).guildId,
1994
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).guildId = $event,
1995
+ placeholder: "Discord server ID",
1996
+ class: "w-full"
1997
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1998
+ ]),
1999
+ _: 1
2000
+ }),
2001
+ createVNode(_component_UFormField, {
2002
+ label: "Channel ID",
2003
+ name: "channelId",
2004
+ hint: "Optional. Limit to one channel (for 'all' mode)."
2005
+ }, {
2006
+ default: withCtx(() => [
2007
+ createVNode(_component_UInput, {
2008
+ modelValue: unref(bridgeConfigForm).channelId,
2009
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).channelId = $event,
2010
+ placeholder: "Discord channel ID",
2011
+ class: "w-full"
2012
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2013
+ ]),
2014
+ _: 1
2015
+ })
2016
+ ], 64)) : createCommentVNode("", true),
2017
+ unref(editingBridge)?.platform === "imessage" ? (openBlock(), createBlock(Fragment, { key: 3 }, [
2018
+ createVNode(_component_UFormField, {
2019
+ label: "Strategy",
2020
+ name: "strategy"
2021
+ }, {
2022
+ default: withCtx(() => [
2023
+ createVNode(_component_USelect, {
2024
+ modelValue: unref(bridgeConfigForm).strategy,
2025
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).strategy = $event,
2026
+ items: imessageStrategyOptions,
2027
+ "value-key": "value",
2028
+ class: "w-full"
2029
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2030
+ ]),
2031
+ _: 1
2032
+ }),
2033
+ unref(bridgeConfigForm).strategy === "bluebubbles" && !unref(secretsData).some((s) => s.key === "BLUEBUBBLES_PASSWORD") ? (openBlock(), createBlock("div", {
2034
+ key: 0,
2035
+ class: "flex items-start gap-2 rounded-lg bg-error/10 border border-error/20 p-3 text-sm"
2036
+ }, [
2037
+ createVNode(_component_UIcon, {
2038
+ name: "i-lucide-alert-triangle",
2039
+ class: "size-4 mt-0.5 text-error shrink-0"
2040
+ }),
2041
+ createVNode("span", { class: "text-dimmed" }, [
2042
+ createTextVNode(" BlueBubbles requires secret "),
2043
+ createVNode("code", { class: "text-xs bg-elevated px-1.5 py-0.5 rounded" }, "BLUEBUBBLES_PASSWORD"),
2044
+ createTextVNode(" in the Secrets tab. ")
2045
+ ])
2046
+ ])) : createCommentVNode("", true),
2047
+ unref(bridgeConfigForm).strategy === "bluebubbles" ? (openBlock(), createBlock(_component_UFormField, {
2048
+ key: 1,
2049
+ label: "BlueBubbles URL",
2050
+ name: "blueBubblesUrl"
2051
+ }, {
2052
+ default: withCtx(() => [
2053
+ createVNode(_component_UInput, {
2054
+ modelValue: unref(bridgeConfigForm).blueBubblesUrl,
2055
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).blueBubblesUrl = $event,
2056
+ placeholder: "http://192.168.1.100:1234",
2057
+ class: "w-full"
2058
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2059
+ ]),
2060
+ _: 1
2061
+ })) : createCommentVNode("", true),
2062
+ createVNode(_component_UFormField, {
2063
+ label: "Allowed Numbers",
2064
+ name: "allowedNumbers",
2065
+ hint: "Comma-separated. Leave empty for all."
2066
+ }, {
2067
+ default: withCtx(() => [
2068
+ createVNode(_component_UInput, {
2069
+ modelValue: unref(bridgeConfigForm).allowedNumbers,
2070
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedNumbers = $event,
2071
+ placeholder: "+15551234567, +15559876543",
2072
+ class: "w-full"
2073
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2074
+ ]),
2075
+ _: 1
2076
+ })
2077
+ ], 64)) : createCommentVNode("", true),
2078
+ unref(editingBridge)?.platform === "google" ? (openBlock(), createBlock(Fragment, { key: 4 }, [
2079
+ createVNode(_component_UFormField, {
2080
+ label: "Enabled Services",
2081
+ name: "enabledServices"
2082
+ }, {
2083
+ default: withCtx(() => [
2084
+ createVNode("div", { class: "space-y-2" }, [
2085
+ (openBlock(), createBlock(Fragment, null, renderList(googleServiceOptions, (svc) => {
2086
+ return createVNode("label", {
2087
+ key: svc.value,
2088
+ class: "flex items-center gap-2 cursor-pointer"
2089
+ }, [
2090
+ createVNode("input", {
2091
+ type: "checkbox",
2092
+ checked: unref(bridgeConfigForm).enabledServices.includes(svc.value),
2093
+ class: "rounded",
2094
+ onChange: ($event) => unref(bridgeConfigForm).enabledServices.includes(svc.value) ? unref(bridgeConfigForm).enabledServices = unref(bridgeConfigForm).enabledServices.filter((s) => s !== svc.value) : unref(bridgeConfigForm).enabledServices.push(svc.value)
2095
+ }, null, 40, ["checked", "onChange"]),
2096
+ createVNode("span", { class: "text-sm" }, toDisplayString(svc.label), 1)
2097
+ ]);
2098
+ }), 64))
2099
+ ])
2100
+ ]),
2101
+ _: 1
2102
+ }),
2103
+ createVNode(_component_UFormField, {
2104
+ label: "Google Account",
2105
+ name: "account",
2106
+ hint: "Email used with gogcli"
2107
+ }, {
2108
+ default: withCtx(() => [
2109
+ createVNode(_component_UInput, {
2110
+ modelValue: unref(bridgeConfigForm).account,
2111
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).account = $event,
2112
+ placeholder: "user@gmail.com",
2113
+ class: "w-full"
2114
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2115
+ ]),
2116
+ _: 1
2117
+ })
2118
+ ], 64)) : createCommentVNode("", true),
2119
+ unref(editingBridge)?.platform === "email" ? (openBlock(), createBlock(Fragment, { key: 5 }, [
2120
+ createVNode(_component_UFormField, {
2121
+ label: "Email Address",
2122
+ name: "emailAddress"
2123
+ }, {
2124
+ default: withCtx(() => [
2125
+ createVNode(_component_UInput, {
2126
+ modelValue: unref(bridgeConfigForm).emailAddress,
2127
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).emailAddress = $event,
2128
+ placeholder: "user@example.com",
2129
+ class: "w-full"
2130
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2131
+ ]),
2132
+ _: 1
2133
+ }),
2134
+ createVNode("div", { class: "grid grid-cols-2 gap-4" }, [
2135
+ createVNode(_component_UFormField, {
2136
+ label: "IMAP Host",
2137
+ name: "imapHost"
2138
+ }, {
2139
+ default: withCtx(() => [
2140
+ createVNode(_component_UInput, {
2141
+ modelValue: unref(bridgeConfigForm).imapHost,
2142
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapHost = $event,
2143
+ placeholder: "imap.example.com",
2144
+ class: "w-full"
2145
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2146
+ ]),
2147
+ _: 1
2148
+ }),
2149
+ createVNode(_component_UFormField, {
2150
+ label: "IMAP Port",
2151
+ name: "imapPort"
2152
+ }, {
2153
+ default: withCtx(() => [
2154
+ createVNode(_component_UInput, {
2155
+ modelValue: unref(bridgeConfigForm).imapPort,
2156
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapPort = $event,
2157
+ placeholder: "993",
2158
+ class: "w-full"
2159
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2160
+ ]),
2161
+ _: 1
2162
+ })
2163
+ ]),
2164
+ createVNode("div", { class: "grid grid-cols-2 gap-4" }, [
2165
+ createVNode(_component_UFormField, {
2166
+ label: "SMTP Host",
2167
+ name: "smtpHost"
2168
+ }, {
2169
+ default: withCtx(() => [
2170
+ createVNode(_component_UInput, {
2171
+ modelValue: unref(bridgeConfigForm).smtpHost,
2172
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpHost = $event,
2173
+ placeholder: "smtp.example.com",
2174
+ class: "w-full"
2175
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2176
+ ]),
2177
+ _: 1
2178
+ }),
2179
+ createVNode(_component_UFormField, {
2180
+ label: "SMTP Port",
2181
+ name: "smtpPort"
2182
+ }, {
2183
+ default: withCtx(() => [
2184
+ createVNode(_component_UInput, {
2185
+ modelValue: unref(bridgeConfigForm).smtpPort,
2186
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpPort = $event,
2187
+ placeholder: "587",
2188
+ class: "w-full"
2189
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2190
+ ]),
2191
+ _: 1
2192
+ })
2193
+ ])
2194
+ ], 64)) : createCommentVNode("", true),
2195
+ createVNode("div", { class: "flex justify-end gap-2 pt-4" }, [
2196
+ createVNode(_component_UButton, {
2197
+ variant: "ghost",
2198
+ onClick: ($event) => bridgeConfigModal.value = false
2199
+ }, {
2200
+ default: withCtx(() => [
2201
+ createTextVNode(" Cancel ")
2202
+ ]),
2203
+ _: 1
2204
+ }, 8, ["onClick"]),
2205
+ createVNode(_component_UButton, {
2206
+ loading: unref(bridgeConfigSaving),
2207
+ onClick: handleBridgeConfigSave
2208
+ }, {
2209
+ default: withCtx(() => [
2210
+ createTextVNode(" Save ")
2211
+ ]),
2212
+ _: 1
2213
+ }, 8, ["loading"])
2214
+ ])
2215
+ ])
2216
+ ];
2217
+ }
2218
+ }),
2219
+ _: 1
2220
+ }, _parent2, _scopeId));
2221
+ } else {
2222
+ return [
2223
+ createVNode(_component_UDashboardNavbar, { title: "Settings" }, {
2224
+ right: withCtx(() => [
2225
+ createVNode(_component_UColorModeButton)
2226
+ ]),
2227
+ _: 1
2228
+ }),
2229
+ createVNode("div", { class: "p-6" }, [
2230
+ createVNode(_component_ClientOnly, null, {
2231
+ fallback: withCtx(() => [
2232
+ createVNode("div", { class: "space-y-8 max-w-xl mx-auto py-6" }, [
2233
+ createVNode(_component_USkeleton, { class: "h-10 w-full" }),
2234
+ createVNode("div", { class: "space-y-4" }, [
2235
+ createVNode(_component_USkeleton, { class: "h-5 w-20" }),
2236
+ createVNode(_component_USkeleton, { class: "h-10 w-full" }),
2237
+ createVNode(_component_USkeleton, { class: "h-10 w-28" })
2238
+ ])
2239
+ ])
2240
+ ]),
2241
+ default: withCtx(() => [
2242
+ createVNode(_component_UTabs, {
2243
+ items: tabs,
2244
+ "default-value": "account",
2245
+ class: "w-full mx-auto",
2246
+ ui: { list: "max-w-xl" }
2247
+ }, {
2248
+ account: withCtx(() => [
2249
+ createVNode("div", { class: "space-y-8 max-w-2xl mx-auto py-6" }, [
2250
+ createVNode("div", null, [
2251
+ createVNode("h3", { class: "text-lg font-semibold mb-4" }, " Profile "),
2252
+ createVNode(_component_UForm, {
2253
+ state: unref(profileState),
2254
+ class: "space-y-4",
2255
+ onSubmit: handleProfileSubmit
2256
+ }, {
2257
+ default: withCtx(() => [
2258
+ createVNode(_component_UFormField, {
2259
+ label: "Name",
2260
+ name: "name"
2261
+ }, {
2262
+ default: withCtx(() => [
2263
+ createVNode(_component_UInput, {
2264
+ modelValue: unref(profileState).name,
2265
+ "onUpdate:modelValue": ($event) => unref(profileState).name = $event,
2266
+ placeholder: "Your name",
2267
+ class: "w-full"
2268
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2269
+ ]),
2270
+ _: 1
2271
+ }),
2272
+ createVNode(_component_UButton, {
2273
+ type: "submit",
2274
+ loading: unref(profileLoading)
2275
+ }, {
2276
+ default: withCtx(() => [
2277
+ createTextVNode(" Save Name ")
2278
+ ]),
2279
+ _: 1
2280
+ }, 8, ["loading"])
2281
+ ]),
2282
+ _: 1
2283
+ }, 8, ["state"])
2284
+ ]),
2285
+ createVNode(_component_USeparator),
2286
+ createVNode("div", null, [
2287
+ createVNode("h3", { class: "text-lg font-semibold mb-4" }, " Email Address "),
2288
+ createVNode(_component_UForm, {
2289
+ state: unref(emailState),
2290
+ class: "space-y-4",
2291
+ onSubmit: handleEmailSubmit
2292
+ }, {
2293
+ default: withCtx(() => [
2294
+ createVNode(_component_UFormField, {
2295
+ label: "Email",
2296
+ name: "newEmail"
2297
+ }, {
2298
+ default: withCtx(() => [
2299
+ createVNode(_component_UInput, {
2300
+ modelValue: unref(emailState).newEmail,
2301
+ "onUpdate:modelValue": ($event) => unref(emailState).newEmail = $event,
2302
+ type: "email",
2303
+ placeholder: "your@email.com",
2304
+ class: "w-full"
2305
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2306
+ ]),
2307
+ _: 1
2308
+ }),
2309
+ createVNode(_component_UButton, {
2310
+ type: "submit",
2311
+ loading: unref(emailLoading)
2312
+ }, {
2313
+ default: withCtx(() => [
2314
+ createTextVNode(" Change Email ")
2315
+ ]),
2316
+ _: 1
2317
+ }, 8, ["loading"])
2318
+ ]),
2319
+ _: 1
2320
+ }, 8, ["state"])
2321
+ ]),
2322
+ createVNode(_component_USeparator),
2323
+ createVNode("div", null, [
2324
+ createVNode("h3", { class: "text-lg font-semibold mb-4" }, " Change Password "),
2325
+ createVNode(_component_UForm, {
2326
+ state: unref(passwordState),
2327
+ class: "space-y-4",
2328
+ onSubmit: handlePasswordSubmit
2329
+ }, {
2330
+ default: withCtx(() => [
2331
+ createVNode(_component_UFormField, {
2332
+ label: "Current Password",
2333
+ name: "currentPassword"
2334
+ }, {
2335
+ default: withCtx(() => [
2336
+ createVNode(_component_UInput, {
2337
+ modelValue: unref(passwordState).currentPassword,
2338
+ "onUpdate:modelValue": ($event) => unref(passwordState).currentPassword = $event,
2339
+ type: "password",
2340
+ class: "w-full"
2341
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2342
+ ]),
2343
+ _: 1
2344
+ }),
2345
+ createVNode(_component_UFormField, {
2346
+ label: "New Password",
2347
+ name: "newPassword"
2348
+ }, {
2349
+ default: withCtx(() => [
2350
+ createVNode(_component_UInput, {
2351
+ modelValue: unref(passwordState).newPassword,
2352
+ "onUpdate:modelValue": ($event) => unref(passwordState).newPassword = $event,
2353
+ type: "password",
2354
+ class: "w-full"
2355
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2356
+ ]),
2357
+ _: 1
2358
+ }),
2359
+ createVNode(_component_UFormField, {
2360
+ label: "Confirm New Password",
2361
+ name: "confirmPassword"
2362
+ }, {
2363
+ default: withCtx(() => [
2364
+ createVNode(_component_UInput, {
2365
+ modelValue: unref(passwordState).confirmPassword,
2366
+ "onUpdate:modelValue": ($event) => unref(passwordState).confirmPassword = $event,
2367
+ type: "password",
2368
+ class: "w-full"
2369
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2370
+ ]),
2371
+ _: 1
2372
+ }),
2373
+ createVNode(_component_UButton, {
2374
+ type: "submit",
2375
+ loading: unref(passwordLoading)
2376
+ }, {
2377
+ default: withCtx(() => [
2378
+ createTextVNode(" Change Password ")
2379
+ ]),
2380
+ _: 1
2381
+ }, 8, ["loading"])
2382
+ ]),
2383
+ _: 1
2384
+ }, 8, ["state"])
2385
+ ])
2386
+ ])
2387
+ ]),
2388
+ secrets: withCtx(() => [
2389
+ createVNode("div", { class: "py-6" }, [
2390
+ createVNode("div", { class: "flex items-center justify-between mb-6" }, [
2391
+ createVNode("div", null, [
2392
+ createVNode("h3", { class: "text-lg font-semibold" }, " Secrets "),
2393
+ createVNode("p", { class: "text-sm text-dimmed" }, " Encrypted key-value store for skills and integrations. ")
2394
+ ]),
2395
+ createVNode(_component_UButton, {
2396
+ icon: "i-lucide-plus",
2397
+ onClick: openCreateSecret
2398
+ }, {
2399
+ default: withCtx(() => [
2400
+ createTextVNode(" Add Secret ")
2401
+ ]),
2402
+ _: 1
2403
+ })
1306
2404
  ]),
1307
2405
  createVNode(_component_UTable, {
1308
2406
  columns: secretColumns,
@@ -1392,7 +2490,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1392
2490
  (openBlock(true), createBlock(Fragment, null, renderList(unref(bridgesData), (bridge) => {
1393
2491
  return openBlock(), createBlock("div", {
1394
2492
  key: bridge.id,
1395
- class: "border border-default rounded-lg px-4 py-3"
2493
+ class: "border border-default rounded-lg px-4 py-3 cursor-pointer hover:bg-elevated/50 transition-colors",
2494
+ onClick: ($event) => openBridgeConfig(bridge)
1396
2495
  }, [
1397
2496
  createVNode("div", { class: "flex items-center justify-between" }, [
1398
2497
  createVNode("div", { class: "flex items-center gap-3" }, [
@@ -1411,14 +2510,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1411
2510
  }, toDisplayString(bridge.healthStatus), 3),
1412
2511
  createVNode(_component_USwitch, {
1413
2512
  "model-value": bridge.enabled,
2513
+ onClick: withModifiers(() => {
2514
+ }, ["stop"]),
1414
2515
  "onUpdate:modelValue": ($event) => toggleBridge(bridge)
1415
- }, null, 8, ["model-value", "onUpdate:modelValue"]),
2516
+ }, null, 8, ["model-value", "onClick", "onUpdate:modelValue"]),
1416
2517
  createVNode(_component_UButton, {
1417
2518
  variant: "ghost",
1418
2519
  color: "error",
1419
2520
  icon: "i-lucide-trash-2",
1420
2521
  size: "xs",
1421
- onClick: ($event) => confirmDeleteBridge(bridge)
2522
+ onClick: withModifiers(($event) => confirmDeleteBridge(bridge), ["stop"])
1422
2523
  }, null, 8, ["onClick"])
1423
2524
  ])
1424
2525
  ]),
@@ -1426,13 +2527,36 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1426
2527
  key: 0,
1427
2528
  class: "text-xs text-dimmed mt-1 pl-8"
1428
2529
  }, toDisplayString(bridge.healthMessage), 1)) : createCommentVNode("", true)
1429
- ]);
2530
+ ], 8, ["onClick"]);
1430
2531
  }), 128))
1431
2532
  ]))
1432
2533
  ])
1433
2534
  ]),
1434
2535
  app: withCtx(() => [
1435
2536
  createVNode("div", { class: "max-w-2xl mx-auto py-6" }, [
2537
+ createVNode("div", { class: "mb-8" }, [
2538
+ createVNode("h3", { class: "text-lg font-semibold mb-1" }, " Public URL "),
2539
+ createVNode("p", { class: "text-sm text-dimmed mb-4" }, " The publicly accessible URL for this instance. Used for Telegram webhooks, auth callbacks, and other integrations that need to reach your server. "),
2540
+ createVNode("div", { class: "flex gap-2" }, [
2541
+ createVNode(_component_UInput, {
2542
+ modelValue: unref(appUrl),
2543
+ "onUpdate:modelValue": ($event) => isRef(appUrl) ? appUrl.value = $event : null,
2544
+ placeholder: "https://example.com",
2545
+ class: "flex-1"
2546
+ }, null, 8, ["modelValue", "onUpdate:modelValue"]),
2547
+ createVNode(_component_UButton, {
2548
+ loading: unref(appUrlSaving),
2549
+ onClick: saveAppUrl
2550
+ }, {
2551
+ default: withCtx(() => [
2552
+ createTextVNode(" Save ")
2553
+ ]),
2554
+ _: 1
2555
+ }, 8, ["loading"])
2556
+ ]),
2557
+ createVNode("p", { class: "text-xs text-dimmed mt-2" }, " Leave empty to use long-polling for Telegram instead of webhooks. Changes require restarting running integrations. ")
2558
+ ]),
2559
+ createVNode(_component_USeparator, { class: "mb-8" }),
1436
2560
  createVNode("div", { class: "mb-6" }, [
1437
2561
  createVNode("h3", { class: "text-lg font-semibold mb-1" }, " Notification Preferences "),
1438
2562
  createVNode("p", { class: "text-sm text-dimmed" }, " Choose which resource changes show toast notifications. ")
@@ -1662,6 +2786,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1662
2786
  ]),
1663
2787
  _: 1
1664
2788
  }),
2789
+ getMissingSecrets(unref(bridgeForm).platform).length ? (openBlock(), createBlock("div", {
2790
+ key: 0,
2791
+ class: "flex items-start gap-2 rounded-lg bg-error/10 border border-error/20 p-3 text-sm"
2792
+ }, [
2793
+ createVNode(_component_UIcon, {
2794
+ name: "i-lucide-alert-triangle",
2795
+ class: "size-4 mt-0.5 text-error shrink-0"
2796
+ }),
2797
+ createVNode("div", null, [
2798
+ createVNode("p", { class: "font-medium text-error" }, " Missing required secrets "),
2799
+ createVNode("p", { class: "text-dimmed mt-1" }, " Add the following in Settings → Secrets before creating: "),
2800
+ createVNode("ul", { class: "mt-1 space-y-0.5" }, [
2801
+ (openBlock(true), createBlock(Fragment, null, renderList(getMissingSecrets(unref(bridgeForm).platform), (key) => {
2802
+ return openBlock(), createBlock("li", { key }, [
2803
+ createVNode("code", { class: "text-xs bg-elevated px-1.5 py-0.5 rounded" }, toDisplayString(key), 1)
2804
+ ]);
2805
+ }), 128))
2806
+ ])
2807
+ ])
2808
+ ])) : createCommentVNode("", true),
1665
2809
  createVNode(_component_UFormField, {
1666
2810
  label: "Name",
1667
2811
  name: "name"
@@ -1670,9 +2814,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1670
2814
  createVNode(_component_UInput, {
1671
2815
  modelValue: unref(bridgeForm).name,
1672
2816
  "onUpdate:modelValue": ($event) => unref(bridgeForm).name = $event,
1673
- placeholder: "My Telegram Bot",
2817
+ placeholder: platformNamePlaceholders[unref(bridgeForm).platform],
1674
2818
  class: "w-full"
1675
- }, null, 8, ["modelValue", "onUpdate:modelValue"])
2819
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "placeholder"])
1676
2820
  ]),
1677
2821
  _: 1
1678
2822
  }),
@@ -1688,13 +2832,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1688
2832
  }, 8, ["onClick"]),
1689
2833
  createVNode(_component_UButton, {
1690
2834
  loading: unref(bridgeSaving),
2835
+ disabled: getMissingSecrets(unref(bridgeForm).platform).length > 0,
1691
2836
  onClick: handleBridgeCreate
1692
2837
  }, {
1693
2838
  default: withCtx(() => [
1694
2839
  createTextVNode(" Create ")
1695
2840
  ]),
1696
2841
  _: 1
1697
- }, 8, ["loading"])
2842
+ }, 8, ["loading", "disabled"])
1698
2843
  ])
1699
2844
  ])
1700
2845
  ]),
@@ -1736,6 +2881,337 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1736
2881
  ])
1737
2882
  ]),
1738
2883
  _: 1
2884
+ }, 8, ["open", "onUpdate:open"]),
2885
+ createVNode(_component_UModal, {
2886
+ open: unref(bridgeConfigModal),
2887
+ "onUpdate:open": ($event) => isRef(bridgeConfigModal) ? bridgeConfigModal.value = $event : null
2888
+ }, {
2889
+ header: withCtx(() => [
2890
+ createVNode("div", { class: "flex items-center gap-2" }, [
2891
+ createVNode(_component_UIcon, {
2892
+ name: platformOptions.find((p) => p.value === unref(editingBridge)?.platform)?.icon || "i-lucide-plug",
2893
+ class: "size-5"
2894
+ }, null, 8, ["name"]),
2895
+ createVNode("h3", { class: "text-lg font-semibold" }, " Configure " + toDisplayString(unref(editingBridge)?.name), 1)
2896
+ ])
2897
+ ]),
2898
+ body: withCtx(() => [
2899
+ createVNode("div", { class: "space-y-4" }, [
2900
+ unref(editingBridge) && platformRequiredSecrets[unref(editingBridge).platform].length ? (openBlock(), createBlock("div", {
2901
+ key: 0,
2902
+ class: "flex items-start gap-2 rounded-lg bg-elevated p-3 text-sm"
2903
+ }, [
2904
+ createVNode(_component_UIcon, {
2905
+ name: "i-lucide-info",
2906
+ class: "size-4 mt-0.5 text-dimmed shrink-0"
2907
+ }),
2908
+ createVNode("span", { class: "text-dimmed" }, [
2909
+ createTextVNode(" Requires "),
2910
+ (openBlock(true), createBlock(Fragment, null, renderList(platformRequiredSecrets[unref(editingBridge).platform], (key, i) => {
2911
+ return openBlock(), createBlock(Fragment, { key }, [
2912
+ createVNode("code", { class: "bg-elevated px-1 py-0.5 rounded text-xs" }, toDisplayString(key), 1),
2913
+ i < platformRequiredSecrets[unref(editingBridge).platform].length - 1 ? (openBlock(), createBlock(Fragment, { key: 0 }, [
2914
+ createTextVNode(", ")
2915
+ ], 64)) : createCommentVNode("", true)
2916
+ ], 64);
2917
+ }), 128)),
2918
+ createTextVNode(" in the Secrets tab. ")
2919
+ ])
2920
+ ])) : createCommentVNode("", true),
2921
+ createVNode(_component_UFormField, {
2922
+ label: "Name",
2923
+ name: "name"
2924
+ }, {
2925
+ default: withCtx(() => [
2926
+ createVNode(_component_UInput, {
2927
+ modelValue: unref(bridgeConfigForm).name,
2928
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).name = $event,
2929
+ placeholder: "Integration name",
2930
+ class: "w-full"
2931
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2932
+ ]),
2933
+ _: 1
2934
+ }),
2935
+ unref(editingBridge)?.platform === "telegram" ? (openBlock(), createBlock(Fragment, { key: 1 }, [
2936
+ createVNode(_component_UFormField, {
2937
+ label: "Bot Username",
2938
+ name: "botUsername",
2939
+ hint: "Without the @ prefix"
2940
+ }, {
2941
+ default: withCtx(() => [
2942
+ createVNode(_component_UInput, {
2943
+ modelValue: unref(bridgeConfigForm).botUsername,
2944
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).botUsername = $event,
2945
+ placeholder: "my_bot",
2946
+ class: "w-full"
2947
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2948
+ ]),
2949
+ _: 1
2950
+ }),
2951
+ createVNode(_component_UFormField, {
2952
+ label: "Allowed Chat IDs",
2953
+ name: "allowedChatIds",
2954
+ hint: "Comma-separated. Leave empty for all."
2955
+ }, {
2956
+ default: withCtx(() => [
2957
+ createVNode(_component_UInput, {
2958
+ modelValue: unref(bridgeConfigForm).allowedChatIds,
2959
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedChatIds = $event,
2960
+ placeholder: "123456, -100789",
2961
+ class: "w-full"
2962
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2963
+ ]),
2964
+ _: 1
2965
+ })
2966
+ ], 64)) : createCommentVNode("", true),
2967
+ unref(editingBridge)?.platform === "discord" ? (openBlock(), createBlock(Fragment, { key: 2 }, [
2968
+ createVNode(_component_UFormField, {
2969
+ label: "Listen Mode",
2970
+ name: "listenMode"
2971
+ }, {
2972
+ default: withCtx(() => [
2973
+ createVNode(_component_USelect, {
2974
+ modelValue: unref(bridgeConfigForm).listenMode,
2975
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).listenMode = $event,
2976
+ items: discordListenModeOptions,
2977
+ "value-key": "value",
2978
+ class: "w-full"
2979
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2980
+ ]),
2981
+ _: 1
2982
+ }),
2983
+ createVNode(_component_UFormField, {
2984
+ label: "Server ID",
2985
+ name: "guildId",
2986
+ hint: "Optional. Limit to one server."
2987
+ }, {
2988
+ default: withCtx(() => [
2989
+ createVNode(_component_UInput, {
2990
+ modelValue: unref(bridgeConfigForm).guildId,
2991
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).guildId = $event,
2992
+ placeholder: "Discord server ID",
2993
+ class: "w-full"
2994
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2995
+ ]),
2996
+ _: 1
2997
+ }),
2998
+ createVNode(_component_UFormField, {
2999
+ label: "Channel ID",
3000
+ name: "channelId",
3001
+ hint: "Optional. Limit to one channel (for 'all' mode)."
3002
+ }, {
3003
+ default: withCtx(() => [
3004
+ createVNode(_component_UInput, {
3005
+ modelValue: unref(bridgeConfigForm).channelId,
3006
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).channelId = $event,
3007
+ placeholder: "Discord channel ID",
3008
+ class: "w-full"
3009
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3010
+ ]),
3011
+ _: 1
3012
+ })
3013
+ ], 64)) : createCommentVNode("", true),
3014
+ unref(editingBridge)?.platform === "imessage" ? (openBlock(), createBlock(Fragment, { key: 3 }, [
3015
+ createVNode(_component_UFormField, {
3016
+ label: "Strategy",
3017
+ name: "strategy"
3018
+ }, {
3019
+ default: withCtx(() => [
3020
+ createVNode(_component_USelect, {
3021
+ modelValue: unref(bridgeConfigForm).strategy,
3022
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).strategy = $event,
3023
+ items: imessageStrategyOptions,
3024
+ "value-key": "value",
3025
+ class: "w-full"
3026
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3027
+ ]),
3028
+ _: 1
3029
+ }),
3030
+ unref(bridgeConfigForm).strategy === "bluebubbles" && !unref(secretsData).some((s) => s.key === "BLUEBUBBLES_PASSWORD") ? (openBlock(), createBlock("div", {
3031
+ key: 0,
3032
+ class: "flex items-start gap-2 rounded-lg bg-error/10 border border-error/20 p-3 text-sm"
3033
+ }, [
3034
+ createVNode(_component_UIcon, {
3035
+ name: "i-lucide-alert-triangle",
3036
+ class: "size-4 mt-0.5 text-error shrink-0"
3037
+ }),
3038
+ createVNode("span", { class: "text-dimmed" }, [
3039
+ createTextVNode(" BlueBubbles requires secret "),
3040
+ createVNode("code", { class: "text-xs bg-elevated px-1.5 py-0.5 rounded" }, "BLUEBUBBLES_PASSWORD"),
3041
+ createTextVNode(" in the Secrets tab. ")
3042
+ ])
3043
+ ])) : createCommentVNode("", true),
3044
+ unref(bridgeConfigForm).strategy === "bluebubbles" ? (openBlock(), createBlock(_component_UFormField, {
3045
+ key: 1,
3046
+ label: "BlueBubbles URL",
3047
+ name: "blueBubblesUrl"
3048
+ }, {
3049
+ default: withCtx(() => [
3050
+ createVNode(_component_UInput, {
3051
+ modelValue: unref(bridgeConfigForm).blueBubblesUrl,
3052
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).blueBubblesUrl = $event,
3053
+ placeholder: "http://192.168.1.100:1234",
3054
+ class: "w-full"
3055
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3056
+ ]),
3057
+ _: 1
3058
+ })) : createCommentVNode("", true),
3059
+ createVNode(_component_UFormField, {
3060
+ label: "Allowed Numbers",
3061
+ name: "allowedNumbers",
3062
+ hint: "Comma-separated. Leave empty for all."
3063
+ }, {
3064
+ default: withCtx(() => [
3065
+ createVNode(_component_UInput, {
3066
+ modelValue: unref(bridgeConfigForm).allowedNumbers,
3067
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).allowedNumbers = $event,
3068
+ placeholder: "+15551234567, +15559876543",
3069
+ class: "w-full"
3070
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3071
+ ]),
3072
+ _: 1
3073
+ })
3074
+ ], 64)) : createCommentVNode("", true),
3075
+ unref(editingBridge)?.platform === "google" ? (openBlock(), createBlock(Fragment, { key: 4 }, [
3076
+ createVNode(_component_UFormField, {
3077
+ label: "Enabled Services",
3078
+ name: "enabledServices"
3079
+ }, {
3080
+ default: withCtx(() => [
3081
+ createVNode("div", { class: "space-y-2" }, [
3082
+ (openBlock(), createBlock(Fragment, null, renderList(googleServiceOptions, (svc) => {
3083
+ return createVNode("label", {
3084
+ key: svc.value,
3085
+ class: "flex items-center gap-2 cursor-pointer"
3086
+ }, [
3087
+ createVNode("input", {
3088
+ type: "checkbox",
3089
+ checked: unref(bridgeConfigForm).enabledServices.includes(svc.value),
3090
+ class: "rounded",
3091
+ onChange: ($event) => unref(bridgeConfigForm).enabledServices.includes(svc.value) ? unref(bridgeConfigForm).enabledServices = unref(bridgeConfigForm).enabledServices.filter((s) => s !== svc.value) : unref(bridgeConfigForm).enabledServices.push(svc.value)
3092
+ }, null, 40, ["checked", "onChange"]),
3093
+ createVNode("span", { class: "text-sm" }, toDisplayString(svc.label), 1)
3094
+ ]);
3095
+ }), 64))
3096
+ ])
3097
+ ]),
3098
+ _: 1
3099
+ }),
3100
+ createVNode(_component_UFormField, {
3101
+ label: "Google Account",
3102
+ name: "account",
3103
+ hint: "Email used with gogcli"
3104
+ }, {
3105
+ default: withCtx(() => [
3106
+ createVNode(_component_UInput, {
3107
+ modelValue: unref(bridgeConfigForm).account,
3108
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).account = $event,
3109
+ placeholder: "user@gmail.com",
3110
+ class: "w-full"
3111
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3112
+ ]),
3113
+ _: 1
3114
+ })
3115
+ ], 64)) : createCommentVNode("", true),
3116
+ unref(editingBridge)?.platform === "email" ? (openBlock(), createBlock(Fragment, { key: 5 }, [
3117
+ createVNode(_component_UFormField, {
3118
+ label: "Email Address",
3119
+ name: "emailAddress"
3120
+ }, {
3121
+ default: withCtx(() => [
3122
+ createVNode(_component_UInput, {
3123
+ modelValue: unref(bridgeConfigForm).emailAddress,
3124
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).emailAddress = $event,
3125
+ placeholder: "user@example.com",
3126
+ class: "w-full"
3127
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3128
+ ]),
3129
+ _: 1
3130
+ }),
3131
+ createVNode("div", { class: "grid grid-cols-2 gap-4" }, [
3132
+ createVNode(_component_UFormField, {
3133
+ label: "IMAP Host",
3134
+ name: "imapHost"
3135
+ }, {
3136
+ default: withCtx(() => [
3137
+ createVNode(_component_UInput, {
3138
+ modelValue: unref(bridgeConfigForm).imapHost,
3139
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapHost = $event,
3140
+ placeholder: "imap.example.com",
3141
+ class: "w-full"
3142
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3143
+ ]),
3144
+ _: 1
3145
+ }),
3146
+ createVNode(_component_UFormField, {
3147
+ label: "IMAP Port",
3148
+ name: "imapPort"
3149
+ }, {
3150
+ default: withCtx(() => [
3151
+ createVNode(_component_UInput, {
3152
+ modelValue: unref(bridgeConfigForm).imapPort,
3153
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).imapPort = $event,
3154
+ placeholder: "993",
3155
+ class: "w-full"
3156
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3157
+ ]),
3158
+ _: 1
3159
+ })
3160
+ ]),
3161
+ createVNode("div", { class: "grid grid-cols-2 gap-4" }, [
3162
+ createVNode(_component_UFormField, {
3163
+ label: "SMTP Host",
3164
+ name: "smtpHost"
3165
+ }, {
3166
+ default: withCtx(() => [
3167
+ createVNode(_component_UInput, {
3168
+ modelValue: unref(bridgeConfigForm).smtpHost,
3169
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpHost = $event,
3170
+ placeholder: "smtp.example.com",
3171
+ class: "w-full"
3172
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3173
+ ]),
3174
+ _: 1
3175
+ }),
3176
+ createVNode(_component_UFormField, {
3177
+ label: "SMTP Port",
3178
+ name: "smtpPort"
3179
+ }, {
3180
+ default: withCtx(() => [
3181
+ createVNode(_component_UInput, {
3182
+ modelValue: unref(bridgeConfigForm).smtpPort,
3183
+ "onUpdate:modelValue": ($event) => unref(bridgeConfigForm).smtpPort = $event,
3184
+ placeholder: "587",
3185
+ class: "w-full"
3186
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
3187
+ ]),
3188
+ _: 1
3189
+ })
3190
+ ])
3191
+ ], 64)) : createCommentVNode("", true),
3192
+ createVNode("div", { class: "flex justify-end gap-2 pt-4" }, [
3193
+ createVNode(_component_UButton, {
3194
+ variant: "ghost",
3195
+ onClick: ($event) => bridgeConfigModal.value = false
3196
+ }, {
3197
+ default: withCtx(() => [
3198
+ createTextVNode(" Cancel ")
3199
+ ]),
3200
+ _: 1
3201
+ }, 8, ["onClick"]),
3202
+ createVNode(_component_UButton, {
3203
+ loading: unref(bridgeConfigSaving),
3204
+ onClick: handleBridgeConfigSave
3205
+ }, {
3206
+ default: withCtx(() => [
3207
+ createTextVNode(" Save ")
3208
+ ]),
3209
+ _: 1
3210
+ }, 8, ["loading"])
3211
+ ])
3212
+ ])
3213
+ ]),
3214
+ _: 1
1739
3215
  }, 8, ["open", "onUpdate:open"])
1740
3216
  ];
1741
3217
  }
@@ -1753,4 +3229,4 @@ _sfc_main.setup = (props, ctx) => {
1753
3229
  };
1754
3230
 
1755
3231
  export { _sfc_main as default };
1756
- //# sourceMappingURL=settings-DuT6LGJZ.mjs.map
3232
+ //# sourceMappingURL=settings-B2KXoGcz.mjs.map