@commandable/mcp 0.0.7 → 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 (217) 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 +124 -33
  107. package/dist/cli/setup.js.map +1 -1
  108. package/dist/config/configApply.js +1 -1
  109. package/dist/config/configApply.js.map +1 -1
  110. package/dist/config/configSchema.d.ts +6 -2
  111. package/dist/config/configSchema.d.ts.map +1 -1
  112. package/dist/config/configSchema.js +2 -1
  113. package/dist/config/configSchema.js.map +1 -1
  114. package/dist/db/client.d.ts +3 -1
  115. package/dist/db/client.d.ts.map +1 -1
  116. package/dist/db/client.js.map +1 -1
  117. package/dist/db/credentialStore.d.ts +2 -0
  118. package/dist/db/credentialStore.d.ts.map +1 -1
  119. package/dist/db/credentialStore.js +15 -16
  120. package/dist/db/credentialStore.js.map +1 -1
  121. package/dist/db/integrationStore.d.ts +7 -0
  122. package/dist/db/integrationStore.d.ts.map +1 -1
  123. package/dist/db/integrationStore.js +61 -31
  124. package/dist/db/integrationStore.js.map +1 -1
  125. package/dist/db/integrationTypeConfigStore.d.ts +6 -0
  126. package/dist/db/integrationTypeConfigStore.d.ts.map +1 -0
  127. package/dist/db/integrationTypeConfigStore.js +94 -0
  128. package/dist/db/integrationTypeConfigStore.js.map +1 -0
  129. package/dist/db/migrate.d.ts.map +1 -1
  130. package/dist/db/migrate.js +8 -109
  131. package/dist/db/migrate.js.map +1 -1
  132. package/dist/db/migrations/pg/0000_initial.sql +74 -0
  133. package/dist/db/migrations/pg/meta/_journal.json +13 -0
  134. package/dist/db/migrations/sqlite/0000_initial.sql +74 -0
  135. package/dist/db/migrations/sqlite/meta/_journal.json +13 -0
  136. package/dist/db/schema.d.ts +961 -153
  137. package/dist/db/schema.d.ts.map +1 -1
  138. package/dist/db/schema.js +55 -3
  139. package/dist/db/schema.js.map +1 -1
  140. package/dist/db/toolDefinitionStore.d.ts +6 -0
  141. package/dist/db/toolDefinitionStore.d.ts.map +1 -0
  142. package/dist/db/toolDefinitionStore.js +95 -0
  143. package/dist/db/toolDefinitionStore.js.map +1 -0
  144. package/dist/index.d.ts +7 -0
  145. package/dist/index.d.ts.map +1 -1
  146. package/dist/index.js +7 -0
  147. package/dist/index.js.map +1 -1
  148. package/dist/integrations/actionsFactory.d.ts +5 -1
  149. package/dist/integrations/actionsFactory.d.ts.map +1 -1
  150. package/dist/integrations/actionsFactory.js +37 -14
  151. package/dist/integrations/actionsFactory.js.map +1 -1
  152. package/dist/integrations/customToolFactory.d.ts +13 -0
  153. package/dist/integrations/customToolFactory.d.ts.map +1 -0
  154. package/dist/integrations/customToolFactory.js +31 -0
  155. package/dist/integrations/customToolFactory.js.map +1 -0
  156. package/dist/integrations/dataLoader.d.ts +2 -2
  157. package/dist/integrations/dataLoader.d.ts.map +1 -1
  158. package/dist/integrations/dataLoader.js +1 -1
  159. package/dist/integrations/dataLoader.js.map +1 -1
  160. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts +7 -0
  161. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts.map +1 -0
  162. package/dist/integrations/fileIntegrationTypeConfigStore.js +34 -0
  163. package/dist/integrations/fileIntegrationTypeConfigStore.js.map +1 -0
  164. package/dist/integrations/getIntegration.d.ts +4 -1
  165. package/dist/integrations/getIntegration.d.ts.map +1 -1
  166. package/dist/integrations/getIntegration.js +12 -4
  167. package/dist/integrations/getIntegration.js.map +1 -1
  168. package/dist/integrations/health.d.ts +20 -0
  169. package/dist/integrations/health.d.ts.map +1 -0
  170. package/dist/integrations/health.js +43 -0
  171. package/dist/integrations/health.js.map +1 -0
  172. package/dist/integrations/integrationTypeConfigLookup.d.ts +12 -0
  173. package/dist/integrations/integrationTypeConfigLookup.d.ts.map +1 -0
  174. package/dist/integrations/integrationTypeConfigLookup.js +11 -0
  175. package/dist/integrations/integrationTypeConfigLookup.js.map +1 -0
  176. package/dist/integrations/providerRegistry.d.ts.map +1 -1
  177. package/dist/integrations/providerRegistry.js +0 -4
  178. package/dist/integrations/providerRegistry.js.map +1 -1
  179. package/dist/integrations/proxy.d.ts +4 -1
  180. package/dist/integrations/proxy.d.ts.map +1 -1
  181. package/dist/integrations/proxy.js +94 -106
  182. package/dist/integrations/proxy.js.map +1 -1
  183. package/dist/integrations/sandbox.js +11 -1
  184. package/dist/integrations/sandbox.js.map +1 -1
  185. package/dist/mcp/abilityCatalog.d.ts +46 -0
  186. package/dist/mcp/abilityCatalog.d.ts.map +1 -0
  187. package/dist/mcp/abilityCatalog.js +275 -0
  188. package/dist/mcp/abilityCatalog.js.map +1 -0
  189. package/dist/mcp/builder_guide.md +441 -0
  190. package/dist/mcp/commandable_readme.md +29 -0
  191. package/dist/mcp/handlers.d.ts +10 -1
  192. package/dist/mcp/handlers.d.ts.map +1 -1
  193. package/dist/mcp/handlers.js +51 -4
  194. package/dist/mcp/handlers.js.map +1 -1
  195. package/dist/mcp/metaTools.d.ts +77 -0
  196. package/dist/mcp/metaTools.d.ts.map +1 -0
  197. package/dist/mcp/metaTools.js +753 -0
  198. package/dist/mcp/metaTools.js.map +1 -0
  199. package/dist/mcp/server.d.ts +10 -0
  200. package/dist/mcp/server.d.ts.map +1 -1
  201. package/dist/mcp/server.js +2 -2
  202. package/dist/mcp/server.js.map +1 -1
  203. package/dist/mcp/sessionState.d.ts +18 -0
  204. package/dist/mcp/sessionState.d.ts.map +1 -0
  205. package/dist/mcp/sessionState.js +65 -0
  206. package/dist/mcp/sessionState.js.map +1 -0
  207. package/dist/mcp/toolAdapter.d.ts +17 -0
  208. package/dist/mcp/toolAdapter.d.ts.map +1 -1
  209. package/dist/mcp/toolAdapter.js +7 -1
  210. package/dist/mcp/toolAdapter.js.map +1 -1
  211. package/dist/types.d.ts +61 -2
  212. package/dist/types.d.ts.map +1 -1
  213. package/dist/version.d.ts +2 -0
  214. package/dist/version.d.ts.map +1 -0
  215. package/dist/version.js +7 -0
  216. package/dist/version.js.map +1 -0
  217. package/package.json +7 -5
