cognova 0.2.7 → 0.2.8

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 (172) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{BjFs8Ujb.js → -2AbaFNH.js} +1 -1
  3. package/.output/public/_nuxt/{B5OWqWCh.js → 0dqQoCHY.js} +1 -1
  4. package/.output/public/_nuxt/{DZ_azKLI.js → 2QHXgMyi.js} +1 -1
  5. package/.output/public/_nuxt/{DaiWSWdm.js → 36ZHqDPo.js} +1 -1
  6. package/.output/public/_nuxt/4XnyUc7C.js +1 -0
  7. package/.output/public/_nuxt/{DgKeJf5C.js → 6QDVg5TO.js} +1 -1
  8. package/.output/public/_nuxt/{RRoc4m9d.js → B-AlyT2D.js} +1 -1
  9. package/.output/public/_nuxt/{1Hz98MKF.js → B0xuHXvN.js} +1 -1
  10. package/.output/public/_nuxt/{BW-E-Sar.js → B2Xfh7am.js} +1 -1
  11. package/.output/public/_nuxt/{Bb1B0ntt.js → B5SnZL2l.js} +1 -1
  12. package/.output/public/_nuxt/{CEfkp9Rl.js → B6-U3KqJ.js} +2 -2
  13. package/.output/public/_nuxt/{Cebw7Q7c.js → B6G3NLfW.js} +1 -1
  14. package/.output/public/_nuxt/B8TQvzYX.js +1 -0
  15. package/.output/public/_nuxt/{D3V98LVR.js → B9zgEO8N.js} +1 -1
  16. package/.output/public/_nuxt/{CNwGp6eP.js → BBDxhFYY.js} +1 -1
  17. package/.output/public/_nuxt/{Dkzqkzki.js → BCCYopTB.js} +1 -1
  18. package/.output/public/_nuxt/{CfWDee_q.js → BE1CVWts.js} +1 -1
  19. package/.output/public/_nuxt/{BTk5mgdf.js → BF3tVKtX.js} +1 -1
  20. package/.output/public/_nuxt/{HCCuOAgZ.js → BHn8tRjg.js} +1 -1
  21. package/.output/public/_nuxt/BIo-9u_O.js +1 -0
  22. package/.output/public/_nuxt/{CG0fS-BQ.js → BJUff9Ku.js} +1 -1
  23. package/.output/public/_nuxt/{CrjKigv8.js → BLm0UviR.js} +1 -1
  24. package/.output/public/_nuxt/BLwctszt.js +1 -0
  25. package/.output/public/_nuxt/BMs0mHEp.js +1 -0
  26. package/.output/public/_nuxt/{DV0JMebZ.js → BSA-U0so.js} +1 -1
  27. package/.output/public/_nuxt/{D-wVwRIx.js → BUC36BHp.js} +1 -1
  28. package/.output/public/_nuxt/{CzqLfT8k.js → BVEFmI4I.js} +1 -1
  29. package/.output/public/_nuxt/{B43p0So7.js → BXtZVbmx.js} +1 -1
  30. package/.output/public/_nuxt/{BJ_GgKV0.js → BYtVdUIW.js} +1 -1
  31. package/.output/public/_nuxt/{CJ85o8FK.js → BZBNJD7U.js} +1 -1
  32. package/.output/public/_nuxt/{Dpp5cOwJ.js → BahXyh-A.js} +1 -1
  33. package/.output/public/_nuxt/{BmTCDcNm.js → BdxP21ep.js} +1 -1
  34. package/.output/public/_nuxt/{Bc0NIKN7.js → BefOhWHD.js} +1 -1
  35. package/.output/public/_nuxt/{DuOsLoVR.js → BhYoxmLV.js} +1 -1
  36. package/.output/public/_nuxt/{BMLwzSDu.js → Bhhg7oSf.js} +1 -1
  37. package/.output/public/_nuxt/{deSeNTOh.js → BjnQ1pI1.js} +1 -1
  38. package/.output/public/_nuxt/{qW7F87d8.js → BkO884Ds.js} +3 -3
  39. package/.output/public/_nuxt/{BNlugvM3.js → Bkc1Hpcf.js} +1 -1
  40. package/.output/public/_nuxt/{DgPiIWA2.js → BlsIfvSf.js} +1 -1
  41. package/.output/public/_nuxt/{Dysa6np_.js → BmaHzvZM.js} +1 -1
  42. package/.output/public/_nuxt/{CBrXB4hk.js → BmdlymIW.js} +1 -1
  43. package/.output/public/_nuxt/{CK5Ef4YR.js → BnJ-6YDw.js} +1 -1
  44. package/.output/public/_nuxt/{C5nfaH9w.js → BqTdsCnW.js} +1 -1
  45. package/.output/public/_nuxt/{CjRmY2OQ.js → BrOKokPO.js} +1 -1
  46. package/.output/public/_nuxt/{B7-0ADn3.js → Buf1PAiO.js} +1 -1
  47. package/.output/public/_nuxt/{CqiOV9n1.js → BvstjGHC.js} +1 -1
  48. package/.output/public/_nuxt/{DsKy-gee.js → BwC62XRN.js} +1 -1
  49. package/.output/public/_nuxt/{WWNeb45u.js → Bwn-CRYH.js} +1 -1
  50. package/.output/public/_nuxt/{BsXPllgv.js → BwyXWqBY.js} +1 -1
  51. package/.output/public/_nuxt/{C6Kc4XvS.js → BxShcW0K.js} +1 -1
  52. package/.output/public/_nuxt/{NBE83ZQn.js → C-HCArYP.js} +1 -1
  53. package/.output/public/_nuxt/{sdvIKLwS.js → C-Ygk9x5.js} +1 -1
  54. package/.output/public/_nuxt/{Dx2Tgm6S.js → C075hYlX.js} +1 -1
  55. package/.output/public/_nuxt/{C14DGwaT.js → C13FKhqK.js} +1 -1
  56. package/.output/public/_nuxt/{BLszW9T3.js → C1tCdK-M.js} +1 -1
  57. package/.output/public/_nuxt/{BdCB2PoJ.js → C21BjagS.js} +1 -1
  58. package/.output/public/_nuxt/{B_28CKij.js → C24so3m7.js} +2 -2
  59. package/.output/public/_nuxt/{Drr-RSSP.js → C3tximD1.js} +1 -1
  60. package/.output/public/_nuxt/{XzRnkkwG.js → C6FFW_cO.js} +1 -1
  61. package/.output/public/_nuxt/{Cedv1M65.js → C6sX7TYf.js} +1 -1
  62. package/.output/public/_nuxt/{CnW8zyuA.js → C7qhmmZh.js} +1 -1
  63. package/.output/public/_nuxt/{CSQ-nblB.js → CAfyXyeo.js} +1 -1
  64. package/.output/public/_nuxt/{DxR8g9So.js → CClsKJ9A.js} +1 -1
  65. package/.output/public/_nuxt/{Ci-MVdCd.js → CDkyQ1eQ.js} +1 -1
  66. package/.output/public/_nuxt/CE9_ECxx.js +1 -0
  67. package/.output/public/_nuxt/{JJIcQEna.js → CEDw8osP.js} +1 -1
  68. package/.output/public/_nuxt/{CwJR22-0.js → CEz288t8.js} +1 -1
  69. package/.output/public/_nuxt/{BvuV9uCn.js → CF33v_m5.js} +1 -1
  70. package/.output/public/_nuxt/{DytaiikM.js → CH_jROT9.js} +1 -1
  71. package/.output/public/_nuxt/{NlScC3GW.js → CO3hceDE.js} +1 -1
  72. package/.output/public/_nuxt/{ByfSJZV6.js → CQ3tAemj.js} +1 -1
  73. package/.output/public/_nuxt/{DMsHLHmB.js → CSHcfejh.js} +1 -1
  74. package/.output/public/_nuxt/{DAs574wU.js → CSjOaBKu.js} +1 -1
  75. package/.output/public/_nuxt/{DNpsjOxN.js → CVYcsqmL.js} +1 -1
  76. package/.output/public/_nuxt/{DfpSaqgV.js → CXTrUfQ5.js} +1 -1
  77. package/.output/public/_nuxt/{0LyRrTRM.js → CY7f553E.js} +1 -1
  78. package/.output/public/_nuxt/{A5lrd5_j.js → CYQP4zpi.js} +1 -1
  79. package/.output/public/_nuxt/CbvNJVrk.js +1 -0
  80. package/.output/public/_nuxt/CewcVxDS.js +1 -0
  81. package/.output/public/_nuxt/{1IuG3yiQ.js → CfY_bsV0.js} +1 -1
  82. package/.output/public/_nuxt/{4bC1z31I.js → ClGn48iq.js} +1 -1
  83. package/.output/public/_nuxt/{CwaMSU1O.js → CqFcWBkW.js} +1 -1
  84. package/.output/public/_nuxt/Cr0NfhPB.js +1 -0
  85. package/.output/public/_nuxt/{CXuKrnTA.js → CrmE-JGu.js} +1 -1
  86. package/.output/public/_nuxt/{CW8xtqwN.js → Cve4psva.js} +1 -1
  87. package/.output/public/_nuxt/{BsPj3ifk.js → CzAZpALW.js} +1 -1
  88. package/.output/public/_nuxt/{S4a_N6rD.js → D-5A6cMB.js} +1 -1
  89. package/.output/public/_nuxt/{HC3657Xq.js → D-Ge96eV.js} +1 -1
  90. package/.output/public/_nuxt/{fTEmwfo4.js → D04CyXmf.js} +1 -1
  91. package/.output/public/_nuxt/{B9Kd_0HK.js → D2kQkOaG.js} +1 -1
  92. package/.output/public/_nuxt/{jeu3Xx8e.js → D4Cizi4y.js} +1 -1
  93. package/.output/public/_nuxt/{B-5roYpk.js → D4X6ONPF.js} +1 -1
  94. package/.output/public/_nuxt/{_16_b82K.js → D4_89MZm.js} +1 -1
  95. package/.output/public/_nuxt/{Db5XIfWS.js → D79lbuWG.js} +1 -1
  96. package/.output/public/_nuxt/{DAFasgHH.js → D7pKT3IW.js} +1 -1
  97. package/.output/public/_nuxt/{DZdh7_lh.js → D887s9k9.js} +1 -1
  98. package/.output/public/_nuxt/{DImdNj-F.js → D9aYkNhQ.js} +1 -1
  99. package/.output/public/_nuxt/{BoPAYize.js → DJt7Rogf.js} +1 -1
  100. package/.output/public/_nuxt/{BZFXnEwe.js → DKKY8zWm.js} +1 -1
  101. package/.output/public/_nuxt/{BJi2ZHtT.js → DLUvsixu.js} +1 -1
  102. package/.output/public/_nuxt/{zBoPDS4z.js → DMb_1D81.js} +1 -1
  103. package/.output/public/_nuxt/{CzTTKfet.js → DX_9SfFb.js} +1 -1
  104. package/.output/public/_nuxt/{CpC3C9gj.js → DZEuR9ms.js} +1 -1
  105. package/.output/public/_nuxt/{DCco_rlV.js → D_O7SlHm.js} +1 -1
  106. package/.output/public/_nuxt/{DvgLoqaC.js → D_obX2Hj.js} +1 -1
  107. package/.output/public/_nuxt/{CeDxLTxX.js → DaBSQDif.js} +1 -1
  108. package/.output/public/_nuxt/{DB3y_21M.js → Dbfwn2zk.js} +1 -1
  109. package/.output/public/_nuxt/{-2wkydbj.js → DcbbfwCe.js} +1 -1
  110. package/.output/public/_nuxt/{MdebRWqA.js → DmDPSvxi.js} +1 -1
  111. package/.output/public/_nuxt/{CVr40yKH.js → DmOS3vFH.js} +1 -1
  112. package/.output/public/_nuxt/DmcMCO8x.js +1 -0
  113. package/.output/public/_nuxt/DmlZSBjF.js +1 -0
  114. package/.output/public/_nuxt/{CB8_A8N4.js → DqzomZoo.js} +1 -1
  115. package/.output/public/_nuxt/{0J8pJb0Z.js → Drxf7nJz.js} +1 -1
  116. package/.output/public/_nuxt/{CjYUi9c8.js → Dt5mOzXj.js} +1 -1
  117. package/.output/public/_nuxt/{Brqrl-cH.js → DtJnWtpL.js} +1 -1
  118. package/.output/public/_nuxt/{CwCEQ4Dw.js → DtyyytRx.js} +1 -1
  119. package/.output/public/_nuxt/{CphXSvBo.js → DwIYtFfA.js} +1 -1
  120. package/.output/public/_nuxt/{CLZS246x.js → GGcn5KPW.js} +1 -1
  121. package/.output/public/_nuxt/{pkbwpgSD.js → GYf-vnR6.js} +1 -1
  122. package/.output/public/_nuxt/{Bn8loaeQ.js → ImPsUDiH.js} +1 -1
  123. package/.output/public/_nuxt/{hqpqUuXS.js → JReYPlwF.js} +1 -1
  124. package/.output/public/_nuxt/{CgQKyBSS.js → KEeoKtq_.js} +1 -1
  125. package/.output/public/_nuxt/{Bf34lExB.js → LQNRVThr.js} +1 -1
  126. package/.output/public/_nuxt/{BhOIdu3Z.js → MWUW1sIF.js} +1 -1
  127. package/.output/public/_nuxt/{w3t8WD8v.js → Pn7VD6uQ.js} +1 -1
  128. package/.output/public/_nuxt/{BaJEGr8G.js → SfaNtyKS.js} +1 -1
  129. package/.output/public/_nuxt/{vM-wdhkZ.js → U3f6dy8i.js} +1 -1
  130. package/.output/public/_nuxt/builds/latest.json +1 -1
  131. package/.output/public/_nuxt/builds/meta/410e449d-9fe8-43a0-ae07-80797693b9b8.json +1 -0
  132. package/.output/public/_nuxt/{BrICHPil.js → cPPThz84.js} +1 -1
  133. package/.output/public/_nuxt/{CxJr4mB0.js → dB7G4iIC.js} +1 -1
  134. package/.output/public/_nuxt/{EgYyfo1g.js → eE8TtXgC.js} +3 -3
  135. package/.output/public/_nuxt/iBaivqi8.js +1 -0
  136. package/.output/public/_nuxt/{BLL1JLwq.js → ijmD2cEW.js} +1 -1
  137. package/.output/public/_nuxt/{DpYns7cT.js → it8syoZI.js} +1 -1
  138. package/.output/public/_nuxt/mT7Mt2d7.js +1 -0
  139. package/.output/public/_nuxt/{Bb9LNSu_.js → mfAEx0Kz.js} +1 -1
  140. package/.output/public/_nuxt/{MzEmU9ER.js → nHSiDk8N.js} +1 -1
  141. package/.output/public/_nuxt/{CvMqUdkl.js → njnzCNrH.js} +3 -3
  142. package/.output/public/_nuxt/{atVSHCxP.js → pHCJ6lhw.js} +1 -1
  143. package/.output/public/_nuxt/{Cow1TrPj.js → vES4kgx7.js} +1 -1
  144. package/.output/public/_nuxt/{Zjvb5YJR.js → yJ9vRvHj.js} +1 -1
  145. package/.output/public/_nuxt/{B8Kve-DH.js → zO9MgHj2.js} +1 -1
  146. package/.output/public/_nuxt/{BaVaTug8.js → zXvvpsZj.js} +1 -1
  147. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  148. package/.output/server/chunks/build/server.mjs +1 -1
  149. package/.output/server/chunks/build/{settings-DuT6LGJZ.mjs → settings-ByUXa46k.mjs} +1507 -218
  150. package/.output/server/chunks/build/settings-ByUXa46k.mjs.map +1 -0
  151. package/.output/server/chunks/build/styles.mjs +2 -2
  152. package/.output/server/chunks/nitro/nitro.mjs +872 -872
  153. package/.output/server/package.json +1 -1
  154. package/app/pages/settings.vue +441 -5
  155. package/package.json +1 -1
  156. package/server/api/skills/import.post.ts +1 -1
  157. package/server/bridge/adapters/telegram.ts +1 -1
  158. package/.output/public/_nuxt/B-YQztaH.js +0 -1
  159. package/.output/public/_nuxt/B1gFtqXK.js +0 -1
  160. package/.output/public/_nuxt/BTfZ7nek.js +0 -1
  161. package/.output/public/_nuxt/BbPnqQJ0.js +0 -1
  162. package/.output/public/_nuxt/BhSWIRpp.js +0 -1
  163. package/.output/public/_nuxt/By6kmkhJ.js +0 -1
  164. package/.output/public/_nuxt/C4XVJnNJ.js +0 -1
  165. package/.output/public/_nuxt/CkvyAKbu.js +0 -1
  166. package/.output/public/_nuxt/D2f7BlK2.js +0 -1
  167. package/.output/public/_nuxt/D2lmhTjQ.js +0 -1
  168. package/.output/public/_nuxt/D64-rCSQ.js +0 -1
  169. package/.output/public/_nuxt/DGP2JJt8.js +0 -1
  170. package/.output/public/_nuxt/builds/meta/9863fe43-d78c-4b29-a1e8-e6de61119507.json +0 -1
  171. package/.output/public/_nuxt/f7zDjk6q.js +0 -1
  172. package/.output/server/chunks/build/settings-DuT6LGJZ.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognova-prod",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
