@commandable/mcp 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/README.md +28 -31
  2. package/dist/app/nitro.json +15 -0
  3. package/dist/app/public/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2 +0 -0
  4. package/dist/app/public/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2 +0 -0
  5. package/dist/app/public/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2 +0 -0
  6. package/dist/app/public/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2 +0 -0
  7. package/dist/app/public/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2 +0 -0
  8. package/dist/app/public/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2 +0 -0
  9. package/dist/app/public/_nuxt/-tOYwuj2.js +30 -0
  10. package/dist/app/public/_nuxt/BdctKXor.js +1 -0
  11. package/dist/app/public/_nuxt/BlP7Uu-5.js +1 -0
  12. package/dist/app/public/_nuxt/CsbkV5Bd.js +1 -0
  13. package/dist/app/public/_nuxt/D-43HurL.js +59 -0
  14. package/dist/app/public/_nuxt/DU1mG77A.js +1 -0
  15. package/dist/app/public/_nuxt/_id_.BKAjWkoP.css +1 -0
  16. package/dist/app/public/_nuxt/builds/latest.json +1 -0
  17. package/dist/app/public/_nuxt/builds/meta/ceae497c-21d6-4278-8cc9-3c2c80f03dca.json +1 -0
  18. package/dist/app/public/_nuxt/entry.Y3mA4bzA.css +1 -0
  19. package/dist/app/public/_nuxt/error-404.C7fg894-.css +1 -0
  20. package/dist/app/public/_nuxt/error-500.DjUK_N2Y.css +1 -0
  21. package/dist/app/public/_nuxt/uS7FY2am.js +1 -0
  22. package/dist/app/public/favicon.ico +0 -0
  23. package/dist/app/server/chunks/_/error-500.mjs +19 -0
  24. package/dist/app/server/chunks/_/error-500.mjs.map +1 -0
  25. package/dist/app/server/chunks/_/icons.mjs +5933 -0
  26. package/dist/app/server/chunks/_/icons.mjs.map +1 -0
  27. package/dist/app/server/chunks/_/icons2.mjs +11338 -0
  28. package/dist/app/server/chunks/_/icons2.mjs.map +1 -0
  29. package/dist/app/server/chunks/build/IntegrationCredentials-styles.CULcCK6_.mjs +8 -0
  30. package/dist/app/server/chunks/build/IntegrationCredentials-styles.CULcCK6_.mjs.map +1 -0
  31. package/dist/app/server/chunks/build/_id_-DBwSV4AY.mjs +1354 -0
  32. package/dist/app/server/chunks/build/_id_-DBwSV4AY.mjs.map +1 -0
  33. package/dist/app/server/chunks/build/client.precomputed.mjs +4 -0
  34. package/dist/app/server/chunks/build/client.precomputed.mjs.map +1 -0
  35. package/dist/app/server/chunks/build/error-404-D2QibUBT.mjs +121 -0
  36. package/dist/app/server/chunks/build/error-404-D2QibUBT.mjs.map +1 -0
  37. package/dist/app/server/chunks/build/error-404-styles.Bvxdxqjk.mjs +8 -0
  38. package/dist/app/server/chunks/build/error-404-styles.Bvxdxqjk.mjs.map +1 -0
  39. package/dist/app/server/chunks/build/error-500-DYvawybF.mjs +104 -0
  40. package/dist/app/server/chunks/build/error-500-DYvawybF.mjs.map +1 -0
  41. package/dist/app/server/chunks/build/error-500-styles.BnYAAXSg.mjs +8 -0
  42. package/dist/app/server/chunks/build/error-500-styles.BnYAAXSg.mjs.map +1 -0
  43. package/dist/app/server/chunks/build/fetch-ZbqIFhDG.mjs +2851 -0
  44. package/dist/app/server/chunks/build/fetch-ZbqIFhDG.mjs.map +1 -0
  45. package/dist/app/server/chunks/build/index-5H-nmhph.mjs +68 -0
  46. package/dist/app/server/chunks/build/index-5H-nmhph.mjs.map +1 -0
  47. package/dist/app/server/chunks/build/index-C8flTcKI.mjs +720 -0
  48. package/dist/app/server/chunks/build/index-C8flTcKI.mjs.map +1 -0
  49. package/dist/app/server/chunks/build/server.mjs +8736 -0
  50. package/dist/app/server/chunks/build/server.mjs.map +1 -0
  51. package/dist/app/server/chunks/build/styles.mjs +12 -0
  52. package/dist/app/server/chunks/build/styles.mjs.map +1 -0
  53. package/dist/app/server/chunks/nitro/nitro.mjs +9359 -0
  54. package/dist/app/server/chunks/nitro/nitro.mjs.map +1 -0
  55. package/dist/app/server/chunks/routes/api/_commandable/status.get.mjs +59 -0
  56. package/dist/app/server/chunks/routes/api/_commandable/status.get.mjs.map +1 -0
  57. package/dist/app/server/chunks/routes/api/catalog/_type/tools.get.mjs +40 -0
  58. package/dist/app/server/chunks/routes/api/catalog/_type/tools.get.mjs.map +1 -0
  59. package/dist/app/server/chunks/routes/api/catalog/_type/toolsets.get.mjs +41 -0
  60. package/dist/app/server/chunks/routes/api/catalog/_type/toolsets.get.mjs.map +1 -0
  61. package/dist/app/server/chunks/routes/api/catalog.get.mjs +46 -0
  62. package/dist/app/server/chunks/routes/api/catalog.get.mjs.map +1 -0
  63. package/dist/app/server/chunks/routes/api/index.get.mjs +39 -0
  64. package/dist/app/server/chunks/routes/api/index.get.mjs.map +1 -0
  65. package/dist/app/server/chunks/routes/api/index.post.mjs +60 -0
  66. package/dist/app/server/chunks/routes/api/index.post.mjs.map +1 -0
  67. package/dist/app/server/chunks/routes/api/integrations/_id/credentials-config.get.mjs +63 -0
  68. package/dist/app/server/chunks/routes/api/integrations/_id/credentials-config.get.mjs.map +1 -0
  69. package/dist/app/server/chunks/routes/api/integrations/_id/credentials-status.get.mjs +70 -0
  70. package/dist/app/server/chunks/routes/api/integrations/_id/credentials-status.get.mjs.map +1 -0
  71. package/dist/app/server/chunks/routes/api/integrations/_id/credentials.delete.mjs +61 -0
  72. package/dist/app/server/chunks/routes/api/integrations/_id/credentials.delete.mjs.map +1 -0
  73. package/dist/app/server/chunks/routes/api/integrations/_id/credentials.post.mjs +94 -0
  74. package/dist/app/server/chunks/routes/api/integrations/_id/credentials.post.mjs.map +1 -0
  75. package/dist/app/server/chunks/routes/api/integrations/_id/permissions.post.mjs +54 -0
  76. package/dist/app/server/chunks/routes/api/integrations/_id/permissions.post.mjs.map +1 -0
  77. package/dist/app/server/chunks/routes/api/integrations/_id/toolsets.post.mjs +53 -0
  78. package/dist/app/server/chunks/routes/api/integrations/_id/toolsets.post.mjs.map +1 -0
  79. package/dist/app/server/chunks/routes/api/integrations/_id_.delete.mjs +44 -0
  80. package/dist/app/server/chunks/routes/api/integrations/_id_.delete.mjs.map +1 -0
  81. package/dist/app/server/chunks/routes/health.get.mjs +37 -0
  82. package/dist/app/server/chunks/routes/health.get.mjs.map +1 -0
  83. package/dist/app/server/chunks/routes/mcp/create.mjs +56 -0
  84. package/dist/app/server/chunks/routes/mcp/create.mjs.map +1 -0
  85. package/dist/app/server/chunks/routes/mcp.mjs +56 -0
  86. package/dist/app/server/chunks/routes/mcp.mjs.map +1 -0
  87. package/dist/app/server/chunks/routes/renderer.mjs +492 -0
  88. package/dist/app/server/chunks/routes/renderer.mjs.map +1 -0
  89. package/dist/app/server/chunks/virtual/_virtual_spa-template.mjs +4 -0
  90. package/dist/app/server/chunks/virtual/_virtual_spa-template.mjs.map +1 -0
  91. package/dist/app/server/index.mjs +31 -0
  92. package/dist/app/server/index.mjs.map +1 -0
  93. package/dist/app/server/migrations/pg/0000_initial.sql +74 -0
  94. package/dist/app/server/migrations/pg/meta/_journal.json +13 -0
  95. package/dist/app/server/migrations/sqlite/0000_initial.sql +74 -0
  96. package/dist/app/server/migrations/sqlite/meta/_journal.json +13 -0
  97. package/dist/app/server/package.json +108 -0
  98. package/dist/cli/credentialManager.d.ts.map +1 -1
  99. package/dist/cli/credentialManager.js +5 -4
  100. package/dist/cli/credentialManager.js.map +1 -1
  101. package/dist/cli/index.d.ts +15 -0
  102. package/dist/cli/index.d.ts.map +1 -1
  103. package/dist/cli/index.js +656 -17
  104. package/dist/cli/index.js.map +1 -1
  105. package/dist/cli/setup.d.ts.map +1 -1
  106. package/dist/cli/setup.js +172 -36
  107. package/dist/cli/setup.js.map +1 -1
  108. package/dist/config/configApply.d.ts.map +1 -1
  109. package/dist/config/configApply.js +4 -1
  110. package/dist/config/configApply.js.map +1 -1
  111. package/dist/config/configSchema.d.ts +18 -2
  112. package/dist/config/configSchema.d.ts.map +1 -1
  113. package/dist/config/configSchema.js +7 -1
  114. package/dist/config/configSchema.js.map +1 -1
  115. package/dist/db/client.d.ts +3 -1
  116. package/dist/db/client.d.ts.map +1 -1
  117. package/dist/db/client.js.map +1 -1
  118. package/dist/db/credentialStore.d.ts +2 -0
  119. package/dist/db/credentialStore.d.ts.map +1 -1
  120. package/dist/db/credentialStore.js +15 -16
  121. package/dist/db/credentialStore.js.map +1 -1
  122. package/dist/db/integrationStore.d.ts +7 -0
  123. package/dist/db/integrationStore.d.ts.map +1 -1
  124. package/dist/db/integrationStore.js +64 -21
  125. package/dist/db/integrationStore.js.map +1 -1
  126. package/dist/db/integrationTypeConfigStore.d.ts +6 -0
  127. package/dist/db/integrationTypeConfigStore.d.ts.map +1 -0
  128. package/dist/db/integrationTypeConfigStore.js +94 -0
  129. package/dist/db/integrationTypeConfigStore.js.map +1 -0
  130. package/dist/db/migrate.d.ts.map +1 -1
  131. package/dist/db/migrate.js +8 -87
  132. package/dist/db/migrate.js.map +1 -1
  133. package/dist/db/migrations/pg/0000_initial.sql +74 -0
  134. package/dist/db/migrations/pg/meta/_journal.json +13 -0
  135. package/dist/db/migrations/sqlite/0000_initial.sql +74 -0
  136. package/dist/db/migrations/sqlite/meta/_journal.json +13 -0
  137. package/dist/db/schema.d.ts +1049 -133
  138. package/dist/db/schema.d.ts.map +1 -1
  139. package/dist/db/schema.js +61 -3
  140. package/dist/db/schema.js.map +1 -1
  141. package/dist/db/toolDefinitionStore.d.ts +6 -0
  142. package/dist/db/toolDefinitionStore.d.ts.map +1 -0
  143. package/dist/db/toolDefinitionStore.js +95 -0
  144. package/dist/db/toolDefinitionStore.js.map +1 -0
  145. package/dist/index.d.ts +7 -0
  146. package/dist/index.d.ts.map +1 -1
  147. package/dist/index.js +7 -0
  148. package/dist/index.js.map +1 -1
  149. package/dist/integrations/actionsFactory.d.ts +5 -1
  150. package/dist/integrations/actionsFactory.d.ts.map +1 -1
  151. package/dist/integrations/actionsFactory.js +46 -16
  152. package/dist/integrations/actionsFactory.js.map +1 -1
  153. package/dist/integrations/customToolFactory.d.ts +13 -0
  154. package/dist/integrations/customToolFactory.d.ts.map +1 -0
  155. package/dist/integrations/customToolFactory.js +31 -0
  156. package/dist/integrations/customToolFactory.js.map +1 -0
  157. package/dist/integrations/dataLoader.d.ts +2 -2
  158. package/dist/integrations/dataLoader.d.ts.map +1 -1
  159. package/dist/integrations/dataLoader.js +1 -1
  160. package/dist/integrations/dataLoader.js.map +1 -1
  161. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts +7 -0
  162. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts.map +1 -0
  163. package/dist/integrations/fileIntegrationTypeConfigStore.js +34 -0
  164. package/dist/integrations/fileIntegrationTypeConfigStore.js.map +1 -0
  165. package/dist/integrations/getIntegration.d.ts +4 -1
  166. package/dist/integrations/getIntegration.d.ts.map +1 -1
  167. package/dist/integrations/getIntegration.js +12 -4
  168. package/dist/integrations/getIntegration.js.map +1 -1
  169. package/dist/integrations/health.d.ts +20 -0
  170. package/dist/integrations/health.d.ts.map +1 -0
  171. package/dist/integrations/health.js +43 -0
  172. package/dist/integrations/health.js.map +1 -0
  173. package/dist/integrations/integrationTypeConfigLookup.d.ts +12 -0
  174. package/dist/integrations/integrationTypeConfigLookup.d.ts.map +1 -0
  175. package/dist/integrations/integrationTypeConfigLookup.js +11 -0
  176. package/dist/integrations/integrationTypeConfigLookup.js.map +1 -0
  177. package/dist/integrations/providerRegistry.d.ts.map +1 -1
  178. package/dist/integrations/providerRegistry.js +22 -8
  179. package/dist/integrations/providerRegistry.js.map +1 -1
  180. package/dist/integrations/proxy.d.ts +4 -1
  181. package/dist/integrations/proxy.d.ts.map +1 -1
  182. package/dist/integrations/proxy.js +109 -94
  183. package/dist/integrations/proxy.js.map +1 -1
  184. package/dist/integrations/sandbox.d.ts +2 -1
  185. package/dist/integrations/sandbox.d.ts.map +1 -1
  186. package/dist/integrations/sandbox.js +13 -2
  187. package/dist/integrations/sandbox.js.map +1 -1
  188. package/dist/integrations/sandboxUtils.d.ts +15 -0
  189. package/dist/integrations/sandboxUtils.d.ts.map +1 -0
  190. package/dist/integrations/sandboxUtils.js +489 -0
  191. package/dist/integrations/sandboxUtils.js.map +1 -0
  192. package/dist/mcp/abilityCatalog.d.ts +46 -0
  193. package/dist/mcp/abilityCatalog.d.ts.map +1 -0
  194. package/dist/mcp/abilityCatalog.js +275 -0
  195. package/dist/mcp/abilityCatalog.js.map +1 -0
  196. package/dist/mcp/builder_guide.md +441 -0
  197. package/dist/mcp/commandable_readme.md +29 -0
  198. package/dist/mcp/handlers.d.ts +10 -1
  199. package/dist/mcp/handlers.d.ts.map +1 -1
  200. package/dist/mcp/handlers.js +51 -4
  201. package/dist/mcp/handlers.js.map +1 -1
  202. package/dist/mcp/metaTools.d.ts +77 -0
  203. package/dist/mcp/metaTools.d.ts.map +1 -0
  204. package/dist/mcp/metaTools.js +753 -0
  205. package/dist/mcp/metaTools.js.map +1 -0
  206. package/dist/mcp/server.d.ts +10 -0
  207. package/dist/mcp/server.d.ts.map +1 -1
  208. package/dist/mcp/server.js +2 -2
  209. package/dist/mcp/server.js.map +1 -1
  210. package/dist/mcp/sessionState.d.ts +18 -0
  211. package/dist/mcp/sessionState.d.ts.map +1 -0
  212. package/dist/mcp/sessionState.js +65 -0
  213. package/dist/mcp/sessionState.js.map +1 -0
  214. package/dist/mcp/toolAdapter.d.ts +17 -0
  215. package/dist/mcp/toolAdapter.d.ts.map +1 -1
  216. package/dist/mcp/toolAdapter.js +7 -1
  217. package/dist/mcp/toolAdapter.js.map +1 -1
  218. package/dist/types.d.ts +66 -2
  219. package/dist/types.d.ts.map +1 -1
  220. package/dist/version.d.ts +2 -0
  221. package/dist/version.d.ts.map +1 -0
  222. package/dist/version.js +7 -0
  223. package/dist/version.js.map +1 -0
  224. package/package.json +13 -9