@@ -0,0 +1,720 @@
1
+ import { m as _sfc_main$b, i as _sfc_main$h, a as __nuxt_component_0$1, g as _sfc_main$m, n as navigateTo, j as _sfc_main$9 } from './server.mjs';
2
+ import { u as useFetch, _ as _sfc_main$4, a as _sfc_main$3, c as _sfc_main$2, d as _sfc_main$1$1, b as __nuxt_component_3 } from './fetch-ZbqIFhDG.mjs';
3
+ import { defineComponent, withAsyncContext, reactive, ref, watchEffect, mergeProps, withCtx, createTextVNode, unref, toDisplayString, createVNode, openBlock, createBlock, createCommentVNode, Fragment, withModifiers, isRef, renderList, computed, watch, useSSRContext } from 'vue';
4
+ import { ssrRenderComponent, ssrRenderList, ssrInterpolate, ssrRenderClass } from 'vue/server-renderer';
5
+ import '../nitro/nitro.mjs';
6
+ import '@modelcontextprotocol/sdk/types.js';
7
+ import '@modelcontextprotocol/sdk/server/index.js';
8
+ import '@modelcontextprotocol/sdk/server/streamableHttp.js';
9
+ import 'node:crypto';
10
+ import 'fastest-levenshtein';
11
+ import 'node:fs';
12
+ import 'node:path';
13
+ import 'node:url';
14
+ import 'node:vm';
15
+ import 'turndown';
16
+ import 'marked';
17
+ import 'drizzle-orm';
18
+ import 'node:buffer';
19
+ import 'google-auth-library';
20
+ import 'node:http';
21
+ import 'node:https';
22
+ import 'node:events';
23
+ import 'node:os';
24
+ import 'better-sqlite3';
25
+ import 'drizzle-orm/better-sqlite3';
26
+ import 'drizzle-orm/node-postgres';
27
+ import 'pg';
28
+ import 'node:process';
29
+ import 'js-yaml';
30
+ import 'zod';
31
+ import 'drizzle-orm/sqlite-core';
32
+ import 'drizzle-orm/pg-core';
33
+ import '@iconify/utils';
34
+ import 'consola';
35
+ import 'vue-router';
36
+ import 'tailwindcss/colors';
37
+ import '@iconify/vue';
38
+ import 'reka-ui';
39
+ import '@vueuse/core';
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 _sfc_main$1 = /* @__PURE__ */ defineComponent({
53
+ __name: "AddIntegrationModal",
54
+ __ssrInlineRender: true,
55
+ props: {
56
+ open: { type: Boolean }
57
+ },
58
+ emits: ["update:open", "created"],
59
+ async setup(__props, { emit: __emit }) {
60
+ let __temp, __restore;
61
+ const props = __props;
62
+ const emit = __emit;
63
+ const isOpen = computed({
64
+ get: () => props.open,
65
+ set: (v) => emit("update:open", v)
66
+ });
67
+ const { data: catalog } = ([__temp, __restore] = withAsyncContext(() => useFetch(
68
+ "/api/catalog",
69
+ "$vYIVj-kaX8"
70
+ /* nuxt-injected */
71
+ )), __temp = await __temp, __restore(), __temp);
72
+ const catalogTypes = computed(() => (catalog.value || []).map((i) => ({ label: i.type, value: i.type })));
73
+ const selectedType = ref(void 0);
74
+ const selectedTypeMaxScope = ref(null);
75
+ const selectedTypeEnabledToolsets = ref([]);
76
+ const selectedTypeDisabledTools = ref([]);
77
+ const toolsTreeRef = ref(null);
78
+ const creating = ref(false);
79
+ watch(isOpen, (open) => {
80
+ if (!open) return;
81
+ selectedType.value = void 0;
82
+ selectedTypeMaxScope.value = null;
83
+ selectedTypeEnabledToolsets.value = [];
84
+ selectedTypeDisabledTools.value = [];
85
+ });
86
+ watch(selectedType, () => {
87
+ selectedTypeMaxScope.value = null;
88
+ selectedTypeEnabledToolsets.value = [];
89
+ selectedTypeDisabledTools.value = [];
90
+ });
91
+ watch(() => toolsTreeRef.value?.toolsets, (toolsets) => {
92
+ if (!selectedType.value || !toolsets?.length)
93
+ return;
94
+ if (!selectedTypeEnabledToolsets.value.length)
95
+ selectedTypeEnabledToolsets.value = toolsets.map((t) => t.key);
96
+ }, { deep: true });
97
+ async function create() {
98
+ if (!selectedType.value) return;
99
+ creating.value = true;
100
+ try {
101
+ const toolsetKeys = (toolsTreeRef.value?.toolsets || []).map((t) => t.key);
102
+ const realToolsetKeys = toolsetKeys.filter((k) => k !== "__all__");
103
+ const enabledToolsets = realToolsetKeys.length ? selectedTypeEnabledToolsets.value.length < realToolsetKeys.length ? selectedTypeEnabledToolsets.value.filter((k) => k !== "__all__") : void 0 : void 0;
104
+ const result = await $fetch("/api/integrations", {
105
+ method: "POST",
106
+ body: {
107
+ type: selectedType.value,
108
+ maxScope: selectedTypeMaxScope.value || void 0,
109
+ enabledToolsets,
110
+ disabledTools: selectedTypeDisabledTools.value.length ? selectedTypeDisabledTools.value : void 0
111
+ }
112
+ });
113
+ isOpen.value = false;
114
+ emit("created", result.id);
115
+ } finally {
116
+ creating.value = false;
117
+ }
118
+ }
119
+ return (_ctx, _push, _parent, _attrs) => {
120
+ const _component_UModal = _sfc_main$9;
121
+ const _component_UFormField = _sfc_main$2;
122
+ const _component_USelect = _sfc_main$1$1;
123
+ const _component_IntegrationToolsTree = __nuxt_component_3;
124
+ const _component_UButton = _sfc_main$h;
125
+ _push(ssrRenderComponent(_component_UModal, mergeProps({
126
+ open: unref(isOpen),
127
+ "onUpdate:open": ($event) => isRef(isOpen) ? isOpen.value = $event : null,
128
+ title: "Add integration",
129
+ description: "Choose a service to connect."
130
+ }, _attrs), {
131
+ body: withCtx((_, _push2, _parent2, _scopeId) => {
132
+ if (_push2) {
133
+ _push2(`<div class="space-y-4"${_scopeId}>`);
134
+ _push2(ssrRenderComponent(_component_UFormField, { label: "Integration type" }, {
135
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
136
+ if (_push3) {
137
+ _push3(ssrRenderComponent(_component_USelect, {
138
+ modelValue: unref(selectedType),
139
+ "onUpdate:modelValue": ($event) => isRef(selectedType) ? selectedType.value = $event : null,
140
+ items: unref(catalogTypes),
141
+ placeholder: "Select a service...",
142
+ class: "w-full"
143
+ }, null, _parent3, _scopeId2));
144
+ } else {
145
+ return [
146
+ createVNode(_component_USelect, {
147
+ modelValue: unref(selectedType),
148
+ "onUpdate:modelValue": ($event) => isRef(selectedType) ? selectedType.value = $event : null,
149
+ items: unref(catalogTypes),
150
+ placeholder: "Select a service...",
151
+ class: "w-full"
152
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "items"])
153
+ ];
154
+ }
155
+ }),
156
+ _: 1
157
+ }, _parent2, _scopeId));
158
+ if (unref(selectedType)) {
159
+ _push2(`<div class="space-y-2"${_scopeId}><div class="text-sm font-medium"${_scopeId}> Access level </div><div class="flex gap-2"${_scopeId}><button type="button" class="${ssrRenderClass([unref(selectedTypeMaxScope) !== "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-slate-200 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-400", "px-3 py-1.5 text-sm rounded-md border transition-colors"])}"${_scopeId}> Read + Write </button><button type="button" class="${ssrRenderClass([unref(selectedTypeMaxScope) === "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-slate-200 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-400", "px-3 py-1.5 text-sm rounded-md border transition-colors"])}"${_scopeId}> Read-only </button></div>`);
160
+ if (unref(selectedTypeMaxScope) === "read") {
161
+ _push2(`<p class="text-xs text-amber-600 dark:text-amber-400"${_scopeId}> Write/admin tools are greyed out automatically. </p>`);
162
+ } else {
163
+ _push2(`<!---->`);
164
+ }
165
+ _push2(`</div>`);
166
+ } else {
167
+ _push2(`<!---->`);
168
+ }
169
+ if (unref(selectedType)) {
170
+ _push2(`<details class="border border-[var(--ui-border)] rounded-md"${_scopeId}><summary class="cursor-pointer select-none px-3 py-2 text-sm font-medium"${_scopeId}> Advanced tool controls (optional) </summary><div class="px-3 pb-3 pt-1 space-y-3"${_scopeId}>`);
171
+ _push2(ssrRenderComponent(_component_IntegrationToolsTree, {
172
+ ref_key: "toolsTreeRef",
173
+ ref: toolsTreeRef,
174
+ "integration-type": unref(selectedType),
175
+ "max-scope": unref(selectedTypeMaxScope),
176
+ "enabled-toolsets": unref(selectedTypeEnabledToolsets),
177
+ "disabled-tools": unref(selectedTypeDisabledTools),
178
+ "onUpdate:enabledToolsets": ($event) => selectedTypeEnabledToolsets.value = $event,
179
+ "onUpdate:disabledTools": ($event) => selectedTypeDisabledTools.value = $event
180
+ }, null, _parent2, _scopeId));
181
+ _push2(`</div></details>`);
182
+ } else {
183
+ _push2(`<!---->`);
184
+ }
185
+ _push2(`</div>`);
186
+ } else {
187
+ return [
188
+ createVNode("div", { class: "space-y-4" }, [
189
+ createVNode(_component_UFormField, { label: "Integration type" }, {
190
+ default: withCtx(() => [
191
+ createVNode(_component_USelect, {
192
+ modelValue: unref(selectedType),
193
+ "onUpdate:modelValue": ($event) => isRef(selectedType) ? selectedType.value = $event : null,
194
+ items: unref(catalogTypes),
195
+ placeholder: "Select a service...",
196
+ class: "w-full"
197
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "items"])
198
+ ]),
199
+ _: 1
200
+ }),
201
+ unref(selectedType) ? (openBlock(), createBlock("div", {
202
+ key: 0,
203
+ class: "space-y-2"
204
+ }, [
205
+ createVNode("div", { class: "text-sm font-medium" }, " Access level "),
206
+ createVNode("div", { class: "flex gap-2" }, [
207
+ createVNode("button", {
208
+ type: "button",
209
+ class: ["px-3 py-1.5 text-sm rounded-md border transition-colors", unref(selectedTypeMaxScope) !== "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-slate-200 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-400"],
210
+ onClick: ($event) => selectedTypeMaxScope.value = null
211
+ }, " Read + Write ", 10, ["onClick"]),
212
+ createVNode("button", {
213
+ type: "button",
214
+ class: ["px-3 py-1.5 text-sm rounded-md border transition-colors", unref(selectedTypeMaxScope) === "read" ? "border-green-500 bg-green-50 text-green-700 font-medium dark:bg-green-950 dark:text-green-300" : "border-slate-200 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-400"],
215
+ onClick: ($event) => selectedTypeMaxScope.value = "read"
216
+ }, " Read-only ", 10, ["onClick"])
217
+ ]),
218
+ unref(selectedTypeMaxScope) === "read" ? (openBlock(), createBlock("p", {
219
+ key: 0,
220
+ class: "text-xs text-amber-600 dark:text-amber-400"
221
+ }, " Write/admin tools are greyed out automatically. ")) : createCommentVNode("", true)
222
+ ])) : createCommentVNode("", true),
223
+ unref(selectedType) ? (openBlock(), createBlock("details", {
224
+ key: 1,
225
+ class: "border border-[var(--ui-border)] rounded-md"
226
+ }, [
227
+ createVNode("summary", { class: "cursor-pointer select-none px-3 py-2 text-sm font-medium" }, " Advanced tool controls (optional) "),
228
+ createVNode("div", { class: "px-3 pb-3 pt-1 space-y-3" }, [
229
+ createVNode(_component_IntegrationToolsTree, {
230
+ ref_key: "toolsTreeRef",
231
+ ref: toolsTreeRef,
232
+ "integration-type": unref(selectedType),
233
+ "max-scope": unref(selectedTypeMaxScope),
234
+ "enabled-toolsets": unref(selectedTypeEnabledToolsets),
235
+ "disabled-tools": unref(selectedTypeDisabledTools),
236
+ "onUpdate:enabledToolsets": ($event) => selectedTypeEnabledToolsets.value = $event,
237
+ "onUpdate:disabledTools": ($event) => selectedTypeDisabledTools.value = $event
238
+ }, null, 8, ["integration-type", "max-scope", "enabled-toolsets", "disabled-tools", "onUpdate:enabledToolsets", "onUpdate:disabledTools"])
239
+ ])
240
+ ])) : createCommentVNode("", true)
241
+ ])
242
+ ];
243
+ }
244
+ }),
245
+ footer: withCtx((_, _push2, _parent2, _scopeId) => {
246
+ if (_push2) {
247
+ _push2(`<div class="flex justify-end gap-2"${_scopeId}>`);
248
+ _push2(ssrRenderComponent(_component_UButton, {
249
+ variant: "soft",
250
+ color: "neutral",
251
+ onClick: ($event) => isOpen.value = false
252
+ }, {
253
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
254
+ if (_push3) {
255
+ _push3(` Cancel `);
256
+ } else {
257
+ return [
258
+ createTextVNode(" Cancel ")
259
+ ];
260
+ }
261
+ }),
262
+ _: 1
263
+ }, _parent2, _scopeId));
264
+ _push2(ssrRenderComponent(_component_UButton, {
265
+ disabled: !unref(selectedType) || unref(creating),
266
+ loading: unref(creating),
267
+ onClick: create
268
+ }, {
269
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
270
+ if (_push3) {
271
+ _push3(` Add `);
272
+ } else {
273
+ return [
274
+ createTextVNode(" Add ")
275
+ ];
276
+ }
277
+ }),
278
+ _: 1
279
+ }, _parent2, _scopeId));
280
+ _push2(`</div>`);
281
+ } else {
282
+ return [
283
+ createVNode("div", { class: "flex justify-end gap-2" }, [
284
+ createVNode(_component_UButton, {
285
+ variant: "soft",
286
+ color: "neutral",
287
+ onClick: ($event) => isOpen.value = false
288
+ }, {
289
+ default: withCtx(() => [
290
+ createTextVNode(" Cancel ")
291
+ ]),
292
+ _: 1
293
+ }, 8, ["onClick"]),
294
+ createVNode(_component_UButton, {
295
+ disabled: !unref(selectedType) || unref(creating),
296
+ loading: unref(creating),
297
+ onClick: create
298
+ }, {
299
+ default: withCtx(() => [
300
+ createTextVNode(" Add ")
301
+ ]),
302
+ _: 1
303
+ }, 8, ["disabled", "loading"])
304
+ ])
305
+ ];
306
+ }
307
+ }),
308
+ _: 1
309
+ }, _parent));
310
+ };
311
+ }
312
+ });
313
+ const _sfc_setup$1 = _sfc_main$1.setup;
314
+ _sfc_main$1.setup = (props, ctx) => {
315
+ const ssrContext = useSSRContext();
316
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/AddIntegrationModal.vue");
317
+ return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0;
318
+ };
319
+ const __nuxt_component_6 = Object.assign(_sfc_main$1, { __name: "AddIntegrationModal" });
320
+ const _sfc_main = /* @__PURE__ */ defineComponent({
321
+ __name: "index",
322
+ __ssrInlineRender: true,
323
+ async setup(__props) {
324
+ let __temp, __restore;
325
+ const { data: integrations, pending, error, refresh } = ([__temp, __restore] = withAsyncContext(() => useFetch(
326
+ "/api/integrations",
327
+ "$3JxGA1emOo"
328
+ /* nuxt-injected */
329
+ )), __temp = await __temp, __restore(), __temp);
330
+ const healthStatus = reactive({});
331
+ const showAddModal = ref(false);
332
+ watchEffect(async () => {
333
+ if (!integrations.value) return;
334
+ for (const i of integrations.value) {
335
+ if (healthStatus[i.id] !== void 0) continue;
336
+ const res = await $fetch(`/api/integrations/${i.id}/credentials-status`).catch(() => null);
337
+ healthStatus[i.id] = res?.health_status ?? "disconnected";
338
+ }
339
+ });
340
+ async function toggleEnabled(integ, enabled) {
341
+ await $fetch("/api/integrations", {
342
+ method: "POST",
343
+ body: { ...integ, enabled }
344
+ });
345
+ await refresh();
346
+ }
347
+ function onIntegrationCreated(id) {
348
+ navigateTo(`/integrations/${id}`);
349
+ }
350
+ return (_ctx, _push, _parent, _attrs) => {
351
+ const _component_UContainer = _sfc_main$b;
352
+ const _component_UButton = _sfc_main$h;
353
+ const _component_NuxtLink = __nuxt_component_0$1;
354
+ const _component_UBadge = _sfc_main$4;
355
+ const _component_USwitch = _sfc_main$3;
356
+ const _component_UIcon = _sfc_main$m;
357
+ const _component_AddIntegrationModal = __nuxt_component_6;
358
+ _push(ssrRenderComponent(_component_UContainer, mergeProps({ class: "py-10 space-y-6" }, _attrs), {
359
+ default: withCtx((_, _push2, _parent2, _scopeId) => {
360
+ if (_push2) {
361
+ _push2(`<div class="flex items-center justify-between gap-4"${_scopeId}><div class="space-y-1"${_scopeId}><h1 class="text-2xl font-semibold"${_scopeId}> Integrations </h1><p class="text-sm text-muted"${_scopeId}> Manage your connected services. </p></div>`);
362
+ _push2(ssrRenderComponent(_component_UButton, {
363
+ icon: "i-lucide-plus",
364
+ onClick: ($event) => showAddModal.value = true
365
+ }, {
366
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
367
+ if (_push3) {
368
+ _push3(` Add Integration `);
369
+ } else {
370
+ return [
371
+ createTextVNode(" Add Integration ")
372
+ ];
373
+ }
374
+ }),
375
+ _: 1
376
+ }, _parent2, _scopeId));
377
+ _push2(`</div>`);
378
+ if (unref(pending)) {
379
+ _push2(`<div class="text-sm text-muted py-8 text-center"${_scopeId}> Loading… </div>`);
380
+ } else if (unref(error)) {
381
+ _push2(`<div class="text-sm text-red-600 py-8 text-center"${_scopeId}> Failed to load integrations. </div>`);
382
+ } else if (!unref(integrations)?.length) {
383
+ _push2(`<div class="py-16 text-center space-y-4"${_scopeId}><div class="text-muted text-sm"${_scopeId}> No integrations yet. </div>`);
384
+ _push2(ssrRenderComponent(_component_UButton, {
385
+ icon: "i-lucide-plus",
386
+ variant: "soft",
387
+ onClick: ($event) => showAddModal.value = true
388
+ }, {
389
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
390
+ if (_push3) {
391
+ _push3(` Add your first integration `);
392
+ } else {
393
+ return [
394
+ createTextVNode(" Add your first integration ")
395
+ ];
396
+ }
397
+ }),
398
+ _: 1
399
+ }, _parent2, _scopeId));
400
+ _push2(`</div>`);
401
+ } else {
402
+ _push2(`<div class="space-y-2"${_scopeId}><!--[-->`);
403
+ ssrRenderList(unref(integrations), (integ) => {
404
+ _push2(ssrRenderComponent(_component_NuxtLink, {
405
+ key: integ.id,
406
+ to: `/integrations/${integ.id}`,
407
+ class: "flex items-center gap-4 p-4 rounded-lg border border-[var(--ui-border)] hover:bg-[var(--ui-bg-elevated)] transition-colors group"
408
+ }, {
409
+ default: withCtx((_2, _push3, _parent3, _scopeId2) => {
410
+ if (_push3) {
411
+ _push3(`<div class="min-w-0 flex-1"${_scopeId2}><div class="flex items-center gap-2"${_scopeId2}><span class="font-medium truncate"${_scopeId2}>${ssrInterpolate(integ.label)}</span>`);
412
+ _push3(ssrRenderComponent(_component_UBadge, {
413
+ size: "xs",
414
+ color: "neutral",
415
+ variant: "subtle"
416
+ }, {
417
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
418
+ if (_push4) {
419
+ _push4(`${ssrInterpolate(integ.type)}`);
420
+ } else {
421
+ return [
422
+ createTextVNode(toDisplayString(integ.type), 1)
423
+ ];
424
+ }
425
+ }),
426
+ _: 2
427
+ }, _parent3, _scopeId2));
428
+ if (integ.maxScope === "read") {
429
+ _push3(ssrRenderComponent(_component_UBadge, {
430
+ size: "xs",
431
+ color: "warning",
432
+ variant: "soft"
433
+ }, {
434
+ default: withCtx((_3, _push4, _parent4, _scopeId3) => {
435
+ if (_push4) {
436
+ _push4(` Read-only `);
437
+ } else {
438
+ return [
439
+ createTextVNode(" Read-only ")
440
+ ];
441
+ }
442
+ }),
443
+ _: 2
444
+ }, _parent3, _scopeId2));
445
+ } else {
446
+ _push3(`<!---->`);
447
+ }
448
+ _push3(`</div><div class="mt-1 flex items-center gap-2 flex-wrap"${_scopeId2}>`);
449
+ if (unref(healthStatus)[integ.id] !== void 0) {
450
+ _push3(`<span class="${ssrRenderClass([{
451
+ "bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-400": unref(healthStatus)[integ.id] === "connected",
452
+ "bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-400": unref(healthStatus)[integ.id] === "invalid_credentials" || unref(healthStatus)[integ.id] === "disconnected"
453
+ }, "inline-flex items-center gap-1 text-xs font-medium px-1.5 py-0.5 rounded"])}"${_scopeId2}><span class="${ssrRenderClass([{
454
+ "bg-green-500": unref(healthStatus)[integ.id] === "connected",
455
+ "bg-red-500": unref(healthStatus)[integ.id] === "invalid_credentials" || unref(healthStatus)[integ.id] === "disconnected"
456
+ }, "inline-block w-1.5 h-1.5 rounded-full"])}"${_scopeId2}></span>`);
457
+ if (unref(healthStatus)[integ.id] === "connected") {
458
+ _push3(`<!--[-->Connected<!--]-->`);
459
+ } else if (unref(healthStatus)[integ.id] === "invalid_credentials") {
460
+ _push3(`<!--[-->Invalid credentials<!--]-->`);
461
+ } else {
462
+ _push3(`<!--[-->Not connected<!--]-->`);
463
+ }
464
+ _push3(`</span>`);
465
+ } else {
466
+ _push3(`<!---->`);
467
+ }
468
+ if (integ.enabledToolsets?.length) {
469
+ _push3(`<span class="text-xs text-muted"${_scopeId2}>${ssrInterpolate(integ.enabledToolsets.length)} toolset${ssrInterpolate(integ.enabledToolsets.length === 1 ? "" : "s")}</span>`);
470
+ } else {
471
+ _push3(`<!---->`);
472
+ }
473
+ if (integ.disabledTools?.length) {
474
+ _push3(`<span class="text-xs text-muted"${_scopeId2}>${ssrInterpolate(integ.disabledTools.length)} tool${ssrInterpolate(integ.disabledTools.length === 1 ? "" : "s")} blocked </span>`);
475
+ } else {
476
+ _push3(`<!---->`);
477
+ }
478
+ _push3(`</div></div><div class="flex items-center gap-3"${_scopeId2}>`);
479
+ _push3(ssrRenderComponent(_component_USwitch, {
480
+ "model-value": integ.enabled !== false,
481
+ "onUpdate:modelValue": ($event) => toggleEnabled(integ, $event)
482
+ }, null, _parent3, _scopeId2));
483
+ _push3(`</div>`);
484
+ _push3(ssrRenderComponent(_component_UIcon, {
485
+ name: "i-lucide-chevron-right",
486
+ class: "text-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
487
+ }, null, _parent3, _scopeId2));
488
+ } else {
489
+ return [
490
+ createVNode("div", { class: "min-w-0 flex-1" }, [
491
+ createVNode("div", { class: "flex items-center gap-2" }, [
492
+ createVNode("span", { class: "font-medium truncate" }, toDisplayString(integ.label), 1),
493
+ createVNode(_component_UBadge, {
494
+ size: "xs",
495
+ color: "neutral",
496
+ variant: "subtle"
497
+ }, {
498
+ default: withCtx(() => [
499
+ createTextVNode(toDisplayString(integ.type), 1)
500
+ ]),
501
+ _: 2
502
+ }, 1024),
503
+ integ.maxScope === "read" ? (openBlock(), createBlock(_component_UBadge, {
504
+ key: 0,
505
+ size: "xs",
506
+ color: "warning",
507
+ variant: "soft"
508
+ }, {
509
+ default: withCtx(() => [
510
+ createTextVNode(" Read-only ")
511
+ ]),
512
+ _: 1
513
+ })) : createCommentVNode("", true)
514
+ ]),
515
+ createVNode("div", { class: "mt-1 flex items-center gap-2 flex-wrap" }, [
516
+ unref(healthStatus)[integ.id] !== void 0 ? (openBlock(), createBlock("span", {
517
+ key: 0,
518
+ class: ["inline-flex items-center gap-1 text-xs font-medium px-1.5 py-0.5 rounded", {
519
+ "bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-400": unref(healthStatus)[integ.id] === "connected",
520
+ "bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-400": unref(healthStatus)[integ.id] === "invalid_credentials" || unref(healthStatus)[integ.id] === "disconnected"
521
+ }]
522
+ }, [
523
+ createVNode("span", {
524
+ class: ["inline-block w-1.5 h-1.5 rounded-full", {
525
+ "bg-green-500": unref(healthStatus)[integ.id] === "connected",
526
+ "bg-red-500": unref(healthStatus)[integ.id] === "invalid_credentials" || unref(healthStatus)[integ.id] === "disconnected"
527
+ }]
528
+ }, null, 2),
529
+ unref(healthStatus)[integ.id] === "connected" ? (openBlock(), createBlock(Fragment, { key: 0 }, [
530
+ createTextVNode("Connected")
531
+ ], 64)) : unref(healthStatus)[integ.id] === "invalid_credentials" ? (openBlock(), createBlock(Fragment, { key: 1 }, [
532
+ createTextVNode("Invalid credentials")
533
+ ], 64)) : (openBlock(), createBlock(Fragment, { key: 2 }, [
534
+ createTextVNode("Not connected")
535
+ ], 64))
536
+ ], 2)) : createCommentVNode("", true),
537
+ integ.enabledToolsets?.length ? (openBlock(), createBlock("span", {
538
+ key: 1,
539
+ class: "text-xs text-muted"
540
+ }, toDisplayString(integ.enabledToolsets.length) + " toolset" + toDisplayString(integ.enabledToolsets.length === 1 ? "" : "s"), 1)) : createCommentVNode("", true),
541
+ integ.disabledTools?.length ? (openBlock(), createBlock("span", {
542
+ key: 2,
543
+ class: "text-xs text-muted"
544
+ }, toDisplayString(integ.disabledTools.length) + " tool" + toDisplayString(integ.disabledTools.length === 1 ? "" : "s") + " blocked ", 1)) : createCommentVNode("", true)
545
+ ])
546
+ ]),
547
+ createVNode("div", {
548
+ class: "flex items-center gap-3",
549
+ onClick: withModifiers(() => {
550
+ }, ["prevent", "stop"])
551
+ }, [
552
+ createVNode(_component_USwitch, {
553
+ "model-value": integ.enabled !== false,
554
+ "onUpdate:modelValue": ($event) => toggleEnabled(integ, $event)
555
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
556
+ ], 8, ["onClick"]),
557
+ createVNode(_component_UIcon, {
558
+ name: "i-lucide-chevron-right",
559
+ class: "text-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
560
+ })
561
+ ];
562
+ }
563
+ }),
564
+ _: 2
565
+ }, _parent2, _scopeId));
566
+ });
567
+ _push2(`<!--]--></div>`);
568
+ }
569
+ _push2(ssrRenderComponent(_component_AddIntegrationModal, {
570
+ open: unref(showAddModal),
571
+ "onUpdate:open": ($event) => isRef(showAddModal) ? showAddModal.value = $event : null,
572
+ onCreated: onIntegrationCreated
573
+ }, null, _parent2, _scopeId));
574
+ } else {
575
+ return [
576
+ createVNode("div", { class: "flex items-center justify-between gap-4" }, [
577
+ createVNode("div", { class: "space-y-1" }, [
578
+ createVNode("h1", { class: "text-2xl font-semibold" }, " Integrations "),
579
+ createVNode("p", { class: "text-sm text-muted" }, " Manage your connected services. ")
580
+ ]),
581
+ createVNode(_component_UButton, {
582
+ icon: "i-lucide-plus",
583
+ onClick: ($event) => showAddModal.value = true
584
+ }, {
585
+ default: withCtx(() => [
586
+ createTextVNode(" Add Integration ")
587
+ ]),
588
+ _: 1
589
+ }, 8, ["onClick"])
590
+ ]),
591
+ unref(pending) ? (openBlock(), createBlock("div", {
592
+ key: 0,
593
+ class: "text-sm text-muted py-8 text-center"
594
+ }, " Loading… ")) : unref(error) ? (openBlock(), createBlock("div", {
595
+ key: 1,
596
+ class: "text-sm text-red-600 py-8 text-center"
597
+ }, " Failed to load integrations. ")) : !unref(integrations)?.length ? (openBlock(), createBlock("div", {
598
+ key: 2,
599
+ class: "py-16 text-center space-y-4"
600
+ }, [
601
+ createVNode("div", { class: "text-muted text-sm" }, " No integrations yet. "),
602
+ createVNode(_component_UButton, {
603
+ icon: "i-lucide-plus",
604
+ variant: "soft",
605
+ onClick: ($event) => showAddModal.value = true
606
+ }, {
607
+ default: withCtx(() => [
608
+ createTextVNode(" Add your first integration ")
609
+ ]),
610
+ _: 1
611
+ }, 8, ["onClick"])
612
+ ])) : (openBlock(), createBlock("div", {
613
+ key: 3,
614
+ class: "space-y-2"
615
+ }, [
616
+ (openBlock(true), createBlock(Fragment, null, renderList(unref(integrations), (integ) => {
617
+ return openBlock(), createBlock(_component_NuxtLink, {
618
+ key: integ.id,
619
+ to: `/integrations/${integ.id}`,
620
+ class: "flex items-center gap-4 p-4 rounded-lg border border-[var(--ui-border)] hover:bg-[var(--ui-bg-elevated)] transition-colors group"
621
+ }, {
622
+ default: withCtx(() => [
623
+ createVNode("div", { class: "min-w-0 flex-1" }, [
624
+ createVNode("div", { class: "flex items-center gap-2" }, [
625
+ createVNode("span", { class: "font-medium truncate" }, toDisplayString(integ.label), 1),
626
+ createVNode(_component_UBadge, {
627
+ size: "xs",
628
+ color: "neutral",
629
+ variant: "subtle"
630
+ }, {
631
+ default: withCtx(() => [
632
+ createTextVNode(toDisplayString(integ.type), 1)
633
+ ]),
634
+ _: 2
635
+ }, 1024),
636
+ integ.maxScope === "read" ? (openBlock(), createBlock(_component_UBadge, {
637
+ key: 0,
638
+ size: "xs",
639
+ color: "warning",
640
+ variant: "soft"
641
+ }, {
642
+ default: withCtx(() => [
643
+ createTextVNode(" Read-only ")
644
+ ]),
645
+ _: 1
646
+ })) : createCommentVNode("", true)
647
+ ]),
648
+ createVNode("div", { class: "mt-1 flex items-center gap-2 flex-wrap" }, [
649
+ unref(healthStatus)[integ.id] !== void 0 ? (openBlock(), createBlock("span", {
650
+ key: 0,
651
+ class: ["inline-flex items-center gap-1 text-xs font-medium px-1.5 py-0.5 rounded", {
652
+ "bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-400": unref(healthStatus)[integ.id] === "connected",
653
+ "bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-400": unref(healthStatus)[integ.id] === "invalid_credentials" || unref(healthStatus)[integ.id] === "disconnected"
654
+ }]
655
+ }, [
656
+ createVNode("span", {
657
+ class: ["inline-block w-1.5 h-1.5 rounded-full", {
658
+ "bg-green-500": unref(healthStatus)[integ.id] === "connected",
659
+ "bg-red-500": unref(healthStatus)[integ.id] === "invalid_credentials" || unref(healthStatus)[integ.id] === "disconnected"
660
+ }]
661
+ }, null, 2),
662
+ unref(healthStatus)[integ.id] === "connected" ? (openBlock(), createBlock(Fragment, { key: 0 }, [
663
+ createTextVNode("Connected")
664
+ ], 64)) : unref(healthStatus)[integ.id] === "invalid_credentials" ? (openBlock(), createBlock(Fragment, { key: 1 }, [
665
+ createTextVNode("Invalid credentials")
666
+ ], 64)) : (openBlock(), createBlock(Fragment, { key: 2 }, [
667
+ createTextVNode("Not connected")
668
+ ], 64))
669
+ ], 2)) : createCommentVNode("", true),
670
+ integ.enabledToolsets?.length ? (openBlock(), createBlock("span", {
671
+ key: 1,
672
+ class: "text-xs text-muted"
673
+ }, toDisplayString(integ.enabledToolsets.length) + " toolset" + toDisplayString(integ.enabledToolsets.length === 1 ? "" : "s"), 1)) : createCommentVNode("", true),
674
+ integ.disabledTools?.length ? (openBlock(), createBlock("span", {
675
+ key: 2,
676
+ class: "text-xs text-muted"
677
+ }, toDisplayString(integ.disabledTools.length) + " tool" + toDisplayString(integ.disabledTools.length === 1 ? "" : "s") + " blocked ", 1)) : createCommentVNode("", true)
678
+ ])
679
+ ]),
680
+ createVNode("div", {
681
+ class: "flex items-center gap-3",
682
+ onClick: withModifiers(() => {
683
+ }, ["prevent", "stop"])
684
+ }, [
685
+ createVNode(_component_USwitch, {
686
+ "model-value": integ.enabled !== false,
687
+ "onUpdate:modelValue": ($event) => toggleEnabled(integ, $event)
688
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
689
+ ], 8, ["onClick"]),
690
+ createVNode(_component_UIcon, {
691
+ name: "i-lucide-chevron-right",
692
+ class: "text-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
693
+ })
694
+ ]),
695
+ _: 2
696
+ }, 1032, ["to"]);
697
+ }), 128))
698
+ ])),
699
+ createVNode(_component_AddIntegrationModal, {
700
+ open: unref(showAddModal),
701
+ "onUpdate:open": ($event) => isRef(showAddModal) ? showAddModal.value = $event : null,
702
+ onCreated: onIntegrationCreated
703
+ }, null, 8, ["open", "onUpdate:open"])
704
+ ];
705
+ }
706
+ }),
707
+ _: 1
708
+ }, _parent));
709
+ };
710
+ }
711
+ });
712
+ const _sfc_setup = _sfc_main.setup;
713
+ _sfc_main.setup = (props, ctx) => {
714
+ const ssrContext = useSSRContext();
715
+ (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/integrations/index.vue");
716
+ return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
717
+ };
718
+
719
+ export { _sfc_main as default };
720
+ //# sourceMappingURL=index-C8flTcKI.mjs.map