@@ -272,6 +272,70 @@ const bridgeForm = reactive({
272
272
  name: ''
273
273
  })
274
274
 
275
+ // Bridge config modal state
276
+ const bridgeConfigModal = ref(false)
277
+ const editingBridge = ref<Bridge | null>(null)
278
+ const bridgeConfigSaving = ref(false)
279
+
280
+ const bridgeConfigForm = reactive({
281
+ name: '',
282
+ // Telegram
283
+ botUsername: '',
284
+ allowedChatIds: '',
285
+ // Discord
286
+ listenMode: 'mentions' as 'mentions' | 'dm' | 'all',
287
+ guildId: '',
288
+ channelId: '',
289
+ // iMessage
290
+ strategy: 'imsg' as 'imsg' | 'bluebubbles',
291
+ allowedNumbers: '',
292
+ blueBubblesUrl: '',
293
+ // Google
294
+ enabledServices: [] as string[],
295
+ account: '',
296
+ // Email
297
+ imapHost: '',
298
+ imapPort: '',
299
+ smtpHost: '',
300
+ smtpPort: '',
301
+ emailAddress: ''
302
+ })
303
+
304
+ const discordListenModeOptions = [
305
+ { value: 'mentions', label: 'Mentions & DMs' },
306
+ { value: 'dm', label: 'DMs only' },
307
+ { value: 'all', label: 'All messages' }
308
+ ]
309
+
310
+ const imessageStrategyOptions = [
311
+ { value: 'imsg', label: 'Local (imsg CLI)' },
312
+ { value: 'bluebubbles', label: 'BlueBubbles' }
313
+ ]
314
+
315
+ const googleServiceOptions = [
316
+ { value: 'gmail', label: 'Gmail' },
317
+ { value: 'calendar', label: 'Calendar' },
318
+ { value: 'drive', label: 'Drive' },
319
+ { value: 'contacts', label: 'Contacts' },
320
+ { value: 'tasks', label: 'Tasks' }
321
+ ]
322
+
323
+ const platformNamePlaceholders: Record<BridgePlatform, string> = {
324
+ telegram: 'My Telegram Bot',
325
+ discord: 'My Discord Bot',
326
+ imessage: 'iMessage Bridge',
327
+ google: 'Google Suite',
328
+ email: 'Work Email'
329
+ }
330
+
331
+ const platformSecretHints: Record<BridgePlatform, string | null> = {
332
+ telegram: 'TELEGRAM_BOT_TOKEN',
333
+ discord: 'DISCORD_BOT_TOKEN',
334
+ imessage: null,
335
+ google: null,
336
+ email: null
337
+ }
338
+
275
339
  const platformOptions: { value: BridgePlatform, label: string, icon: string }[] = [
276
340
  { value: 'telegram', label: 'Telegram', icon: 'i-lucide-send' },
277
341
  { value: 'discord', label: 'Discord', icon: 'i-lucide-message-circle' },
@@ -298,6 +362,119 @@ async function fetchBridges() {
298
362
  bridgesLoading.value = false
299
363
  }
300
364
 
365
+ function openBridgeConfig(bridge: Bridge) {
366
+ editingBridge.value = bridge
367
+ bridgeConfigForm.name = bridge.name
368
+
369
+ const config = bridge.config ? JSON.parse(bridge.config) : {}
370
+
371
+ // Reset all fields
372
+ bridgeConfigForm.botUsername = ''
373
+ bridgeConfigForm.allowedChatIds = ''
374
+ bridgeConfigForm.listenMode = 'mentions'
375
+ bridgeConfigForm.guildId = ''
376
+ bridgeConfigForm.channelId = ''
377
+ bridgeConfigForm.strategy = 'imsg'
378
+ bridgeConfigForm.allowedNumbers = ''
379
+ bridgeConfigForm.blueBubblesUrl = ''
380
+ bridgeConfigForm.enabledServices = []
381
+ bridgeConfigForm.account = ''
382
+ bridgeConfigForm.imapHost = ''
383
+ bridgeConfigForm.imapPort = ''
384
+ bridgeConfigForm.smtpHost = ''
385
+ bridgeConfigForm.smtpPort = ''
386
+ bridgeConfigForm.emailAddress = ''
387
+
388
+ // Populate platform-specific fields from config
389
+ switch (bridge.platform) {
390
+ case 'telegram':
391
+ bridgeConfigForm.botUsername = config.botUsername || ''
392
+ bridgeConfigForm.allowedChatIds = (config.allowedChatIds || []).join(', ')
393
+ break
394
+ case 'discord':
395
+ bridgeConfigForm.listenMode = config.listenMode || 'mentions'
396
+ bridgeConfigForm.guildId = config.guildId || ''
397
+ bridgeConfigForm.channelId = config.channelId || ''
398
+ break
399
+ case 'imessage':
400
+ bridgeConfigForm.strategy = config.strategy || 'imsg'
401
+ bridgeConfigForm.allowedNumbers = (config.allowedNumbers || []).join(', ')
402
+ bridgeConfigForm.blueBubblesUrl = config.blueBubblesUrl || ''
403
+ break
404
+ case 'google':
405
+ bridgeConfigForm.enabledServices = config.enabledServices || []
406
+ bridgeConfigForm.account = config.account || ''
407
+ break
408
+ case 'email':
409
+ bridgeConfigForm.imapHost = config.imapHost || ''
410
+ bridgeConfigForm.imapPort = config.imapPort?.toString() || ''
411
+ bridgeConfigForm.smtpHost = config.smtpHost || ''
412
+ bridgeConfigForm.smtpPort = config.smtpPort?.toString() || ''
413
+ bridgeConfigForm.emailAddress = config.emailAddress || ''
414
+ break
415
+ }
416
+
417
+ bridgeConfigModal.value = true
418
+ }
419
+
420
+ async function handleBridgeConfigSave() {
421
+ if (!editingBridge.value) return
422
+
423
+ const platform = editingBridge.value.platform
424
+ let config: Record<string, unknown> = {}
425
+
426
+ // Preserve existing config (like webhookSecret) and merge new fields
427
+ if (editingBridge.value.config)
428
+ config = JSON.parse(editingBridge.value.config)
429
+
430
+ switch (platform) {
431
+ case 'telegram':
432
+ config.botUsername = bridgeConfigForm.botUsername || undefined
433
+ config.allowedChatIds = bridgeConfigForm.allowedChatIds
434
+ ? bridgeConfigForm.allowedChatIds.split(',').map(s => s.trim()).filter(Boolean)
435
+ : undefined
436
+ break
437
+ case 'discord':
438
+ config.listenMode = bridgeConfigForm.listenMode
439
+ config.guildId = bridgeConfigForm.guildId || undefined
440
+ config.channelId = bridgeConfigForm.channelId || undefined
441
+ break
442
+ case 'imessage':
443
+ config.strategy = bridgeConfigForm.strategy
444
+ config.allowedNumbers = bridgeConfigForm.allowedNumbers
445
+ ? bridgeConfigForm.allowedNumbers.split(',').map(s => s.trim()).filter(Boolean)
446
+ : undefined
447
+ config.blueBubblesUrl = bridgeConfigForm.blueBubblesUrl || undefined
448
+ break
449
+ case 'google':
450
+ config.enabledServices = bridgeConfigForm.enabledServices
451
+ config.account = bridgeConfigForm.account || undefined
452
+ break
453
+ case 'email':
454
+ config.imapHost = bridgeConfigForm.imapHost || undefined
455
+ config.imapPort = bridgeConfigForm.imapPort ? Number(bridgeConfigForm.imapPort) : undefined
456
+ config.smtpHost = bridgeConfigForm.smtpHost || undefined
457
+ config.smtpPort = bridgeConfigForm.smtpPort ? Number(bridgeConfigForm.smtpPort) : undefined
458
+ config.emailAddress = bridgeConfigForm.emailAddress || undefined
459
+ break
460
+ }
461
+
462
+ bridgeConfigSaving.value = true
463
+ try {
464
+ await $fetch(`/api/bridges/${editingBridge.value.id}` as string, {
465
+ method: 'PUT',
466
+ body: { name: bridgeConfigForm.name, config }
467
+ })
468
+ toast.add({ title: 'Integration updated', color: 'success' })
469
+ bridgeConfigModal.value = false
470
+ await fetchBridges()
471
+ } catch (err: unknown) {
472
+ const error = err as { data?: { message?: string } }
473
+ toast.add({ title: 'Failed to update integration', description: error.data?.message, color: 'error' })
474
+ }
475
+ bridgeConfigSaving.value = false
476
+ }
477
+
301
478
  function openCreateBridge() {
302
479
  bridgeForm.platform = 'telegram'
303
480
  bridgeForm.name = ''
@@ -327,7 +504,7 @@ async function handleBridgeCreate() {
327
504
 
328
505
  async function toggleBridge(bridge: Bridge) {
329
506
  try {
330
- await $fetch(`/api/bridges/${bridge.id}`, {
507
+ await $fetch(`/api/bridges/${bridge.id}` as string, {
331
508
  method: 'PUT',
332
509
  body: { enabled: !bridge.enabled }
333
510
  })
@@ -345,7 +522,7 @@ function confirmDeleteBridge(bridge: Bridge) {
345
522
  async function handleDeleteBridge() {
346
523
  if (!bridgeToDelete.value) return
347
524
  try {
348
- await $fetch(`/api/bridges/${bridgeToDelete.value.id}`, { method: 'DELETE' })
525
+ await $fetch(`/api/bridges/${bridgeToDelete.value.id}` as string, { method: 'DELETE' })
349
526
  toast.add({ title: 'Integration deleted', color: 'success' })
350
527
  bridgeDeleteConfirm.value = false
351
528
  bridgeToDelete.value = null
@@ -717,7 +894,8 @@ async function handlePasswordSubmit() {
717
894
  <div
718
895
  v-for="bridge in bridgesData"
719
896
  :key="bridge.id"
720
- class="border border-default rounded-lg px-4 py-3"
897
+ class="border border-default rounded-lg px-4 py-3 cursor-pointer hover:bg-elevated/50 transition-colors"
898
+ @click="openBridgeConfig(bridge)"
721
899
  >
722
900
  <div class="flex items-center justify-between">
723
901
  <div class="flex items-center gap-3">
@@ -739,6 +917,7 @@ async function handlePasswordSubmit() {
739
917
  </span>
740
918
  <USwitch
741
919
  :model-value="bridge.enabled"
920
+ @click.stop
742
921
  @update:model-value="toggleBridge(bridge)"
743
922
  />
744
923
  <UButton
@@ -746,7 +925,7 @@ async function handlePasswordSubmit() {
746
925
  color="error"
747
926
  icon="i-lucide-trash-2"
748
927
  size="xs"
749
- @click="confirmDeleteBridge(bridge)"
928
+ @click.stop="confirmDeleteBridge(bridge)"
750
929
  />
751
930
  </div>
752
931
  </div>
@@ -980,7 +1159,7 @@ async function handlePasswordSubmit() {
980
1159
  >
981
1160
  <UInput
982
1161
  v-model="bridgeForm.name"
983
- placeholder="My Telegram Bot"
1162
+ :placeholder="platformNamePlaceholders[bridgeForm.platform]"
984
1163
  class="w-full"
985
1164
  />
986
1165
  </UFormField>
@@ -1032,5 +1211,262 @@ async function handlePasswordSubmit() {
1032
1211
  </div>
1033
1212
  </template>
1034
1213
  </UModal>
1214
+
1215
+ <!-- Bridge Config Modal -->
1216
+ <UModal v-model:open="bridgeConfigModal">
1217
+ <template #header>
1218
+ <div class="flex items-center gap-2">
1219
+ <UIcon
1220
+ :name="platformOptions.find(p => p.value === editingBridge?.platform)?.icon || 'i-lucide-plug'"
1221
+ class="size-5"
1222
+ />
1223
+ <h3 class="text-lg font-semibold">
1224
+ Configure {{ editingBridge?.name }}
1225
+ </h3>
1226
+ </div>
1227
+ </template>
1228
+ <template #body>
1229
+ <div class="space-y-4">
1230
+ <!-- Secret hint -->
1231
+ <div
1232
+ v-if="editingBridge && platformSecretHints[editingBridge.platform]"
1233
+ class="flex items-start gap-2 rounded-lg bg-elevated p-3 text-sm"
1234
+ >
1235
+ <UIcon
1236
+ name="i-lucide-info"
1237
+ class="size-4 mt-0.5 text-dimmed shrink-0"
1238
+ />
1239
+ <span class="text-dimmed">
1240
+ Requires secret <code class="bg-elevated px-1 py-0.5 rounded text-xs">{{ platformSecretHints[editingBridge.platform] }}</code> in the Secrets tab.
1241
+ </span>
1242
+ </div>
1243
+
1244
+ <!-- Common: Name -->
1245
+ <UFormField
1246
+ label="Name"
1247
+ name="name"
1248
+ >
1249
+ <UInput
1250
+ v-model="bridgeConfigForm.name"
1251
+ placeholder="Integration name"
1252
+ class="w-full"
1253
+ />
1254
+ </UFormField>
1255
+
1256
+ <!-- Telegram -->
1257
+ <template v-if="editingBridge?.platform === 'telegram'">
1258
+ <UFormField
1259
+ label="Bot Username"
1260
+ name="botUsername"
1261
+ hint="Without the @ prefix"
1262
+ >
1263
+ <UInput
1264
+ v-model="bridgeConfigForm.botUsername"
1265
+ placeholder="my_bot"
1266
+ class="w-full"
1267
+ />
1268
+ </UFormField>
1269
+ <UFormField
1270
+ label="Allowed Chat IDs"
1271
+ name="allowedChatIds"
1272
+ hint="Comma-separated. Leave empty for all."
1273
+ >
1274
+ <UInput
1275
+ v-model="bridgeConfigForm.allowedChatIds"
1276
+ placeholder="123456, -100789"
1277
+ class="w-full"
1278
+ />
1279
+ </UFormField>
1280
+ </template>
1281
+
1282
+ <!-- Discord -->
1283
+ <template v-if="editingBridge?.platform === 'discord'">
1284
+ <UFormField
1285
+ label="Listen Mode"
1286
+ name="listenMode"
1287
+ >
1288
+ <USelect
1289
+ v-model="bridgeConfigForm.listenMode"
1290
+ :items="discordListenModeOptions"
1291
+ value-key="value"
1292
+ class="w-full"
1293
+ />
1294
+ </UFormField>
1295
+ <UFormField
1296
+ label="Server ID"
1297
+ name="guildId"
1298
+ hint="Optional. Limit to one server."
1299
+ >
1300
+ <UInput
1301
+ v-model="bridgeConfigForm.guildId"
1302
+ placeholder="Discord server ID"
1303
+ class="w-full"
1304
+ />
1305
+ </UFormField>
1306
+ <UFormField
1307
+ label="Channel ID"
1308
+ name="channelId"
1309
+ hint="Optional. Limit to one channel (for 'all' mode)."
1310
+ >
1311
+ <UInput
1312
+ v-model="bridgeConfigForm.channelId"
1313
+ placeholder="Discord channel ID"
1314
+ class="w-full"
1315
+ />
1316
+ </UFormField>
1317
+ </template>
1318
+
1319
+ <!-- iMessage -->
1320
+ <template v-if="editingBridge?.platform === 'imessage'">
1321
+ <UFormField
1322
+ label="Strategy"
1323
+ name="strategy"
1324
+ >
1325
+ <USelect
1326
+ v-model="bridgeConfigForm.strategy"
1327
+ :items="imessageStrategyOptions"
1328
+ value-key="value"
1329
+ class="w-full"
1330
+ />
1331
+ </UFormField>
1332
+ <UFormField
1333
+ v-if="bridgeConfigForm.strategy === 'bluebubbles'"
1334
+ label="BlueBubbles URL"
1335
+ name="blueBubblesUrl"
1336
+ >
1337
+ <UInput
1338
+ v-model="bridgeConfigForm.blueBubblesUrl"
1339
+ placeholder="http://192.168.1.100:1234"
1340
+ class="w-full"
1341
+ />
1342
+ </UFormField>
1343
+ <UFormField
1344
+ label="Allowed Numbers"
1345
+ name="allowedNumbers"
1346
+ hint="Comma-separated. Leave empty for all."
1347
+ >
1348
+ <UInput
1349
+ v-model="bridgeConfigForm.allowedNumbers"
1350
+ placeholder="+15551234567, +15559876543"
1351
+ class="w-full"
1352
+ />
1353
+ </UFormField>
1354
+ </template>
1355
+
1356
+ <!-- Google Suite -->
1357
+ <template v-if="editingBridge?.platform === 'google'">
1358
+ <UFormField
1359
+ label="Enabled Services"
1360
+ name="enabledServices"
1361
+ >
1362
+ <div class="space-y-2">
1363
+ <label
1364
+ v-for="svc in googleServiceOptions"
1365
+ :key="svc.value"
1366
+ class="flex items-center gap-2 cursor-pointer"
1367
+ >
1368
+ <input
1369
+ type="checkbox"
1370
+ :checked="bridgeConfigForm.enabledServices.includes(svc.value)"
1371
+ class="rounded"
1372
+ @change="
1373
+ bridgeConfigForm.enabledServices.includes(svc.value)
1374
+ ? bridgeConfigForm.enabledServices = bridgeConfigForm.enabledServices.filter(s => s !== svc.value)
1375
+ : bridgeConfigForm.enabledServices.push(svc.value)
1376
+ "
1377
+ >
1378
+ <span class="text-sm">{{ svc.label }}</span>
1379
+ </label>
1380
+ </div>
1381
+ </UFormField>
1382
+ <UFormField
1383
+ label="Google Account"
1384
+ name="account"
1385
+ hint="Email used with gogcli"
1386
+ >
1387
+ <UInput
1388
+ v-model="bridgeConfigForm.account"
1389
+ placeholder="user@gmail.com"
1390
+ class="w-full"
1391
+ />
1392
+ </UFormField>
1393
+ </template>
1394
+
1395
+ <!-- Email (IMAP/SMTP) -->
1396
+ <template v-if="editingBridge?.platform === 'email'">
1397
+ <UFormField
1398
+ label="Email Address"
1399
+ name="emailAddress"
1400
+ >
1401
+ <UInput
1402
+ v-model="bridgeConfigForm.emailAddress"
1403
+ placeholder="user@example.com"
1404
+ class="w-full"
1405
+ />
1406
+ </UFormField>
1407
+ <div class="grid grid-cols-2 gap-4">
1408
+ <UFormField
1409
+ label="IMAP Host"
1410
+ name="imapHost"
1411
+ >
1412
+ <UInput
1413
+ v-model="bridgeConfigForm.imapHost"
1414
+ placeholder="imap.example.com"
1415
+ class="w-full"
1416
+ />
1417
+ </UFormField>
1418
+ <UFormField
1419
+ label="IMAP Port"
1420
+ name="imapPort"
1421
+ >
1422
+ <UInput
1423
+ v-model="bridgeConfigForm.imapPort"
1424
+ placeholder="993"
1425
+ class="w-full"
1426
+ />
1427
+ </UFormField>
1428
+ </div>
1429
+ <div class="grid grid-cols-2 gap-4">
1430
+ <UFormField
1431
+ label="SMTP Host"
1432
+ name="smtpHost"
1433
+ >
1434
+ <UInput
1435
+ v-model="bridgeConfigForm.smtpHost"
1436
+ placeholder="smtp.example.com"
1437
+ class="w-full"
1438
+ />
1439
+ </UFormField>
1440
+ <UFormField
1441
+ label="SMTP Port"
1442
+ name="smtpPort"
1443
+ >
1444
+ <UInput
1445
+ v-model="bridgeConfigForm.smtpPort"
1446
+ placeholder="587"
1447
+ class="w-full"
1448
+ />
1449
+ </UFormField>
1450
+ </div>
1451
+ </template>
1452
+
1453
+ <!-- Save / Cancel -->
1454
+ <div class="flex justify-end gap-2 pt-4">
1455
+ <UButton
1456
+ variant="ghost"
1457
+ @click="bridgeConfigModal = false"
1458
+ >
1459
+ Cancel
1460
+ </UButton>
1461
+ <UButton
1462
+ :loading="bridgeConfigSaving"
1463
+ @click="handleBridgeConfigSave"
1464
+ >
1465
+ Save
1466
+ </UButton>
1467
+ </div>
1468
+ </div>
1469
+ </template>
1470
+ </UModal>
1035
1471
  </UDashboardPanel>
1036
1472
  </template>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cognova",
3
3
  "type": "module",
4
- "version": "0.2.7",
4
+ "version": "0.2.8",
5
5
  "description": "Personal knowledge management system with Claude Code integration",
6
6
  "repository": {
7
7
  "type": "git",
@@ -19,7 +19,7 @@ export default defineEventHandler(async (event) => {
19
19
  throw createError({ statusCode: 400, message: 'Zip file is empty' })
20
20
 
21
21
  // Determine skill name from root folder or filename
22
- const firstEntry = entries[0].entryName
22
+ const firstEntry = entries[0]!.entryName
23
23
  const rootFolder = firstEntry.includes('/') ? firstEntry.split('/')[0] : null
24
24
  const fileName = fileField.filename?.replace(/\.zip$/i, '') || ''
25
25
  const skillName = rootFolder || fileName
@@ -100,7 +100,7 @@ export class TelegramAdapter implements BridgeAdapter {
100
100
 
101
101
  // Store bot username if not set
102
102
  if (!this.config.botUsername && me.result?.username) {
103
- this.config.botUsername = me.result.username
103
+ this.config.botUsername = me.result.username as string
104
104
  }
105
105
 
106
106
  console.log(`[telegram] Bot @${me.result?.username} authenticated`)
@@ -1 +0,0 @@
1
- import{N as r,c,G as n,R as p,a4 as u,U as i,al as s}from"./CvMqUdkl.js";const m={base:"list-disc ps-6 my-5 marker:text-(--ui-border-accented)"},_={__name:"ProseUl",props:{class:{type:null,required:!1}},setup(e){const a=e,t=r(),l=c(()=>s({extend:s(m),...t.ui?.prose?.ul||{}}));return(o,d)=>(p(),n("ul",{class:i(l.value({class:a.class}))},[u(o.$slots,"default")],2))}};export{_ as default};
@@ -1 +0,0 @@
1
- import{c as e,b as r,a5 as t}from"./CvMqUdkl.js";function a(o){return e(()=>r(o)?!!t(o)?.closest("form"):!0)}export{a as u};
@@ -1 +0,0 @@
1
- import{N as o,c as r,al as a,Q as c,R as u,S as i,a4 as p,U as m,C as f,a3 as x}from"./CvMqUdkl.js";const d={base:"w-full max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8"},g={__name:"UContainer",props:{as:{type:null,required:!1},class:{type:null,required:!1}},setup(s){const e=s,t=o(),l=r(()=>a({extend:a(d),...t.ui?.container||{}}));return(n,C)=>(u(),c(f(x),{as:s.as,class:m(l.value({class:e.class}))},{default:i(()=>[p(n.$slots,"default")]),_:3},8,["as","class"]))}};export{g as _};
@@ -1 +0,0 @@
1
- import{N as r,c,G as n,R as p,a4 as u,U as m,al as s}from"./CvMqUdkl.js";const i={base:"list-decimal ps-6 my-5 marker:text-muted"},_={__name:"ProseOl",props:{class:{type:null,required:!1}},setup(e){const a=e,t=r(),l=c(()=>s({extend:s(i),...t.ui?.prose?.ol||{}}));return(o,d)=>(p(),n("ol",{class:m(l.value({class:a.class}))},[u(o.$slots,"default")],2))}};export{_ as default};
@@ -1 +0,0 @@
1
- import{N as n,c as p,G as r,R as c,a4 as u,U as i,al as s}from"./CvMqUdkl.js";const m={base:"my-5 leading-7 text-pretty"},_={__name:"ProseP",props:{class:{type:null,required:!1}},setup(e){const a=e,t=n(),o=p(()=>s({extend:s(m),...t.ui?.prose?.p||{}}));return(l,d)=>(c(),r("p",{class:i(o.value({class:a.class}))},[u(l.$slots,"default")],2))}};export{_ as default};
@@ -1 +0,0 @@
1
- import{N as c,c as n,G as r,R as p,a4 as u,U as d,al as s}from"./CvMqUdkl.js";const i={base:""},_={__name:"ProseTbody",props:{class:{type:null,required:!1}},setup(e){const a=e,o=c(),t=n(()=>s({extend:s(i),...o.ui?.prose?.tbody||{}}));return(l,m)=>(p(),r("tbody",{class:d(t.value({class:a.class}))},[u(l.$slots,"default")],2))}};export{_ as default};
@@ -1 +0,0 @@
1
- import{N as r,c as l,G as c,R as p,a4 as u,U as i,al as s}from"./CvMqUdkl.js";const m={base:""},g={__name:"ProseStrong",props:{class:{type:null,required:!1}},setup(e){const a=e,o=r(),t=l(()=>s({extend:s(m),...o.ui?.prose?.strong||{}}));return(n,f)=>(p(),c("strong",{class:i(t.value({class:a.class}))},[u(n.$slots,"default")],2))}};export{g as default};
@@ -1 +0,0 @@
1
- import{N as c,c as n,G as r,R as p,a4 as u,U as d,al as e}from"./CvMqUdkl.js";const m={base:"bg-muted"},h={__name:"ProseThead",props:{class:{type:null,required:!1}},setup(s){const a=s,t=c(),o=n(()=>e({extend:e(m),...t.ui?.prose?.thead||{}}));return(l,i)=>(p(),r("thead",{class:d(o.value({class:a.class}))},[u(l.$slots,"default")],2))}};export{h as default};
@@ -1 +0,0 @@
1
- import"./CvMqUdkl.js";const s=globalThis.setInterval;export{s};
@@ -1 +0,0 @@
1
- import{X as e}from"./CvMqUdkl.js";function a(r,u="reka"){return r||`${u}-${e?.()}`}export{a as u};
@@ -1 +0,0 @@
1
- import{_ as ze}from"./CrjKigv8.js";import{_ as Ie,a as Le}from"./1Hz98MKF.js";import{_ as Ke}from"./BaJEGr8G.js";import{_ as qe}from"./S4a_N6rD.js";import{a as Re,ag as Ye,ah as A,e as r,f as Oe,q as Ge,Q as He,S as o,R as f,T as s,ab as l,G as v,C as a,ai as N,aj as T,a9 as ae,W as Qe,_ as We,ae as g,aa as c,U as Je,ak as I}from"./CvMqUdkl.js";import{_ as Xe}from"./DuOsLoVR.js";import{_ as Ze}from"./BMLwzSDu.js";import{_ as et}from"./C6Kc4XvS.js";import{_ as tt}from"./CB8_A8N4.js";import{_ as st}from"./D-wVwRIx.js";import{_ as lt}from"./CnW8zyuA.js";import{_ as at}from"./Bb1B0ntt.js";import{_ as ot}from"./pkbwpgSD.js";import{_ as nt}from"./MdebRWqA.js";import{u as it,d as te}from"./DpYns7cT.js";import{u as dt}from"./BNlugvM3.js";import"./sdvIKLwS.js";import"./HCCuOAgZ.js";import"./Cow1TrPj.js";import"./w3t8WD8v.js";import"./88opOQSr.js";import"./B9Kd_0HK.js";import"./B1gFtqXK.js";import"./CxJr4mB0.js";import"./DAFasgHH.js";import"./WWNeb45u.js";import"./Bn8loaeQ.js";import"./DxR8g9So.js";import"./D2lmhTjQ.js";import"./Zjvb5YJR.js";import"./CJ85o8FK.js";import"./BJ_GgKV0.js";import"./BJi2ZHtT.js";import"./D3V98LVR.js";import"./DImdNj-F.js";import"./CXuKrnTA.js";import"./Dkzqkzki.js";import"./D2f7BlK2.js";const rt={class:"p-6"},ut={class:"space-y-8 max-w-2xl mx-auto py-6"},ct={class:"py-6"},mt={class:"flex items-center justify-between mb-6"},pt={class:"text-sm bg-elevated px-2 py-0.5 rounded"},ft={class:"text-dimmed"},vt={class:"text-dimmed text-sm"},yt={class:"flex gap-2 justify-end"},gt={class:"py-12 text-center"},bt={class:"py-6"},wt={class:"flex items-center justify-between mb-6"},_t={key:0,class:"space-y-3"},xt={key:1,class:"py-12 text-center"},kt={key:2,class:"space-y-3"},ht={class:"flex items-center justify-between"},Pt={class:"flex items-center gap-3"},St={class:"font-medium"},Ct={class:"text-sm text-dimmed ml-2"},Ut={class:"flex items-center gap-3"},Vt={key:0,class:"text-xs text-dimmed mt-1 pl-8"},$t={class:"max-w-2xl mx-auto py-6"},Et={key:0,class:"space-y-3"},Dt={key:1,class:"space-y-2"},At={class:"flex items-center justify-between px-4 py-3"},Nt={class:"flex items-center gap-3"},Tt={class:"font-medium"},Mt={key:0,class:"border-t border-default px-4 py-3 space-y-2 bg-elevated/50"},Bt={class:"text-sm text-dimmed capitalize"},Ft={class:"mt-6"},jt={class:"space-y-8 max-w-xl mx-auto py-6"},zt={class:"space-y-4"},It={class:"text-lg font-semibold"},Lt={class:"flex justify-end gap-2 pt-4"},Kt={class:"mb-4"},qt={class:"bg-elevated px-2 py-0.5 rounded"},Rt={class:"flex justify-end gap-2 pt-6"},Yt={class:"space-y-4"},Ot={class:"flex justify-end gap-2 pt-4"},Gt={class:"mb-4"},Ht={class:"flex justify-end gap-2 pt-6"},Ts=Re({__name:"settings",setup(Qt){const{user:oe,updateProfile:ne,changeEmail:ie,changePassword:de}=dt(),i=Ye(),{updatePreferences:re}=it(),V=A({name:""}),L=r(!1),h=A({newEmail:""}),K=r(!1),m=A({currentPassword:"",newPassword:"",confirmPassword:""}),q=r(!1),se=r([]),R=r(!1),k=r(!1),P=r(!1),$=r(null),Y=r(!1),y=r(null),d=A({key:"",value:"",description:""});Oe(()=>oe.value,n=>{n&&(V.name=n.name||"",h.newEmail=n.email||"")},{immediate:!0});async function O(){R.value=!0;try{const{data:n}=await $fetch("/api/secrets");se.value=n}catch{i.add({title:"Failed to load secrets",color:"error"})}R.value=!1}const ue=[{label:"Account",icon:"i-lucide-user",value:"account",slot:"account"},{label:"Secrets",icon:"i-lucide-key",value:"secrets",slot:"secrets"},{label:"Integrations",icon:"i-lucide-plug",value:"integrations",slot:"integrations"},{label:"App",icon:"i-lucide-settings",value:"app",slot:"app"}],ce=[{accessorKey:"key",header:"Key"},{accessorKey:"description",header:"Description"},{accessorKey:"updatedAt",header:"Last Updated"},{accessorKey:"actions",header:""}];function me(){y.value=null,d.key="",d.value="",d.description="",k.value=!0}function pe(n){y.value=n,d.key=n.key,d.value="",d.description=n.description||"",k.value=!0}function fe(n){$.value=n,P.value=!0}async function ve(){if(!d.key||!y.value&&!d.value){i.add({title:"Missing fields",description:y.value?"Key is required.":"Key and value are required.",color:"error"});return}Y.value=!0;try{y.value?(await $fetch(`/api/secrets/${y.value.key}`,{method:"PUT",body:{value:d.value||void 0,description:d.description||void 0}}),i.add({title:"Secret updated",color:"success"})):(await $fetch("/api/secrets",{method:"POST",body:{key:d.key,value:d.value,description:d.description||void 0}}),i.add({title:"Secret created",color:"success"})),k.value=!1,await O()}catch(n){const e=n;i.add({title:y.value?"Failed to update secret":"Failed to create secret",description:e.data?.message||"An error occurred",color:"error"})}Y.value=!1}async function ye(){if($.value)try{await $fetch(`/api/secrets/${$.value.key}`,{method:"DELETE"}),i.add({title:"Secret deleted",color:"success"}),P.value=!1,$.value=null,await O()}catch{i.add({title:"Failed to delete secret",color:"error"})}}function ge(n){return new Date(n).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}const b=r({...te}),G=r(!1),H=r(!1),E=r(new Set),be=[{key:"task",label:"Tasks",icon:"i-lucide-check-square",subtypes:["create","edit","delete","restore"]},{key:"project",label:"Projects",icon:"i-lucide-folder",subtypes:["create","edit","delete"]},{key:"agent",label:"Agents",icon:"i-lucide-bot",subtypes:["create","edit","delete","run","complete","fail","cancel"]},{key:"document",label:"Documents",icon:"i-lucide-file-text",subtypes:["edit","delete","restore"]},{key:"memory",label:"Memories",icon:"i-lucide-brain",subtypes:["create","delete"]},{key:"reminder",label:"Reminders",icon:"i-lucide-bell",subtypes:["create"]},{key:"secret",label:"Secrets",icon:"i-lucide-key-round",subtypes:["create","edit","delete"]},{key:"hook",label:"Hooks",icon:"i-lucide-webhook",subtypes:["create"]},{key:"conversation",label:"Conversations",icon:"i-lucide-message-square",subtypes:["delete"]},{key:"bridge",label:"Bridges",icon:"i-lucide-plug",subtypes:["create","edit","delete","complete","fail"]}];async function we(){G.value=!0;try{const{data:n}=await $fetch("/api/settings");b.value={...te,...n.notifications}}catch{b.value={...te}}G.value=!1}async function _e(){H.value=!0;try{await $fetch("/api/settings",{method:"PUT",body:{notifications:b.value}}),re(b.value),i.add({title:"Notification preferences saved",color:"success"})}catch{i.add({title:"Failed to save preferences",color:"error"})}H.value=!1}function xe(n){E.value.has(n)?E.value.delete(n):E.value.add(n)}function ke(n,e){b.value[n]={...b.value[n],enabled:e}}function he(n,e,Z){const B=b.value[n];b.value[n]={...B,subtypes:{...B?.subtypes,[e]:Z}}}const Q=r([]),W=r(!1),S=r(!1),J=r(!1),C=r(!1),D=r(null),_=A({platform:"telegram",name:""}),X=[{value:"telegram",label:"Telegram",icon:"i-lucide-send"},{value:"discord",label:"Discord",icon:"i-lucide-message-circle"},{value:"imessage",label:"iMessage",icon:"i-lucide-smartphone"},{value:"google",label:"Google Suite",icon:"i-lucide-mail"},{value:"email",label:"Email (IMAP)",icon:"i-lucide-at-sign"}],Pe={connected:"text-success",disconnected:"text-dimmed",error:"text-error",unconfigured:"text-dimmed"};async function M(){W.value=!0;try{const{data:n}=await $fetch("/api/bridges");Q.value=n}catch{i.add({title:"Failed to load integrations",color:"error"})}W.value=!1}function Se(){_.platform="telegram",_.name="",S.value=!0}async function Ce(){if(!_.name){i.add({title:"Name is required",color:"error"});return}J.value=!0;try{await $fetch("/api/bridges",{method:"POST",body:{platform:_.platform,name:_.name}}),i.add({title:"Integration created",color:"success"}),S.value=!1,await M()}catch(n){const e=n;i.add({title:"Failed to create integration",description:e.data?.message,color:"error"})}J.value=!1}async function Ue(n){try{await $fetch(`/api/bridges/${n.id}`,{method:"PUT",body:{enabled:!n.enabled}}),await M()}catch{i.add({title:"Failed to update integration",color:"error"})}}function Ve(n){D.value=n,C.value=!0}async function $e(){if(D.value)try{await $fetch(`/api/bridges/${D.value.id}`,{method:"DELETE"}),i.add({title:"Integration deleted",color:"success"}),C.value=!1,D.value=null,await M()}catch{i.add({title:"Failed to delete integration",color:"error"})}}Ge(()=>{O(),we(),M()});async function Ee(){L.value=!0;const n=await ne({name:V.name});n.error?i.add({title:"Update failed",description:n.error.message,color:"error"}):i.add({title:"Profile updated",description:"Your name has been updated successfully.",color:"success"}),L.value=!1}async function De(){if(!h.newEmail){i.add({title:"Email required",description:"Please enter a new email address.",color:"error"});return}K.value=!0;const n=await ie(h.newEmail);n.error?i.add({title:"Email change failed",description:n.error.message,color:"error"}):i.add({title:"Email updated",description:"Your email has been changed successfully.",color:"success"}),K.value=!1}async function Ae(){if(m.newPassword!==m.confirmPassword){i.add({title:"Passwords do not match",description:"Please make sure your new passwords match.",color:"error"});return}if(!m.currentPassword||!m.newPassword){i.add({title:"Missing fields",description:"Please fill in all password fields.",color:"error"});return}q.value=!0;const n=await de({currentPassword:m.currentPassword,newPassword:m.newPassword});n.error?i.add({title:"Password change failed",description:n.error.message,color:"error"}):(i.add({title:"Password changed",description:"Your password has been changed successfully.",color:"success"}),m.currentPassword="",m.newPassword="",m.confirmPassword=""),q.value=!1}return(n,e)=>{const Z=ze,B=Le,x=Ke,w=qe,u=Qe,F=Xe,le=Ze,j=We,Ne=et,U=tt,ee=st,Te=lt,Me=at,z=ot,Be=nt,Fe=Ie;return f(),He(Fe,{id:"settings",grow:""},{default:o(()=>[s(B,{title:"Settings"},{right:o(()=>[s(Z)]),_:1}),l("div",rt,[s(Me,null,{fallback:o(()=>[l("div",jt,[s(U,{class:"h-10 w-full"}),l("div",zt,[s(U,{class:"h-5 w-20"}),s(U,{class:"h-10 w-full"}),s(U,{class:"h-10 w-28"})])])]),default:o(()=>[s(Te,{items:ue,"default-value":"account",class:"w-full mx-auto",ui:{list:"max-w-xl"}},{account:o(()=>[l("div",ut,[l("div",null,[e[19]||(e[19]=l("h3",{class:"text-lg font-semibold mb-4"}," Profile ",-1)),s(F,{state:a(V),class:"space-y-4",onSubmit:Ee},{default:o(()=>[s(w,{label:"Name",name:"name"},{default:o(()=>[s(x,{modelValue:a(V).name,"onUpdate:modelValue":e[0]||(e[0]=t=>a(V).name=t),placeholder:"Your name",class:"w-full"},null,8,["modelValue"])]),_:1}),s(u,{type:"submit",loading:a(L)},{default:o(()=>[...e[18]||(e[18]=[c(" Save Name ",-1)])]),_:1},8,["loading"])]),_:1},8,["state"])]),s(le),l("div",null,[e[21]||(e[21]=l("h3",{class:"text-lg font-semibold mb-4"}," Email Address ",-1)),s(F,{state:a(h),class:"space-y-4",onSubmit:De},{default:o(()=>[s(w,{label:"Email",name:"newEmail"},{default:o(()=>[s(x,{modelValue:a(h).newEmail,"onUpdate:modelValue":e[1]||(e[1]=t=>a(h).newEmail=t),type:"email",placeholder:"your@email.com",class:"w-full"},null,8,["modelValue"])]),_:1}),s(u,{type:"submit",loading:a(K)},{default:o(()=>[...e[20]||(e[20]=[c(" Change Email ",-1)])]),_:1},8,["loading"])]),_:1},8,["state"])]),s(le),l("div",null,[e[23]||(e[23]=l("h3",{class:"text-lg font-semibold mb-4"}," Change Password ",-1)),s(F,{state:a(m),class:"space-y-4",onSubmit:Ae},{default:o(()=>[s(w,{label:"Current Password",name:"currentPassword"},{default:o(()=>[s(x,{modelValue:a(m).currentPassword,"onUpdate:modelValue":e[2]||(e[2]=t=>a(m).currentPassword=t),type:"password",class:"w-full"},null,8,["modelValue"])]),_:1}),s(w,{label:"New Password",name:"newPassword"},{default:o(()=>[s(x,{modelValue:a(m).newPassword,"onUpdate:modelValue":e[3]||(e[3]=t=>a(m).newPassword=t),type:"password",class:"w-full"},null,8,["modelValue"])]),_:1}),s(w,{label:"Confirm New Password",name:"confirmPassword"},{default:o(()=>[s(x,{modelValue:a(m).confirmPassword,"onUpdate:modelValue":e[4]||(e[4]=t=>a(m).confirmPassword=t),type:"password",class:"w-full"},null,8,["modelValue"])]),_:1}),s(u,{type:"submit",loading:a(q)},{default:o(()=>[...e[22]||(e[22]=[c(" Change Password ",-1)])]),_:1},8,["loading"])]),_:1},8,["state"])])])]),secrets:o(()=>[l("div",ct,[l("div",mt,[e[25]||(e[25]=l("div",null,[l("h3",{class:"text-lg font-semibold"}," Secrets "),l("p",{class:"text-sm text-dimmed"}," Encrypted key-value store for skills and integrations. ")],-1)),s(u,{icon:"i-lucide-plus",onClick:me},{default:o(()=>[...e[24]||(e[24]=[c(" Add Secret ",-1)])]),_:1})]),s(Ne,{columns:ce,data:a(se),loading:a(R)},{"key-cell":o(({row:t})=>[l("code",pt,g(t.original.key),1)]),"description-cell":o(({row:t})=>[l("span",ft,g(t.original.description||"—"),1)]),"updatedAt-cell":o(({row:t})=>[l("span",vt,g(ge(t.original.updatedAt)),1)]),"actions-cell":o(({row:t})=>[l("div",yt,[s(u,{variant:"ghost",icon:"i-lucide-pencil",size:"xs",onClick:p=>pe(t.original)},null,8,["onClick"]),s(u,{variant:"ghost",color:"error",icon:"i-lucide-trash-2",size:"xs",onClick:p=>fe(t.original)},null,8,["onClick"])])]),empty:o(()=>[l("div",gt,[s(j,{name:"i-lucide-key",class:"size-12 mx-auto mb-4 text-dimmed"}),e[26]||(e[26]=l("p",{class:"text-dimmed"}," No secrets yet. Add one to get started. ",-1))])]),_:1},8,["data","loading"])])]),integrations:o(()=>[l("div",bt,[l("div",wt,[e[28]||(e[28]=l("div",null,[l("h3",{class:"text-lg font-semibold"}," Integrations "),l("p",{class:"text-sm text-dimmed"}," Connect external platforms to the message bridge. ")],-1)),s(u,{icon:"i-lucide-plus",onClick:Se},{default:o(()=>[...e[27]||(e[27]=[c(" Add Integration ",-1)])]),_:1})]),a(W)?(f(),v("div",_t,[(f(),v(N,null,T(3,t=>s(U,{key:t,class:"h-16 w-full"})),64))])):a(Q).length===0?(f(),v("div",xt,[s(j,{name:"i-lucide-plug",class:"size-12 mx-auto mb-4 text-dimmed"}),e[29]||(e[29]=l("p",{class:"text-dimmed"}," No integrations configured. ",-1)),e[30]||(e[30]=l("p",{class:"text-sm text-dimmed mt-1"}," Connect Telegram, Discord, iMessage, or Google Suite. ",-1))])):(f(),v("div",kt,[(f(!0),v(N,null,T(a(Q),t=>(f(),v("div",{key:t.id,class:"border border-default rounded-lg px-4 py-3"},[l("div",ht,[l("div",Pt,[s(j,{name:X.find(p=>p.value===t.platform)?.icon||"i-lucide-plug",class:"size-5 text-dimmed"},null,8,["name"]),l("div",null,[l("span",St,g(t.name),1),l("span",Ct,g(X.find(p=>p.value===t.platform)?.label),1)])]),l("div",Ut,[l("span",{class:Je(["text-xs capitalize",Pe[t.healthStatus]||"text-dimmed"])},g(t.healthStatus),3),s(ee,{"model-value":t.enabled,"onUpdate:modelValue":p=>Ue(t)},null,8,["model-value","onUpdate:modelValue"]),s(u,{variant:"ghost",color:"error",icon:"i-lucide-trash-2",size:"xs",onClick:p=>Ve(t)},null,8,["onClick"])])]),t.healthMessage?(f(),v("p",Vt,g(t.healthMessage),1)):ae("",!0)]))),128))]))])]),app:o(()=>[l("div",$t,[e[32]||(e[32]=l("div",{class:"mb-6"},[l("h3",{class:"text-lg font-semibold mb-1"}," Notification Preferences "),l("p",{class:"text-sm text-dimmed"}," Choose which resource changes show toast notifications. ")],-1)),a(G)?(f(),v("div",Et,[(f(),v(N,null,T(5,t=>s(U,{key:t,class:"h-12 w-full"})),64))])):(f(),v("div",Dt,[(f(),v(N,null,T(be,t=>l("div",{key:t.key,class:"border border-default rounded-lg"},[l("div",At,[l("div",Nt,[s(u,{variant:"ghost",size:"xs",icon:a(E).has(t.key)?"i-lucide-chevron-down":"i-lucide-chevron-right",onClick:p=>xe(t.key)},null,8,["icon","onClick"]),s(j,{name:t.icon,class:"size-5 text-dimmed"},null,8,["name"]),l("span",Tt,g(t.label),1)]),s(ee,{"model-value":a(b)[t.key]?.enabled??!1,"onUpdate:modelValue":p=>ke(t.key,p)},null,8,["model-value","onUpdate:modelValue"])]),a(E).has(t.key)&&a(b)[t.key]?.enabled?(f(),v("div",Mt,[(f(!0),v(N,null,T(t.subtypes,p=>(f(),v("div",{key:p,class:"flex items-center justify-between pl-11"},[l("span",Bt,g(p),1),s(ee,{"model-value":a(b)[t.key]?.subtypes?.[p]!==!1,size:"sm","onUpdate:modelValue":je=>he(t.key,p,je)},null,8,["model-value","onUpdate:modelValue"])]))),128))])):ae("",!0)])),64))])),l("div",Ft,[s(u,{loading:a(H),onClick:_e},{default:o(()=>[...e[31]||(e[31]=[c(" Save Preferences ",-1)])]),_:1},8,["loading"])])])]),_:1})]),_:1})]),s(z,{open:a(k),"onUpdate:open":e[9]||(e[9]=t=>I(k)?k.value=t:null)},{header:o(()=>[l("h3",It,g(a(y)?"Edit Secret":"Add Secret"),1)]),body:o(()=>[s(F,{state:a(d),class:"space-y-4",onSubmit:ve},{default:o(()=>[s(w,{label:"Key",name:"key",hint:a(y)?"":"SCREAMING_SNAKE_CASE"},{default:o(()=>[s(x,{modelValue:a(d).key,"onUpdate:modelValue":e[5]||(e[5]=t=>a(d).key=t),disabled:!!a(y),placeholder:"MY_API_KEY",class:"w-full font-mono"},null,8,["modelValue","disabled"])]),_:1},8,["hint"]),s(w,{label:"Value",name:"value",hint:a(y)?"Leave empty to keep current value":""},{default:o(()=>[s(x,{modelValue:a(d).value,"onUpdate:modelValue":e[6]||(e[6]=t=>a(d).value=t),type:"password",placeholder:a(y)?"••••••••":"Secret value",class:"w-full"},null,8,["modelValue","placeholder"])]),_:1},8,["hint"]),s(w,{label:"Description",name:"description"},{default:o(()=>[s(x,{modelValue:a(d).description,"onUpdate:modelValue":e[7]||(e[7]=t=>a(d).description=t),placeholder:"Optional description",class:"w-full"},null,8,["modelValue"])]),_:1}),l("div",Lt,[s(u,{variant:"ghost",onClick:e[8]||(e[8]=t=>k.value=!1)},{default:o(()=>[...e[33]||(e[33]=[c(" Cancel ",-1)])]),_:1}),s(u,{type:"submit",loading:a(Y)},{default:o(()=>[c(g(a(y)?"Update":"Create"),1)]),_:1},8,["loading"])])]),_:1},8,["state"])]),_:1},8,["open"]),s(z,{open:a(P),"onUpdate:open":e[11]||(e[11]=t=>I(P)?P.value=t:null)},{header:o(()=>[...e[34]||(e[34]=[l("h3",{class:"text-lg font-semibold"}," Delete Secret ",-1)])]),body:o(()=>[l("p",Kt,[e[35]||(e[35]=c(" Are you sure you want to delete ",-1)),l("code",qt,g(a($)?.key),1),e[36]||(e[36]=c("? ",-1))]),e[39]||(e[39]=l("p",{class:"text-sm text-dimmed"}," This action cannot be undone. Any skills using this secret will stop working. ",-1)),l("div",Rt,[s(u,{variant:"ghost",onClick:e[10]||(e[10]=t=>P.value=!1)},{default:o(()=>[...e[37]||(e[37]=[c(" Cancel ",-1)])]),_:1}),s(u,{color:"error",onClick:ye},{default:o(()=>[...e[38]||(e[38]=[c(" Delete ",-1)])]),_:1})])]),_:1},8,["open"]),s(z,{open:a(S),"onUpdate:open":e[15]||(e[15]=t=>I(S)?S.value=t:null)},{header:o(()=>[...e[40]||(e[40]=[l("h3",{class:"text-lg font-semibold"}," Add Integration ",-1)])]),body:o(()=>[l("div",Yt,[s(w,{label:"Platform",name:"platform"},{default:o(()=>[s(Be,{modelValue:a(_).platform,"onUpdate:modelValue":e[12]||(e[12]=t=>a(_).platform=t),items:X,"value-key":"value",class:"w-full"},null,8,["modelValue"])]),_:1}),s(w,{label:"Name",name:"name"},{default:o(()=>[s(x,{modelValue:a(_).name,"onUpdate:modelValue":e[13]||(e[13]=t=>a(_).name=t),placeholder:"My Telegram Bot",class:"w-full"},null,8,["modelValue"])]),_:1}),l("div",Ot,[s(u,{variant:"ghost",onClick:e[14]||(e[14]=t=>S.value=!1)},{default:o(()=>[...e[41]||(e[41]=[c(" Cancel ",-1)])]),_:1}),s(u,{loading:a(J),onClick:Ce},{default:o(()=>[...e[42]||(e[42]=[c(" Create ",-1)])]),_:1},8,["loading"])])])]),_:1},8,["open"]),s(z,{open:a(C),"onUpdate:open":e[17]||(e[17]=t=>I(C)?C.value=t:null)},{header:o(()=>[...e[43]||(e[43]=[l("h3",{class:"text-lg font-semibold"}," Delete Integration ",-1)])]),body:o(()=>[l("p",Gt,[e[44]||(e[44]=c(" Are you sure you want to delete ",-1)),l("strong",null,g(a(D)?.name),1),e[45]||(e[45]=c("? ",-1))]),e[48]||(e[48]=l("p",{class:"text-sm text-dimmed"}," This will remove the integration and all associated message history. ",-1)),l("div",Ht,[s(u,{variant:"ghost",onClick:e[16]||(e[16]=t=>C.value=!1)},{default:o(()=>[...e[46]||(e[46]=[c(" Cancel ",-1)])]),_:1}),s(u,{color:"error",onClick:$e},{default:o(()=>[...e[47]||(e[47]=[c(" Delete ",-1)])]),_:1})])]),_:1},8,["open"])]),_:1})}}});export{Ts as default};
@@ -1 +0,0 @@
1
- import{r as l}from"./BaVaTug8.js";import{N as c,c as p,Q as n,R as u,S as i,U as m,al as s}from"./CvMqUdkl.js";import{_ as d}from"./Zjvb5YJR.js";import"./iik6CYzq.js";const f={base:"rounded-full"},v={__name:"ProseBadge",props:{class:{type:null,required:!1}},setup(a){const e=a,o=c(),r=p(()=>s({extend:s(f),...o.ui?.prose?.badge||{}}));return(t,_)=>(u(),n(d,{color:"primary",variant:"subtle",class:m(r.value({class:e.class}))},{default:i(()=>[l(t.$slots,"default",{mdcUnwrap:"p"})]),_:3},8,["class"]))}};export{v as default};
@@ -1 +0,0 @@
1
- {"id":"9863fe43-d78c-4b29-a1e8-e6de61119507","timestamp":1771726473975,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -1 +0,0 @@
1
- import{d as a,n as i}from"./CvMqUdkl.js";import{u}from"./BNlugvM3.js";const r=a(()=>{const{isAuthenticated:e,isPending:t}=u();if(!t.value&&!e.value)return i("/login")});export{r as default};