@@ -0,0 +1,1354 @@
1
+ import { k as useRoute, m as _sfc_main$b, i as _sfc_main$h, a as __nuxt_component_0$1, g as _sfc_main$m, _ as _export_sfc, n as navigateTo, j as _sfc_main$9, b as useAppConfig, c as useComponentUI, d as useFormField, e as useFieldGroup, f as useComponentIcons, t as tv, h as _sfc_main$k, l as looseToNumber } from './server.mjs';
2
+ import { u as useFetch, _ as _sfc_main$4, a as _sfc_main$3, b as __nuxt_component_3, c as _sfc_main$2$1, d as _sfc_main$1$1 } from './fetch-ZbqIFhDG.mjs';
3
+ import { defineComponent, withAsyncContext, computed, ref, watch, mergeProps, withCtx, unref, createTextVNode, createVNode, toDisplayString, isRef, openBlock, createBlock, Fragment, createCommentVNode, reactive, renderList, useSlots, useTemplateRef, renderSlot, useSSRContext } from 'vue';
4
+ import { ssrRenderComponent, ssrInterpolate, ssrRenderClass, ssrRenderAttrs, ssrRenderList, ssrRenderSlot } from 'vue/server-renderer';
5
+ import { Primitive } from 'reka-ui';
6
+ import { useVModel } from '@vueuse/core';
7
+ import { marked } from 'marked';
8
+ import '../nitro/nitro.mjs';
9
+ import '@modelcontextprotocol/sdk/types.js';
10
+ import '@modelcontextprotocol/sdk/server/index.js';
11
+ import '@modelcontextprotocol/sdk/server/streamableHttp.js';
12
+ import 'node:crypto';
13
+ import 'fastest-levenshtein';
14
+ import 'node:fs';
15
+ import 'node:path';
16
+ import 'node:url';
17
+ import 'node:vm';
18
+ import 'turndown';
19
+ import 'drizzle-orm';
20
+ import 'node:buffer';
21
+ import 'google-auth-library';
22
+ import 'node:http';
23
+ import 'node:https';
24
+ import 'node:events';
25
+ import 'node:os';
26
+ import 'better-sqlite3';
27
+ import 'drizzle-orm/better-sqlite3';
28
+ import 'drizzle-orm/node-postgres';
29
+ import 'pg';
30
+ import 'node:process';
31
+ import 'js-yaml';
32
+ import 'zod';
33
+ import 'drizzle-orm/sqlite-core';
34
+ import 'drizzle-orm/pg-core';
35
+ import '@iconify/utils';
36
+ import 'consola';
37
+ import 'vue-router';
38
+ import 'tailwindcss/colors';
39
+ import '@iconify/vue';
40
+ import 'tailwind-variants';
41
+ import '@iconify/utils/lib/css/icon';
42
+ import 'perfect-debounce';
43
+ import 'vaul-vue';
44
+ import '../routes/renderer.mjs';
45
+ import 'vue-bundle-renderer/runtime';
46
+ import 'unhead/server';
47
+ import 'devalue';
48
+ import 'unhead/plugins';
49
+ import 'unhead/utils';
50
+ import '@vue/shared';
51
+
52
+ const theme = {
53
+ "slots": {
54
+ "root": "relative inline-flex items-center",
55
+ "base": [
56
+ "w-full rounded-md border-0 appearance-none placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75",
57
+ "transition-colors"
58
+ ],
59
+ "leading": "absolute inset-y-0 start-0 flex items-center",
60
+ "leadingIcon": "shrink-0 text-dimmed",
61
+ "leadingAvatar": "shrink-0",
62
+ "leadingAvatarSize": "",
63
+ "trailing": "absolute inset-y-0 end-0 flex items-center",
64
+ "trailingIcon": "shrink-0 text-dimmed"
65
+ },
66
+ "variants": {
67
+ "fieldGroup": {
68
+ "horizontal": {
69
+ "root": "group has-focus-visible:z-[1]",
70
+ "base": "group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none"
71
+ },
72
+ "vertical": {
73
+ "root": "group has-focus-visible:z-[1]",
74
+ "base": "group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none"
75
+ }
76
+ },
77
+ "size": {
78
+ "xs": {
79
+ "base": "px-2 py-1 text-sm/4 gap-1",
80
+ "leading": "ps-2",
81
+ "trailing": "pe-2",
82
+ "leadingIcon": "size-4",
83
+ "leadingAvatarSize": "3xs",
84
+ "trailingIcon": "size-4"
85
+ },
86
+ "sm": {
87
+ "base": "px-2.5 py-1.5 text-sm/4 gap-1.5",
88
+ "leading": "ps-2.5",
89
+ "trailing": "pe-2.5",
90
+ "leadingIcon": "size-4",
91
+ "leadingAvatarSize": "3xs",
92
+ "trailingIcon": "size-4"
93
+ },
94
+ "md": {
95
+ "base": "px-2.5 py-1.5 text-base/5 gap-1.5",
96
+ "leading": "ps-2.5",
97
+ "trailing": "pe-2.5",
98
+ "leadingIcon": "size-5",
99
+ "leadingAvatarSize": "2xs",
100
+ "trailingIcon": "size-5"
101
+ },
102
+ "lg": {
103
+ "base": "px-3 py-2 text-base/5 gap-2",
104
+ "leading": "ps-3",
105
+ "trailing": "pe-3",
106
+ "leadingIcon": "size-5",
107
+ "leadingAvatarSize": "2xs",
108
+ "trailingIcon": "size-5"
109
+ },
110
+ "xl": {
111
+ "base": "px-3 py-2 text-base gap-2",
112
+ "leading": "ps-3",
113
+ "trailing": "pe-3",
114
+ "leadingIcon": "size-6",
115
+ "leadingAvatarSize": "xs",
116
+ "trailingIcon": "size-6"
117
+ }
118
+ },
119
+ "variant": {
120
+ "outline": "text-highlighted bg-default ring ring-inset ring-accented",
121
+ "soft": "text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50",
122
+ "subtle": "text-highlighted bg-elevated ring ring-inset ring-accented",
123
+ "ghost": "text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent",
124
+ "none": "text-highlighted bg-transparent"
125
+ },
126
+ "color": {
127
+ "primary": "",
128
+ "secondary": "",
129
+ "success": "",
130
+ "info": "",
131
+ "warning": "",
132
+ "error": "",
133
+ "neutral": ""
134
+ },
135
+ "leading": {
136
+ "true": ""
137
+ },
138
+ "trailing": {
139
+ "true": ""
140
+ },
141
+ "loading": {
142
+ "true": ""
143
+ },
144
+ "highlight": {
145
+ "true": ""
146
+ },
147
+ "fixed": {
148
+ "false": ""
149
+ },
150
+ "type": {
151
+ "file": "file:me-1.5 file:font-medium file:text-muted file:outline-none"
152
+ }
153
+ },
154
+ "compoundVariants": [
155
+ {
156
+ "color": "primary",
157
+ "variant": [
158
+ "outline",
159
+ "subtle"
160
+ ],
161
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary"
162
+ },
163
+ {
164
+ "color": "secondary",
165
+ "variant": [
166
+ "outline",
167
+ "subtle"
168
+ ],
169
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-secondary"
170
+ },
171
+ {
172
+ "color": "success",
173
+ "variant": [
174
+ "outline",
175
+ "subtle"
176
+ ],
177
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success"
178
+ },
179
+ {
180
+ "color": "info",
181
+ "variant": [
182
+ "outline",
183
+ "subtle"
184
+ ],
185
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info"
186
+ },
187
+ {
188
+ "color": "warning",
189
+ "variant": [
190
+ "outline",
191
+ "subtle"
192
+ ],
193
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning"
194
+ },
195
+ {
196
+ "color": "error",
197
+ "variant": [
198
+ "outline",
199
+ "subtle"
200
+ ],
201
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error"
202
+ },
203
+ {
204
+ "color": "primary",
205
+ "highlight": true,
206
+ "class": "ring ring-inset ring-primary"
207
+ },
208
+ {
209
+ "color": "secondary",
210
+ "highlight": true,
211
+ "class": "ring ring-inset ring-secondary"
212
+ },
213
+ {
214
+ "color": "success",
215
+ "highlight": true,
216
+ "class": "ring ring-inset ring-success"
217
+ },
218
+ {
219
+ "color": "info",
220
+ "highlight": true,
221
+ "class": "ring ring-inset ring-info"
222
+ },
223
+ {
224
+ "color": "warning",
225
+ "highlight": true,
226
+ "class": "ring ring-inset ring-warning"
227
+ },
228
+ {
229
+ "color": "error",
230
+ "highlight": true,
231
+ "class": "ring ring-inset ring-error"
232
+ },
233
+ {
234
+ "color": "neutral",
235
+ "variant": [
236
+ "outline",
237
+ "subtle"
238
+ ],
239
+ "class": "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted"
240
+ },
241
+ {
242
+ "color": "neutral",
243
+ "highlight": true,
244
+ "class": "ring ring-inset ring-inverted"
245
+ },
246
+ {
247
+ "leading": true,
248
+ "size": "xs",
249
+ "class": "ps-7"
250
+ },
251
+ {
252
+ "leading": true,
253
+ "size": "sm",
254
+ "class": "ps-8"
255
+ },
256
+ {
257
+ "leading": true,
258
+ "size": "md",
259
+ "class": "ps-9"
260
+ },
261
+ {
262
+ "leading": true,
263
+ "size": "lg",
264
+ "class": "ps-10"
265
+ },
266
+ {
267
+ "leading": true,
268
+ "size": "xl",
269
+ "class": "ps-11"
270
+ },
271
+ {
272
+ "trailing": true,
273
+ "size": "xs",
274
+ "class": "pe-7"
275
+ },
276
+ {
277
+ "trailing": true,
278
+ "size": "sm",
279
+ "class": "pe-8"
280
+ },
281
+ {
282
+ "trailing": true,
283
+ "size": "md",
284
+ "class": "pe-9"
285
+ },
286
+ {
287
+ "trailing": true,
288
+ "size": "lg",
289
+ "class": "pe-10"
290
+ },
291
+ {
292
+ "trailing": true,
293
+ "size": "xl",
294
+ "class": "pe-11"
295
+ },
296
+ {
297
+ "loading": true,
298
+ "leading": true,
299
+ "class": {
300
+ "leadingIcon": "animate-spin"
301
+ }
302
+ },
303
+ {
304
+ "loading": true,
305
+ "leading": false,
306
+ "trailing": true,
307
+ "class": {
308
+ "trailingIcon": "animate-spin"
309
+ }
310
+ },
311
+ {
312
+ "fixed": false,
313
+ "size": "xs",
314
+ "class": "md:text-xs"
315
+ },
316
+ {
317
+ "fixed": false,
318
+ "size": "sm",
319
+ "class": "md:text-xs"
320
+ },
321
+ {
322
+ "fixed": false,
323
+ "size": "md",
324
+ "class": "md:text-sm"
325
+ },
326
+ {
327
+ "fixed": false,
328
+ "size": "lg",
329
+ "class": "md:text-sm"
330
+ }
331
+ ],
332
+ "defaultVariants": {
333
+ "size": "md",
334
+ "color": "primary",
335
+ "variant": "outline"
336
+ }
337
+ };
338
+ const _sfc_main$2 = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
339
+ __name: "UInput",
340
+ __ssrInlineRender: true,
341
+ props: {
342
+ as: { type: null, required: false },
343
+ id: { type: String, required: false },
344
+ name: { type: String, required: false },
345
+ type: { type: null, required: false, default: "text" },
346
+ placeholder: { type: String, required: false },
347
+ color: { type: null, required: false },
348
+ variant: { type: null, required: false },
349
+ size: { type: null, required: false },
350
+ required: { type: Boolean, required: false },
351
+ autocomplete: { type: [String, Object], required: false, default: "off" },
352
+ autofocus: { type: Boolean, required: false },
353
+ autofocusDelay: { type: Number, required: false, default: 0 },
354
+ disabled: { type: Boolean, required: false },
355
+ highlight: { type: Boolean, required: false },
356
+ fixed: { type: Boolean, required: false },
357
+ modelValue: { type: null, required: false },
358
+ defaultValue: { type: null, required: false },
359
+ modelModifiers: { type: null, required: false },
360
+ class: { type: null, required: false },
361
+ ui: { type: Object, required: false },
362
+ icon: { type: null, required: false },
363
+ avatar: { type: Object, required: false },
364
+ leading: { type: Boolean, required: false },
365
+ leadingIcon: { type: null, required: false },
366
+ trailing: { type: Boolean, required: false },
367
+ trailingIcon: { type: null, required: false },
368
+ loading: { type: Boolean, required: false },
369
+ loadingIcon: { type: null, required: false }
370
+ },
371
+ emits: ["update:modelValue", "blur", "change"],
372
+ setup(__props, { expose: __expose, emit: __emit }) {
373
+ const props = __props;
374
+ const emits = __emit;
375
+ const slots = useSlots();
376
+ const modelValue = useVModel(props, "modelValue", emits, { defaultValue: props.defaultValue });
377
+ const appConfig = useAppConfig();
378
+ const uiProp = useComponentUI("input", props);
379
+ const { emitFormBlur, emitFormInput, emitFormChange, size: formGroupSize, color, id, name, highlight, disabled, emitFormFocus, ariaAttrs } = useFormField(props, { deferInputValidation: true });
380
+ const { orientation, size: fieldGroupSize } = useFieldGroup(props);
381
+ const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
382
+ const inputSize = computed(() => fieldGroupSize.value || formGroupSize.value);
383
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.input || {} })({
384
+ type: props.type,
385
+ color: color.value,
386
+ variant: props.variant,
387
+ size: inputSize?.value,
388
+ loading: props.loading,
389
+ highlight: highlight.value,
390
+ fixed: props.fixed,
391
+ leading: isLeading.value || !!props.avatar || !!slots.leading,
392
+ trailing: isTrailing.value || !!slots.trailing,
393
+ fieldGroup: orientation.value
394
+ }));
395
+ const inputRef = useTemplateRef("inputRef");
396
+ function updateInput(value) {
397
+ if (props.modelModifiers?.trim && (typeof value === "string" || value === null || value === void 0)) {
398
+ value = value?.trim() ?? null;
399
+ }
400
+ if (props.modelModifiers?.number || props.type === "number") {
401
+ value = looseToNumber(value);
402
+ }
403
+ if (props.modelModifiers?.nullable) {
404
+ value ||= null;
405
+ }
406
+ if (props.modelModifiers?.optional && !props.modelModifiers?.nullable && value !== null) {
407
+ value ||= void 0;
408
+ }
409
+ modelValue.value = value;
410
+ emitFormInput();
411
+ }
412
+ function onInput(event) {
413
+ if (!props.modelModifiers?.lazy) {
414
+ updateInput(event.target.value);
415
+ }
416
+ }
417
+ function onChange(event) {
418
+ const value = event.target.value;
419
+ if (props.modelModifiers?.lazy) {
420
+ updateInput(value);
421
+ }
422
+ if (props.modelModifiers?.trim) {
423
+ event.target.value = value.trim();
424
+ }
425
+ emitFormChange();
426
+ emits("change", event);
427
+ }
428
+ function onBlur(event) {
429
+ emitFormBlur();
430
+ emits("blur", event);
431
+ }
432
+ __expose({
433
+ inputRef
434
+ });
435
+ return (_ctx, _push, _parent, _attrs) => {
436
+ _push(ssrRenderComponent(unref(Primitive), mergeProps({
437
+ as: __props.as,
438
+ "data-slot": "root",
439
+ class: ui.value.root({ class: [unref(uiProp)?.root, props.class] })
440
+ }, _attrs), {
441
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
442
+ if (_push2) {
443
+ _push2(`<input${ssrRenderAttrs(mergeProps({
444
+ id: unref(id),
445
+ ref_key: "inputRef",
446
+ ref: inputRef,
447
+ type: __props.type,
448
+ value: unref(modelValue),
449
+ name: unref(name),
450
+ placeholder: __props.placeholder,
451
+ "data-slot": "base",
452
+ class: ui.value.base({ class: unref(uiProp)?.base }),
453
+ disabled: unref(disabled),
454
+ required: __props.required,
455
+ autocomplete: __props.autocomplete
456
+ }, { ..._ctx.$attrs, ...unref(ariaAttrs) }))}${_scopeId}>`);
457
+ ssrRenderSlot(_ctx.$slots, "default", { ui: ui.value }, null, _push2, _parent2, _scopeId);
458
+ if (unref(isLeading) || !!__props.avatar || !!slots.leading) {
459
+ _push2(`<span data-slot="leading" class="${ssrRenderClass(ui.value.leading({ class: unref(uiProp)?.leading }))}"${_scopeId}>`);
460
+ ssrRenderSlot(_ctx.$slots, "leading", { ui: ui.value }, () => {
461
+ if (unref(isLeading) && unref(leadingIconName)) {
462
+ _push2(ssrRenderComponent(_sfc_main$m, {
463
+ name: unref(leadingIconName),
464
+ "data-slot": "leadingIcon",
465
+ class: ui.value.leadingIcon({ class: unref(uiProp)?.leadingIcon })
466
+ }, null, _parent2, _scopeId));
467
+ } else if (!!__props.avatar) {
468
+ _push2(ssrRenderComponent(_sfc_main$k, mergeProps({
469
+ size: unref(uiProp)?.leadingAvatarSize || ui.value.leadingAvatarSize()
470
+ }, __props.avatar, {
471
+ "data-slot": "leadingAvatar",
472
+ class: ui.value.leadingAvatar({ class: unref(uiProp)?.leadingAvatar })
473
+ }), null, _parent2, _scopeId));
474
+ } else {
475
+ _push2(`<!---->`);
476
+ }
477
+ }, _push2, _parent2, _scopeId);
478
+ _push2(`</span>`);
479
+ } else {
480
+ _push2(`<!---->`);
481
+ }
482
+ if (unref(isTrailing) || !!slots.trailing) {
483
+ _push2(`<span data-slot="trailing" class="${ssrRenderClass(ui.value.trailing({ class: unref(uiProp)?.trailing }))}"${_scopeId}>`);
484
+ ssrRenderSlot(_ctx.$slots, "trailing", { ui: ui.value }, () => {
485
+ if (unref(trailingIconName)) {
486
+ _push2(ssrRenderComponent(_sfc_main$m, {
487
+ name: unref(trailingIconName),
488
+ "data-slot": "trailingIcon",
489
+ class: ui.value.trailingIcon({ class: unref(uiProp)?.trailingIcon })
490
+ }, null, _parent2, _scopeId));
491
+ } else {
492
+ _push2(`<!---->`);
493
+ }
494
+ }, _push2, _parent2, _scopeId);
495
+ _push2(`</span>`);
496
+ } else {
497
+ _push2(`<!---->`);
498
+ }
499
+ } else {
500
+ return [
501
+ createVNode("input", mergeProps({
502
+ id: unref(id),
503
+ ref_key: "inputRef",
504
+ ref: inputRef,
505
+ type: __props.type,
506
+ value: unref(modelValue),
507
+ name: unref(name),
508
+ placeholder: __props.placeholder,
509
+ "data-slot": "base",
510
+ class: ui.value.base({ class: unref(uiProp)?.base }),
511
+ disabled: unref(disabled),
512
+ required: __props.required,
513
+ autocomplete: __props.autocomplete
514
+ }, { ..._ctx.$attrs, ...unref(ariaAttrs) }, {
515
+ onInput,
516
+ onBlur,
517
+ onChange,
518
+ onFocus: unref(emitFormFocus)
519
+ }), null, 16, ["id", "type", "value", "name", "placeholder", "disabled", "required", "autocomplete", "onFocus"]),
520
+ renderSlot(_ctx.$slots, "default", { ui: ui.value }),
521
+ unref(isLeading) || !!__props.avatar || !!slots.leading ? (openBlock(), createBlock("span", {
522
+ key: 0,
523
+ "data-slot": "leading",
524
+ class: ui.value.leading({ class: unref(uiProp)?.leading })
525
+ }, [
526
+ renderSlot(_ctx.$slots, "leading", { ui: ui.value }, () => [
527
+ unref(isLeading) && unref(leadingIconName) ? (openBlock(), createBlock(_sfc_main$m, {
528
+ key: 0,
529
+ name: unref(leadingIconName),
530
+ "data-slot": "leadingIcon",
531
+ class: ui.value.leadingIcon({ class: unref(uiProp)?.leadingIcon })
532
+ }, null, 8, ["name", "class"])) : !!__props.avatar ? (openBlock(), createBlock(_sfc_main$k, mergeProps({
533
+ key: 1,
534
+ size: unref(uiProp)?.leadingAvatarSize || ui.value.leadingAvatarSize()
535
+ }, __props.avatar, {
536
+ "data-slot": "leadingAvatar",
537
+ class: ui.value.leadingAvatar({ class: unref(uiProp)?.leadingAvatar })
538
+ }), null, 16, ["size", "class"])) : createCommentVNode("", true)
539
+ ])
540
+ ], 2)) : createCommentVNode("", true),
541
+ unref(isTrailing) || !!slots.trailing ? (openBlock(), createBlock("span", {
542
+ key: 1,
543
+ "data-slot": "trailing",
544
+ class: ui.value.trailing({ class: unref(uiProp)?.trailing })
545
+ }, [
546
+ renderSlot(_ctx.$slots, "trailing", { ui: ui.value }, () => [
547
+ unref(trailingIconName) ? (openBlock(), createBlock(_sfc_main$m, {
548
+ key: 0,
549
+ name: unref(trailingIconName),
550
+ "data-slot": "trailingIcon",
551
+ class: ui.value.trailingIcon({ class: unref(uiProp)?.trailingIcon })
552
+ }, null, 8, ["name", "class"])) : createCommentVNode("", true)
553
+ ])
554
+ ], 2)) : createCommentVNode("", true)
555
+ ];
556
+ }
557
+ }),
558
+ _: 3
559
+ }, _parent));
560
+ };
561
+ }
562
+ });
563
+ const _sfc_setup$2 = _sfc_main$2.setup;
564
+ _sfc_main$2.setup = (props, ctx) => {
565
+ const ssrContext = useSSRContext();
566
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("../../node_modules/@nuxt/ui/dist/runtime/components/Input.vue");
567
+ return _sfc_setup$2 ? _sfc_setup$2(props, ctx) : void 0;
568
+ };
569
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
570
+ __name: "IntegrationCredentials",
571
+ __ssrInlineRender: true,
572
+ props: {
573
+ integrationId: {},
574
+ integrationType: {},
575
+ currentVariant: {}
576
+ },
577
+ emits: ["saved", "disconnected"],
578
+ setup(__props, { emit: __emit }) {
579
+ const props = __props;
580
+ const emit = __emit;
581
+ const credConfig = ref(null);
582
+ const loading = ref(true);
583
+ const loadError = ref(false);
584
+ const hasCredentials = ref(false);
585
+ const healthStatus = ref(null);
586
+ const selectedVariant = ref(void 0);
587
+ const form = reactive({});
588
+ const saving = ref(false);
589
+ const disconnecting = ref(false);
590
+ const modalOpen = ref(false);
591
+ const hasMultipleVariants = computed(() => (credConfig.value?.variants?.length ?? 0) > 1);
592
+ const variantItems = computed(
593
+ () => (credConfig.value?.variants || []).map((v) => ({ label: v.label, value: v.key }))
594
+ );
595
+ const activeVariant = computed(
596
+ () => credConfig.value?.variants?.find((v) => v.key === selectedVariant.value) ?? null
597
+ );
598
+ const schemaFields = computed(() => {
599
+ const properties = activeVariant.value?.schema?.properties || {};
600
+ return Object.entries(properties);
601
+ });
602
+ const renderedHint = computed(() => {
603
+ const md = activeVariant.value?.hintMarkdown;
604
+ if (!md) return "";
605
+ return marked.parse(md);
606
+ });
607
+ function isSecretField(key) {
608
+ const lower = key.toLowerCase();
609
+ return lower.includes("token") || lower.includes("key") || lower.includes("secret") || lower.includes("password") || lower.includes("json");
610
+ }
611
+ function openModal() {
612
+ for (const k of Object.keys(form))
613
+ delete form[k];
614
+ modalOpen.value = true;
615
+ }
616
+ watch(selectedVariant, () => {
617
+ for (const k of Object.keys(form))
618
+ delete form[k];
619
+ });
620
+ async function load() {
621
+ loading.value = true;
622
+ loadError.value = false;
623
+ try {
624
+ const [config, status] = await Promise.all([
625
+ $fetch(`/api/integrations/${props.integrationId}/credentials-config`),
626
+ $fetch(`/api/integrations/${props.integrationId}/credentials-status`)
627
+ ]);
628
+ credConfig.value = config;
629
+ hasCredentials.value = !!status?.hasCredentials;
630
+ healthStatus.value = status?.health_status ?? null;
631
+ selectedVariant.value = props.currentVariant || config?.defaultVariant || config?.variants?.[0]?.key || void 0;
632
+ } catch {
633
+ loadError.value = true;
634
+ } finally {
635
+ loading.value = false;
636
+ }
637
+ }
638
+ async function save() {
639
+ saving.value = true;
640
+ try {
641
+ const body = {};
642
+ for (const [k] of schemaFields.value) {
643
+ const v = (form[k] || "").trim();
644
+ if (v) body[k] = v;
645
+ }
646
+ if (selectedVariant.value)
647
+ body.credentialVariant = selectedVariant.value;
648
+ const res = await $fetch(`/api/integrations/${props.integrationId}/credentials`, { method: "POST", body });
649
+ hasCredentials.value = true;
650
+ healthStatus.value = res.health_status ?? "connected";
651
+ modalOpen.value = false;
652
+ for (const k of Object.keys(form))
653
+ delete form[k];
654
+ emit("saved");
655
+ } finally {
656
+ saving.value = false;
657
+ }
658
+ }
659
+ async function disconnect() {
660
+ disconnecting.value = true;
661
+ try {
662
+ await $fetch(`/api/integrations/${props.integrationId}/credentials`, { method: "DELETE" });
663
+ hasCredentials.value = false;
664
+ healthStatus.value = "disconnected";
665
+ emit("disconnected");
666
+ } finally {
667
+ disconnecting.value = false;
668
+ }
669
+ }
670
+ load();
671
+ return (_ctx, _push, _parent, _attrs) => {
672
+ const _component_UIcon = _sfc_main$m;
673
+ const _component_UButton = _sfc_main$h;
674
+ const _component_UModal = _sfc_main$9;
675
+ const _component_UFormField = _sfc_main$2$1;
676
+ const _component_USelect = _sfc_main$1$1;
677
+ const _component_UInput = _sfc_main$2;
678
+ _push(`<div${ssrRenderAttrs(_attrs)} data-v-f235dc98>`);
679
+ if (unref(loading)) {
680
+ _push(`<div class="flex items-center gap-2 text-sm text-muted" data-v-f235dc98>`);
681
+ _push(ssrRenderComponent(_component_UIcon, {
682
+ name: "i-lucide-loader-2",
683
+ class: "animate-spin"
684
+ }, null, _parent));
685
+ _push(` Checking connection… </div>`);
686
+ } else if (unref(credConfig)?.supportsCredentials === false) {
687
+ _push(`<div class="flex items-center gap-2 text-sm text-muted" data-v-f235dc98>`);
688
+ _push(ssrRenderComponent(_component_UIcon, { name: "i-lucide-info" }, null, _parent));
689
+ _push(` No credentials required for this integration. </div>`);
690
+ } else if (unref(healthStatus) === "connected") {
691
+ _push(`<div class="flex items-center gap-3 flex-wrap" data-v-f235dc98><div class="flex items-center gap-2 text-sm font-medium text-green-600 dark:text-green-400" data-v-f235dc98><span class="inline-block w-2 h-2 rounded-full bg-green-500" data-v-f235dc98></span> Connected </div>`);
692
+ _push(ssrRenderComponent(_component_UButton, {
693
+ size: "xs",
694
+ variant: "soft",
695
+ color: "neutral",
696
+ icon: "i-lucide-refresh-cw",
697
+ onClick: openModal
698
+ }, {
699
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
700
+ if (_push2) {
701
+ _push2(` Reconfigure `);
702
+ } else {
703
+ return [
704
+ createTextVNode(" Reconfigure ")
705
+ ];
706
+ }
707
+ }),
708
+ _: 1
709
+ }, _parent));
710
+ _push(ssrRenderComponent(_component_UButton, {
711
+ size: "xs",
712
+ variant: "soft",
713
+ color: "error",
714
+ icon: "i-lucide-unplug",
715
+ loading: unref(disconnecting),
716
+ onClick: disconnect
717
+ }, {
718
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
719
+ if (_push2) {
720
+ _push2(` Disconnect `);
721
+ } else {
722
+ return [
723
+ createTextVNode(" Disconnect ")
724
+ ];
725
+ }
726
+ }),
727
+ _: 1
728
+ }, _parent));
729
+ _push(`</div>`);
730
+ } else if (unref(healthStatus) === "invalid_credentials") {
731
+ _push(`<div class="flex items-center gap-3 flex-wrap" data-v-f235dc98><div class="flex items-center gap-2 text-sm font-medium text-red-600 dark:text-red-400" data-v-f235dc98><span class="inline-block w-2 h-2 rounded-full bg-red-500" data-v-f235dc98></span> Invalid credentials </div>`);
732
+ _push(ssrRenderComponent(_component_UButton, {
733
+ size: "sm",
734
+ icon: "i-lucide-refresh-cw",
735
+ color: "primary",
736
+ onClick: openModal
737
+ }, {
738
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
739
+ if (_push2) {
740
+ _push2(` Reconfigure `);
741
+ } else {
742
+ return [
743
+ createTextVNode(" Reconfigure ")
744
+ ];
745
+ }
746
+ }),
747
+ _: 1
748
+ }, _parent));
749
+ _push(ssrRenderComponent(_component_UButton, {
750
+ size: "xs",
751
+ variant: "soft",
752
+ color: "error",
753
+ icon: "i-lucide-unplug",
754
+ loading: unref(disconnecting),
755
+ onClick: disconnect
756
+ }, {
757
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
758
+ if (_push2) {
759
+ _push2(` Disconnect `);
760
+ } else {
761
+ return [
762
+ createTextVNode(" Disconnect ")
763
+ ];
764
+ }
765
+ }),
766
+ _: 1
767
+ }, _parent));
768
+ _push(`</div>`);
769
+ } else {
770
+ _push(`<div class="flex items-center gap-3 flex-wrap" data-v-f235dc98><div class="flex items-center gap-2 text-sm font-medium text-red-600 dark:text-red-400" data-v-f235dc98><span class="inline-block w-2 h-2 rounded-full bg-red-500" data-v-f235dc98></span> Not connected </div>`);
771
+ _push(ssrRenderComponent(_component_UButton, {
772
+ size: "sm",
773
+ icon: "i-lucide-plug",
774
+ color: "primary",
775
+ onClick: openModal
776
+ }, {
777
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
778
+ if (_push2) {
779
+ _push2(` Connect `);
780
+ } else {
781
+ return [
782
+ createTextVNode(" Connect ")
783
+ ];
784
+ }
785
+ }),
786
+ _: 1
787
+ }, _parent));
788
+ _push(`</div>`);
789
+ }
790
+ _push(ssrRenderComponent(_component_UModal, {
791
+ open: unref(modalOpen),
792
+ "onUpdate:open": ($event) => isRef(modalOpen) ? modalOpen.value = $event : null,
793
+ title: unref(hasCredentials) ? "Reconfigure Credentials" : "Connect Integration",
794
+ description: "Enter your credentials to connect this integration."
795
+ }, {
796
+ body: withCtx((_, _push2, _parent2, _scopeId) => {
797
+ if (_push2) {
798
+ _push2(`<div class="space-y-4" data-v-f235dc98${_scopeId}>`);
799
+ if (unref(loadError)) {
800
+ _push2(`<div class="text-sm text-red-600" data-v-f235dc98${_scopeId}> Failed to load credential schema. Please try again. </div>`);
801
+ } else {
802
+ _push2(`<!--[-->`);
803
+ if (unref(hasMultipleVariants)) {
804
+ _push2(ssrRenderComponent(_component_UFormField, { label: "Credential type" }, {
805
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
806
+ if (_push3) {
807
+ _push3(ssrRenderComponent(_component_USelect, {
808
+ modelValue: unref(selectedVariant),
809
+ "onUpdate:modelValue": ($event) => isRef(selectedVariant) ? selectedVariant.value = $event : null,
810
+ items: unref(variantItems),
811
+ class: "w-full"
812
+ }, null, _parent3, _scopeId2));
813
+ } else {
814
+ return [
815
+ createVNode(_component_USelect, {
816
+ modelValue: unref(selectedVariant),
817
+ "onUpdate:modelValue": ($event) => isRef(selectedVariant) ? selectedVariant.value = $event : null,
818
+ items: unref(variantItems),
819
+ class: "w-full"
820
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "items"])
821
+ ];
822
+ }
823
+ }),
824
+ _: 1
825
+ }, _parent2, _scopeId));
826
+ } else {
827
+ _push2(`<!---->`);
828
+ }
829
+ if (unref(activeVariant)?.hintMarkdown) {
830
+ _push2(`<div class="hint-markdown text-sm bg-[var(--ui-bg-elevated)] rounded-md px-3 py-2" data-v-f235dc98${_scopeId}>${unref(renderedHint) ?? ""}</div>`);
831
+ } else {
832
+ _push2(`<!---->`);
833
+ }
834
+ _push2(`<div class="space-y-3" data-v-f235dc98${_scopeId}><!--[-->`);
835
+ ssrRenderList(unref(schemaFields), ([key, prop]) => {
836
+ _push2(ssrRenderComponent(_component_UFormField, {
837
+ key,
838
+ label: prop.title || key,
839
+ description: prop.description
840
+ }, {
841
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
842
+ if (_push3) {
843
+ _push3(ssrRenderComponent(_component_UInput, {
844
+ modelValue: unref(form)[key],
845
+ "onUpdate:modelValue": ($event) => unref(form)[key] = $event,
846
+ type: isSecretField(key) ? "password" : "text",
847
+ class: "w-full"
848
+ }, null, _parent3, _scopeId2));
849
+ } else {
850
+ return [
851
+ createVNode(_component_UInput, {
852
+ modelValue: unref(form)[key],
853
+ "onUpdate:modelValue": ($event) => unref(form)[key] = $event,
854
+ type: isSecretField(key) ? "password" : "text",
855
+ class: "w-full"
856
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "type"])
857
+ ];
858
+ }
859
+ }),
860
+ _: 2
861
+ }, _parent2, _scopeId));
862
+ });
863
+ _push2(`<!--]--></div><!--]-->`);
864
+ }
865
+ _push2(`</div>`);
866
+ } else {
867
+ return [
868
+ createVNode("div", { class: "space-y-4" }, [
869
+ unref(loadError) ? (openBlock(), createBlock("div", {
870
+ key: 0,
871
+ class: "text-sm text-red-600"
872
+ }, " Failed to load credential schema. Please try again. ")) : (openBlock(), createBlock(Fragment, { key: 1 }, [
873
+ unref(hasMultipleVariants) ? (openBlock(), createBlock(_component_UFormField, {
874
+ key: 0,
875
+ label: "Credential type"
876
+ }, {
877
+ default: withCtx(() => [
878
+ createVNode(_component_USelect, {
879
+ modelValue: unref(selectedVariant),
880
+ "onUpdate:modelValue": ($event) => isRef(selectedVariant) ? selectedVariant.value = $event : null,
881
+ items: unref(variantItems),
882
+ class: "w-full"
883
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "items"])
884
+ ]),
885
+ _: 1
886
+ })) : createCommentVNode("", true),
887
+ unref(activeVariant)?.hintMarkdown ? (openBlock(), createBlock("div", {
888
+ key: 1,
889
+ class: "hint-markdown text-sm bg-[var(--ui-bg-elevated)] rounded-md px-3 py-2",
890
+ innerHTML: unref(renderedHint)
891
+ }, null, 8, ["innerHTML"])) : createCommentVNode("", true),
892
+ createVNode("div", { class: "space-y-3" }, [
893
+ (openBlock(true), createBlock(Fragment, null, renderList(unref(schemaFields), ([key, prop]) => {
894
+ return openBlock(), createBlock(_component_UFormField, {
895
+ key,
896
+ label: prop.title || key,
897
+ description: prop.description
898
+ }, {
899
+ default: withCtx(() => [
900
+ createVNode(_component_UInput, {
901
+ modelValue: unref(form)[key],
902
+ "onUpdate:modelValue": ($event) => unref(form)[key] = $event,
903
+ type: isSecretField(key) ? "password" : "text",
904
+ class: "w-full"
905
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "type"])
906
+ ]),
907
+ _: 2
908
+ }, 1032, ["label", "description"]);
909
+ }), 128))
910
+ ])
911
+ ], 64))
912
+ ])
913
+ ];
914
+ }
915
+ }),
916
+ footer: withCtx((_, _push2, _parent2, _scopeId) => {
917
+ if (_push2) {
918
+ _push2(`<div class="flex items-center justify-end gap-2 w-full" data-v-f235dc98${_scopeId}>`);
919
+ _push2(ssrRenderComponent(_component_UButton, {
920
+ variant: "ghost",
921
+ color: "neutral",
922
+ disabled: unref(saving),
923
+ onClick: ($event) => modalOpen.value = false
924
+ }, {
925
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
926
+ if (_push3) {
927
+ _push3(` Cancel `);
928
+ } else {
929
+ return [
930
+ createTextVNode(" Cancel ")
931
+ ];
932
+ }
933
+ }),
934
+ _: 1
935
+ }, _parent2, _scopeId));
936
+ _push2(ssrRenderComponent(_component_UButton, {
937
+ loading: unref(saving),
938
+ icon: "i-lucide-check",
939
+ onClick: save
940
+ }, {
941
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
942
+ if (_push3) {
943
+ _push3(` Save Credentials `);
944
+ } else {
945
+ return [
946
+ createTextVNode(" Save Credentials ")
947
+ ];
948
+ }
949
+ }),
950
+ _: 1
951
+ }, _parent2, _scopeId));
952
+ _push2(`</div>`);
953
+ } else {
954
+ return [
955
+ createVNode("div", { class: "flex items-center justify-end gap-2 w-full" }, [
956
+ createVNode(_component_UButton, {
957
+ variant: "ghost",
958
+ color: "neutral",
959
+ disabled: unref(saving),
960
+ onClick: ($event) => modalOpen.value = false
961
+ }, {
962
+ default: withCtx(() => [
963
+ createTextVNode(" Cancel ")
964
+ ]),
965
+ _: 1
966
+ }, 8, ["disabled", "onClick"]),
967
+ createVNode(_component_UButton, {
968
+ loading: unref(saving),
969
+ icon: "i-lucide-check",
970
+ onClick: save
971
+ }, {
972
+ default: withCtx(() => [
973
+ createTextVNode(" Save Credentials ")
974
+ ]),
975
+ _: 1
976
+ }, 8, ["loading"])
977
+ ])
978
+ ];
979
+ }
980
+ }),
981
+ _: 1
982
+ }, _parent));
983
+ _push(`</div>`);
984
+ };
985
+ }
986
+ });
987
+ const _sfc_setup$1 = _sfc_main$1.setup;
988
+ _sfc_main$1.setup = (props, ctx) => {
989
+ const ssrContext = useSSRContext();
990
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/IntegrationCredentials.vue");
991
+ return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0;
992
+ };
993
+ const __nuxt_component_6 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main$1, [["__scopeId", "data-v-f235dc98"]]), { __name: "IntegrationCredentials" });
994
+ const _sfc_main = /* @__PURE__ */ defineComponent({
995
+ __name: "[id]",
996
+ __ssrInlineRender: true,
997
+ async setup(__props) {
998
+ let __temp, __restore;
999
+ const route = useRoute();
1000
+ const integrationId = route.params.id;
1001
+ const { data: integrations, pending, error, refresh } = ([__temp, __restore] = withAsyncContext(() => useFetch(
1002
+ "/api/integrations",
1003
+ "$Dgyl0ZYFMT"
1004
+ /* nuxt-injected */
1005
+ )), __temp = await __temp, __restore(), __temp);
1006
+ const integration = computed(() => integrations.value?.find((i) => i.id === integrationId) ?? null);
1007
+ const formEnabled = ref(true);
1008
+ const formMaxScope = ref(null);
1009
+ const formEnabledToolsets = ref([]);
1010
+ const formDisabledTools = ref([]);
1011
+ const toolsTreeRef = ref(null);
1012
+ const saving = ref(false);
1013
+ function initForm() {
1014
+ if (!integration.value) return;
1015
+ formEnabled.value = integration.value.enabled !== false;
1016
+ formMaxScope.value = integration.value.maxScope === "read" ? "read" : null;
1017
+ formDisabledTools.value = integration.value.disabledTools ? [...integration.value.disabledTools] : [];
1018
+ const treeToolsets = toolsTreeRef.value?.toolsets;
1019
+ const allKeys = Array.isArray(treeToolsets) ? treeToolsets.map((t) => t.key).filter((k) => k !== "__all__") : [];
1020
+ formEnabledToolsets.value = integration.value.enabledToolsets?.length ? [...integration.value.enabledToolsets] : allKeys;
1021
+ }
1022
+ watch(integration, () => initForm(), { immediate: true });
1023
+ watch(() => toolsTreeRef.value?.toolsets, (toolsets) => {
1024
+ if (!integration.value || !toolsets?.length) return;
1025
+ if (!integration.value.enabledToolsets?.length) {
1026
+ formEnabledToolsets.value = toolsets.map((t) => t.key).filter((k) => k !== "__all__");
1027
+ }
1028
+ }, { deep: true });
1029
+ async function saveAll() {
1030
+ if (!integration.value) return;
1031
+ saving.value = true;
1032
+ try {
1033
+ const id = integration.value.id;
1034
+ await $fetch("/api/integrations", {
1035
+ method: "POST",
1036
+ body: { ...integration.value, enabled: formEnabled.value }
1037
+ });
1038
+ const treeToolsets = toolsTreeRef.value?.toolsets;
1039
+ const allKeys = Array.isArray(treeToolsets) ? treeToolsets.map((t) => t.key).filter((k) => k !== "__all__") : [];
1040
+ const enabledToolsets = allKeys.length && formEnabledToolsets.value.length < allKeys.length ? formEnabledToolsets.value : [];
1041
+ await $fetch(`/api/integrations/${id}/toolsets`, {
1042
+ method: "POST",
1043
+ body: { enabledToolsets }
1044
+ });
1045
+ await $fetch(`/api/integrations/${id}/permissions`, {
1046
+ method: "POST",
1047
+ body: {
1048
+ maxScope: formMaxScope.value,
1049
+ disabledTools: formDisabledTools.value.length ? formDisabledTools.value : null
1050
+ }
1051
+ });
1052
+ await refresh();
1053
+ } finally {
1054
+ saving.value = false;
1055
+ }
1056
+ }
1057
+ async function confirmRemove() {
1058
+ if (!integration.value) return;
1059
+ if (!(void 0).confirm(`Remove "${integration.value.label}"? This cannot be undone.`))
1060
+ return;
1061
+ await $fetch(`/api/integrations/${integration.value.id}`, { method: "DELETE" });
1062
+ navigateTo("/integrations");
1063
+ }
1064
+ function onCredentialChange() {
1065
+ refresh();
1066
+ }
1067
+ return (_ctx, _push, _parent, _attrs) => {
1068
+ const _component_UContainer = _sfc_main$b;
1069
+ const _component_UButton = _sfc_main$h;
1070
+ const _component_NuxtLink = __nuxt_component_0$1;
1071
+ const _component_UIcon = _sfc_main$m;
1072
+ const _component_UBadge = _sfc_main$4;
1073
+ const _component_USwitch = _sfc_main$3;
1074
+ const _component_IntegrationCredentials = __nuxt_component_6;
1075
+ const _component_IntegrationToolsTree = __nuxt_component_3;
1076
+ _push(ssrRenderComponent(_component_UContainer, mergeProps({ class: "py-10 space-y-8 max-w-3xl" }, _attrs), {
1077
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
1078
+ if (_push2) {
1079
+ if (unref(pending)) {
1080
+ _push2(`<div class="text-sm text-muted py-8 text-center"${_scopeId}> Loading… </div>`);
1081
+ } else if (unref(error) || !unref(integration)) {
1082
+ _push2(`<div class="py-8 text-center space-y-4"${_scopeId}><div class="text-sm text-red-600"${_scopeId}> Integration not found. </div>`);
1083
+ _push2(ssrRenderComponent(_component_UButton, {
1084
+ to: "/integrations",
1085
+ variant: "soft",
1086
+ color: "neutral",
1087
+ icon: "i-lucide-arrow-left"
1088
+ }, {
1089
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
1090
+ if (_push3) {
1091
+ _push3(` Back to Integrations `);
1092
+ } else {
1093
+ return [
1094
+ createTextVNode(" Back to Integrations ")
1095
+ ];
1096
+ }
1097
+ }),
1098
+ _: 1
1099
+ }, _parent2, _scopeId));
1100
+ _push2(`</div>`);
1101
+ } else {
1102
+ _push2(`<!--[--><div${_scopeId}>`);
1103
+ _push2(ssrRenderComponent(_component_NuxtLink, {
1104
+ to: "/integrations",
1105
+ class: "inline-flex items-center gap-1 text-sm text-muted hover:text-[var(--ui-text)] transition-colors mb-4"
1106
+ }, {
1107
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
1108
+ if (_push3) {
1109
+ _push3(ssrRenderComponent(_component_UIcon, {
1110
+ name: "i-lucide-arrow-left",
1111
+ class: "w-4 h-4"
1112
+ }, null, _parent3, _scopeId2));
1113
+ _push3(` Back to Integrations `);
1114
+ } else {
1115
+ return [
1116
+ createVNode(_component_UIcon, {
1117
+ name: "i-lucide-arrow-left",
1118
+ class: "w-4 h-4"
1119
+ }),
1120
+ createTextVNode(" Back to Integrations ")
1121
+ ];
1122
+ }
1123
+ }),
1124
+ _: 1
1125
+ }, _parent2, _scopeId));
1126
+ _push2(`<div class="flex items-center justify-between gap-4"${_scopeId}><div class="flex items-center gap-3"${_scopeId}><h1 class="text-2xl font-semibold"${_scopeId}>${ssrInterpolate(unref(integration).label)}</h1>`);
1127
+ _push2(ssrRenderComponent(_component_UBadge, {
1128
+ size: "sm",
1129
+ color: "neutral",
1130
+ variant: "subtle"
1131
+ }, {
1132
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
1133
+ if (_push3) {
1134
+ _push3(`${ssrInterpolate(unref(integration).type)}`);
1135
+ } else {
1136
+ return [
1137
+ createTextVNode(toDisplayString(unref(integration).type), 1)
1138
+ ];
1139
+ }
1140
+ }),
1141
+ _: 1
1142
+ }, _parent2, _scopeId));
1143
+ _push2(`</div>`);
1144
+ _push2(ssrRenderComponent(_component_USwitch, {
1145
+ modelValue: unref(formEnabled),
1146
+ "onUpdate:modelValue": ($event) => isRef(formEnabled) ? formEnabled.value = $event : null,
1147
+ size: "lg"
1148
+ }, null, _parent2, _scopeId));
1149
+ _push2(`</div><p class="text-sm text-muted mt-1"${_scopeId}>${ssrInterpolate(unref(integration).type)} · ${ssrInterpolate(unref(integration).referenceId)}</p></div><section${_scopeId}><div class="flex items-center justify-between gap-4 mb-1"${_scopeId}><h2 class="text-lg font-medium"${_scopeId}> Connection </h2></div><div class="border border-[var(--ui-border)] rounded-lg px-4 py-3"${_scopeId}>`);
1150
+ _push2(ssrRenderComponent(_component_IntegrationCredentials, {
1151
+ "integration-id": unref(integration).id,
1152
+ "integration-type": unref(integration).type,
1153
+ "current-variant": unref(integration).credentialVariant,
1154
+ onSaved: onCredentialChange,
1155
+ onDisconnected: onCredentialChange
1156
+ }, null, _parent2, _scopeId));
1157
+ _push2(`</div></section><section class="space-y-3"${_scopeId}><h2 class="text-lg font-medium"${_scopeId}> Access Level </h2><div class="flex gap-2"${_scopeId}><button type="button" class="${ssrRenderClass([unref(formMaxScope) !== "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-[var(--ui-border)] text-muted hover:bg-[var(--ui-bg-elevated)]", "px-4 py-2 text-sm rounded-lg border transition-colors"])}"${_scopeId}> Read + Write </button><button type="button" class="${ssrRenderClass([unref(formMaxScope) === "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-[var(--ui-border)] text-muted hover:bg-[var(--ui-bg-elevated)]", "px-4 py-2 text-sm rounded-lg border transition-colors"])}"${_scopeId}> Read-only </button></div>`);
1158
+ if (unref(formMaxScope) === "read") {
1159
+ _push2(`<p class="text-xs text-amber-600 dark:text-amber-400"${_scopeId}> Only read tools will be available. Write and admin tools will be greyed out below. </p>`);
1160
+ } else {
1161
+ _push2(`<!---->`);
1162
+ }
1163
+ _push2(`</section><section class="space-y-3"${_scopeId}><h2 class="text-lg font-medium"${_scopeId}> Tools </h2>`);
1164
+ _push2(ssrRenderComponent(_component_IntegrationToolsTree, {
1165
+ ref_key: "toolsTreeRef",
1166
+ ref: toolsTreeRef,
1167
+ "integration-type": unref(integration).type,
1168
+ "max-scope": unref(formMaxScope),
1169
+ "enabled-toolsets": unref(formEnabledToolsets),
1170
+ "disabled-tools": unref(formDisabledTools),
1171
+ "onUpdate:enabledToolsets": ($event) => formEnabledToolsets.value = $event,
1172
+ "onUpdate:disabledTools": ($event) => formDisabledTools.value = $event
1173
+ }, null, _parent2, _scopeId));
1174
+ _push2(`</section><div class="sticky bottom-0 py-4 bg-[var(--ui-bg)] border-t border-[var(--ui-border)] -mx-4 px-4 flex items-center justify-between gap-4"${_scopeId}>`);
1175
+ _push2(ssrRenderComponent(_component_UButton, {
1176
+ loading: unref(saving),
1177
+ size: "lg",
1178
+ onClick: saveAll
1179
+ }, {
1180
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
1181
+ if (_push3) {
1182
+ _push3(` Save Changes `);
1183
+ } else {
1184
+ return [
1185
+ createTextVNode(" Save Changes ")
1186
+ ];
1187
+ }
1188
+ }),
1189
+ _: 1
1190
+ }, _parent2, _scopeId));
1191
+ _push2(ssrRenderComponent(_component_UButton, {
1192
+ variant: "soft",
1193
+ color: "error",
1194
+ icon: "i-lucide-trash-2",
1195
+ onClick: confirmRemove
1196
+ }, {
1197
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
1198
+ if (_push3) {
1199
+ _push3(` Remove Integration `);
1200
+ } else {
1201
+ return [
1202
+ createTextVNode(" Remove Integration ")
1203
+ ];
1204
+ }
1205
+ }),
1206
+ _: 1
1207
+ }, _parent2, _scopeId));
1208
+ _push2(`</div><!--]-->`);
1209
+ }
1210
+ } else {
1211
+ return [
1212
+ unref(pending) ? (openBlock(), createBlock("div", {
1213
+ key: 0,
1214
+ class: "text-sm text-muted py-8 text-center"
1215
+ }, " Loading… ")) : unref(error) || !unref(integration) ? (openBlock(), createBlock("div", {
1216
+ key: 1,
1217
+ class: "py-8 text-center space-y-4"
1218
+ }, [
1219
+ createVNode("div", { class: "text-sm text-red-600" }, " Integration not found. "),
1220
+ createVNode(_component_UButton, {
1221
+ to: "/integrations",
1222
+ variant: "soft",
1223
+ color: "neutral",
1224
+ icon: "i-lucide-arrow-left"
1225
+ }, {
1226
+ default: withCtx(() => [
1227
+ createTextVNode(" Back to Integrations ")
1228
+ ]),
1229
+ _: 1
1230
+ })
1231
+ ])) : (openBlock(), createBlock(Fragment, { key: 2 }, [
1232
+ createVNode("div", null, [
1233
+ createVNode(_component_NuxtLink, {
1234
+ to: "/integrations",
1235
+ class: "inline-flex items-center gap-1 text-sm text-muted hover:text-[var(--ui-text)] transition-colors mb-4"
1236
+ }, {
1237
+ default: withCtx(() => [
1238
+ createVNode(_component_UIcon, {
1239
+ name: "i-lucide-arrow-left",
1240
+ class: "w-4 h-4"
1241
+ }),
1242
+ createTextVNode(" Back to Integrations ")
1243
+ ]),
1244
+ _: 1
1245
+ }),
1246
+ createVNode("div", { class: "flex items-center justify-between gap-4" }, [
1247
+ createVNode("div", { class: "flex items-center gap-3" }, [
1248
+ createVNode("h1", { class: "text-2xl font-semibold" }, toDisplayString(unref(integration).label), 1),
1249
+ createVNode(_component_UBadge, {
1250
+ size: "sm",
1251
+ color: "neutral",
1252
+ variant: "subtle"
1253
+ }, {
1254
+ default: withCtx(() => [
1255
+ createTextVNode(toDisplayString(unref(integration).type), 1)
1256
+ ]),
1257
+ _: 1
1258
+ })
1259
+ ]),
1260
+ createVNode(_component_USwitch, {
1261
+ modelValue: unref(formEnabled),
1262
+ "onUpdate:modelValue": ($event) => isRef(formEnabled) ? formEnabled.value = $event : null,
1263
+ size: "lg"
1264
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
1265
+ ]),
1266
+ createVNode("p", { class: "text-sm text-muted mt-1" }, toDisplayString(unref(integration).type) + " · " + toDisplayString(unref(integration).referenceId), 1)
1267
+ ]),
1268
+ createVNode("section", null, [
1269
+ createVNode("div", { class: "flex items-center justify-between gap-4 mb-1" }, [
1270
+ createVNode("h2", { class: "text-lg font-medium" }, " Connection ")
1271
+ ]),
1272
+ createVNode("div", { class: "border border-[var(--ui-border)] rounded-lg px-4 py-3" }, [
1273
+ createVNode(_component_IntegrationCredentials, {
1274
+ "integration-id": unref(integration).id,
1275
+ "integration-type": unref(integration).type,
1276
+ "current-variant": unref(integration).credentialVariant,
1277
+ onSaved: onCredentialChange,
1278
+ onDisconnected: onCredentialChange
1279
+ }, null, 8, ["integration-id", "integration-type", "current-variant"])
1280
+ ])
1281
+ ]),
1282
+ createVNode("section", { class: "space-y-3" }, [
1283
+ createVNode("h2", { class: "text-lg font-medium" }, " Access Level "),
1284
+ createVNode("div", { class: "flex gap-2" }, [
1285
+ createVNode("button", {
1286
+ type: "button",
1287
+ class: ["px-4 py-2 text-sm rounded-lg border transition-colors", unref(formMaxScope) !== "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-[var(--ui-border)] text-muted hover:bg-[var(--ui-bg-elevated)]"],
1288
+ onClick: ($event) => formMaxScope.value = null
1289
+ }, " Read + Write ", 10, ["onClick"]),
1290
+ createVNode("button", {
1291
+ type: "button",
1292
+ class: ["px-4 py-2 text-sm rounded-lg border transition-colors", unref(formMaxScope) === "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-[var(--ui-border)] text-muted hover:bg-[var(--ui-bg-elevated)]"],
1293
+ onClick: ($event) => formMaxScope.value = "read"
1294
+ }, " Read-only ", 10, ["onClick"])
1295
+ ]),
1296
+ unref(formMaxScope) === "read" ? (openBlock(), createBlock("p", {
1297
+ key: 0,
1298
+ class: "text-xs text-amber-600 dark:text-amber-400"
1299
+ }, " Only read tools will be available. Write and admin tools will be greyed out below. ")) : createCommentVNode("", true)
1300
+ ]),
1301
+ createVNode("section", { class: "space-y-3" }, [
1302
+ createVNode("h2", { class: "text-lg font-medium" }, " Tools "),
1303
+ createVNode(_component_IntegrationToolsTree, {
1304
+ ref_key: "toolsTreeRef",
1305
+ ref: toolsTreeRef,
1306
+ "integration-type": unref(integration).type,
1307
+ "max-scope": unref(formMaxScope),
1308
+ "enabled-toolsets": unref(formEnabledToolsets),
1309
+ "disabled-tools": unref(formDisabledTools),
1310
+ "onUpdate:enabledToolsets": ($event) => formEnabledToolsets.value = $event,
1311
+ "onUpdate:disabledTools": ($event) => formDisabledTools.value = $event
1312
+ }, null, 8, ["integration-type", "max-scope", "enabled-toolsets", "disabled-tools", "onUpdate:enabledToolsets", "onUpdate:disabledTools"])
1313
+ ]),
1314
+ createVNode("div", { class: "sticky bottom-0 py-4 bg-[var(--ui-bg)] border-t border-[var(--ui-border)] -mx-4 px-4 flex items-center justify-between gap-4" }, [
1315
+ createVNode(_component_UButton, {
1316
+ loading: unref(saving),
1317
+ size: "lg",
1318
+ onClick: saveAll
1319
+ }, {
1320
+ default: withCtx(() => [
1321
+ createTextVNode(" Save Changes ")
1322
+ ]),
1323
+ _: 1
1324
+ }, 8, ["loading"]),
1325
+ createVNode(_component_UButton, {
1326
+ variant: "soft",
1327
+ color: "error",
1328
+ icon: "i-lucide-trash-2",
1329
+ onClick: confirmRemove
1330
+ }, {
1331
+ default: withCtx(() => [
1332
+ createTextVNode(" Remove Integration ")
1333
+ ]),
1334
+ _: 1
1335
+ })
1336
+ ])
1337
+ ], 64))
1338
+ ];
1339
+ }
1340
+ }),
1341
+ _: 1
1342
+ }, _parent));
1343
+ };
1344
+ }
1345
+ });
1346
+ const _sfc_setup = _sfc_main.setup;
1347
+ _sfc_main.setup = (props, ctx) => {
1348
+ const ssrContext = useSSRContext();
1349
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/integrations/[id].vue");
1350
+ return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
1351
+ };
1352
+
1353
+ export { _sfc_main as default };
1354
+ //# sourceMappingURL=_id_-DBwSV4AY.mjs.map