imcp 0.1.7 → 0.1.8-dev

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 (314) hide show
  1. package/dist/cli/commands/install.js +1 -106
  2. package/dist/cli/commands/install.js.map +1 -0
  3. package/dist/cli/commands/list.js +1 -90
  4. package/dist/cli/commands/list.js.map +1 -0
  5. package/dist/cli/commands/pull.js +1 -16
  6. package/dist/cli/commands/pull.js.map +1 -0
  7. package/dist/cli/commands/serve.js +1 -33
  8. package/dist/cli/commands/serve.js.map +1 -0
  9. package/dist/cli/commands/uninstall.js +1 -46
  10. package/dist/cli/commands/uninstall.js.map +1 -0
  11. package/dist/cli/index.js +1 -65
  12. package/dist/cli/index.js.map +1 -0
  13. package/dist/core/installers/clients/BaseClientInstaller.js +1 -282
  14. package/dist/core/installers/clients/BaseClientInstaller.js.map +1 -0
  15. package/dist/core/installers/clients/ClientInstaller.js +1 -163
  16. package/dist/core/installers/clients/ClientInstaller.js.map +1 -0
  17. package/dist/core/installers/clients/ClientInstallerFactory.js +1 -36
  18. package/dist/core/installers/clients/ClientInstallerFactory.js.map +1 -0
  19. package/dist/core/installers/clients/ClineInstaller.js +1 -30
  20. package/dist/core/installers/clients/ClineInstaller.js.map +1 -0
  21. package/dist/core/installers/clients/ExtensionInstaller.js +1 -151
  22. package/dist/core/installers/clients/ExtensionInstaller.js.map +1 -0
  23. package/dist/core/installers/clients/GithubCopilotInstaller.js +1 -68
  24. package/dist/core/installers/clients/GithubCopilotInstaller.js.map +1 -0
  25. package/dist/core/installers/clients/MSRooCodeInstaller.js +1 -28
  26. package/dist/core/installers/clients/MSRooCodeInstaller.js.map +1 -0
  27. package/dist/core/installers/index.js +1 -8
  28. package/dist/core/installers/index.js.map +1 -0
  29. package/dist/core/installers/requirements/BaseInstaller.js +1 -56
  30. package/dist/core/installers/requirements/BaseInstaller.js.map +1 -0
  31. package/dist/core/installers/requirements/CommandInstaller.js +1 -213
  32. package/dist/core/installers/requirements/CommandInstaller.js.map +1 -0
  33. package/dist/core/installers/requirements/GeneralInstaller.js +1 -126
  34. package/dist/core/installers/requirements/GeneralInstaller.js.map +1 -0
  35. package/dist/core/installers/requirements/InstallerFactory.js +1 -99
  36. package/dist/core/installers/requirements/InstallerFactory.js.map +1 -0
  37. package/dist/core/installers/requirements/NpmInstaller.js +1 -235
  38. package/dist/core/installers/requirements/NpmInstaller.js.map +1 -0
  39. package/dist/core/installers/requirements/NugetInstaller.js +1 -188
  40. package/dist/core/installers/requirements/NugetInstaller.js.map +1 -0
  41. package/dist/core/installers/requirements/PipInstaller.js +1 -192
  42. package/dist/core/installers/requirements/PipInstaller.js.map +1 -0
  43. package/dist/core/installers/requirements/RequirementInstaller.js +1 -2
  44. package/dist/core/installers/requirements/RequirementInstaller.js.map +1 -0
  45. package/dist/core/loaders/ConfigurationLoader.js +1 -256
  46. package/dist/core/loaders/ConfigurationLoader.js.map +1 -0
  47. package/dist/core/loaders/ConfigurationProvider.js +1 -383
  48. package/dist/core/loaders/ConfigurationProvider.js.map +1 -0
  49. package/dist/core/loaders/InstallOperationManager.js +1 -310
  50. package/dist/core/loaders/InstallOperationManager.js.map +1 -0
  51. package/dist/core/loaders/ServerSchemaLoader.js +1 -108
  52. package/dist/core/loaders/ServerSchemaLoader.js.map +1 -0
  53. package/dist/core/loaders/ServerSchemaProvider.js +1 -89
  54. package/dist/core/loaders/ServerSchemaProvider.js.map +1 -0
  55. package/dist/core/loaders/SystemSettingsManager.js +1 -256
  56. package/dist/core/loaders/SystemSettingsManager.js.map +1 -0
  57. package/dist/core/metadatas/constants.js +1 -100
  58. package/dist/core/metadatas/constants.js.map +1 -0
  59. package/dist/core/metadatas/recordingConstants.js +1 -46
  60. package/dist/core/metadatas/recordingConstants.js.map +1 -0
  61. package/dist/core/metadatas/types.js +1 -15
  62. package/dist/core/metadatas/types.js.map +1 -0
  63. package/dist/core/onboard/FeedOnboardService.js +1 -422
  64. package/dist/core/onboard/FeedOnboardService.js.map +1 -0
  65. package/dist/core/onboard/OnboardProcessor.js +1 -333
  66. package/dist/core/onboard/OnboardProcessor.js.map +1 -0
  67. package/dist/core/onboard/OnboardStatus.js +1 -9
  68. package/dist/core/onboard/OnboardStatus.js.map +1 -0
  69. package/dist/core/onboard/OnboardStatusManager.js +1 -360
  70. package/dist/core/onboard/OnboardStatusManager.js.map +1 -0
  71. package/dist/core/validators/FeedValidator.js +1 -133
  72. package/dist/core/validators/FeedValidator.js.map +1 -0
  73. package/dist/core/validators/IServerValidator.js +1 -1
  74. package/dist/core/validators/IServerValidator.js.map +1 -0
  75. package/dist/core/validators/SSEServerValidator.js +1 -38
  76. package/dist/core/validators/SSEServerValidator.js.map +1 -0
  77. package/dist/core/validators/ServerValidatorFactory.js +1 -44
  78. package/dist/core/validators/ServerValidatorFactory.js.map +1 -0
  79. package/dist/core/validators/StdioServerValidator.js +1 -281
  80. package/dist/core/validators/StdioServerValidator.js.map +1 -0
  81. package/dist/index.js +1 -18
  82. package/dist/index.js.map +1 -0
  83. package/dist/services/InstallationService.js +1 -81
  84. package/dist/services/InstallationService.js.map +1 -0
  85. package/dist/services/MCPManager.js +1 -197
  86. package/dist/services/MCPManager.js.map +1 -0
  87. package/dist/services/RequirementService.js +1 -548
  88. package/dist/services/RequirementService.js.map +1 -0
  89. package/dist/services/ServerService.js +1 -127
  90. package/dist/services/ServerService.js.map +1 -0
  91. package/dist/services/TelemetryService.js +1 -53
  92. package/dist/services/TelemetryService.js.map +1 -0
  93. package/dist/utils/UpdateCheckTracker.js +1 -79
  94. package/dist/utils/UpdateCheckTracker.js.map +1 -0
  95. package/dist/utils/adoUtils.js +1 -254
  96. package/dist/utils/adoUtils.js.map +1 -0
  97. package/dist/utils/clientUtils.js +1 -65
  98. package/dist/utils/clientUtils.js.map +1 -0
  99. package/dist/utils/feedUtils.js +1 -28
  100. package/dist/utils/feedUtils.js.map +1 -0
  101. package/dist/utils/githubAuth.js +1 -177
  102. package/dist/utils/githubAuth.js.map +1 -0
  103. package/dist/utils/githubUtils.js +1 -125
  104. package/dist/utils/githubUtils.js.map +1 -0
  105. package/dist/utils/logger.js +1 -176
  106. package/dist/utils/logger.js.map +1 -0
  107. package/dist/utils/macroExpressionUtils.js +1 -93
  108. package/dist/utils/macroExpressionUtils.js.map +1 -0
  109. package/dist/utils/osUtils.js +1 -664
  110. package/dist/utils/osUtils.js.map +1 -0
  111. package/dist/utils/versionUtils.js +1 -101
  112. package/dist/utils/versionUtils.js.map +1 -0
  113. package/dist/web/contract/serverContract.js +1 -1
  114. package/dist/web/contract/serverContract.js.map +1 -0
  115. package/dist/web/public/js/api.js +2 -132
  116. package/dist/web/public/js/api.js.map +1 -0
  117. package/dist/web/public/js/detailsWidget.js +2 -264
  118. package/dist/web/public/js/detailsWidget.js.map +1 -0
  119. package/dist/web/public/js/flights/flights.js +2 -127
  120. package/dist/web/public/js/flights/flights.js.map +1 -0
  121. package/dist/web/public/js/modal/index.js +2 -52
  122. package/dist/web/public/js/modal/index.js.map +1 -0
  123. package/dist/web/public/js/modal/installModal.js +2 -162
  124. package/dist/web/public/js/modal/installModal.js.map +1 -0
  125. package/dist/web/public/js/modal/installation.js +2 -266
  126. package/dist/web/public/js/modal/installation.js.map +1 -0
  127. package/dist/web/public/js/modal/loadingModal.js +2 -182
  128. package/dist/web/public/js/modal/loadingModal.js.map +1 -0
  129. package/dist/web/public/js/modal/modalSetup.js +2 -595
  130. package/dist/web/public/js/modal/modalSetup.js.map +1 -0
  131. package/dist/web/public/js/modal/modalUtils.js +2 -37
  132. package/dist/web/public/js/modal/modalUtils.js.map +1 -0
  133. package/dist/web/public/js/modal/versionUtils.js +2 -20
  134. package/dist/web/public/js/modal/versionUtils.js.map +1 -0
  135. package/dist/web/public/js/modal.js +2 -42
  136. package/dist/web/public/js/modal.js.map +1 -0
  137. package/dist/web/public/js/notifications.js +2 -137
  138. package/dist/web/public/js/notifications.js.map +1 -0
  139. package/dist/web/public/js/onboard/formProcessor.js +2 -1037
  140. package/dist/web/public/js/onboard/formProcessor.js.map +1 -0
  141. package/dist/web/public/js/onboard/index.js +2 -374
  142. package/dist/web/public/js/onboard/index.js.map +1 -0
  143. package/dist/web/public/js/onboard/publishHandler.js +2 -172
  144. package/dist/web/public/js/onboard/publishHandler.js.map +1 -0
  145. package/dist/web/public/js/onboard/state.js +2 -76
  146. package/dist/web/public/js/onboard/state.js.map +1 -0
  147. package/dist/web/public/js/onboard/templates.js +2 -342
  148. package/dist/web/public/js/onboard/templates.js.map +1 -0
  149. package/dist/web/public/js/onboard/uiHandlers.js +2 -1076
  150. package/dist/web/public/js/onboard/uiHandlers.js.map +1 -0
  151. package/dist/web/public/js/onboard/validationHandlers.js +2 -493
  152. package/dist/web/public/js/onboard/validationHandlers.js.map +1 -0
  153. package/dist/web/public/js/serverCategoryDetails.js +2 -364
  154. package/dist/web/public/js/serverCategoryDetails.js.map +1 -0
  155. package/dist/web/public/js/serverCategoryList.js +2 -241
  156. package/dist/web/public/js/serverCategoryList.js.map +1 -0
  157. package/dist/web/public/js/settings.js +2 -314
  158. package/dist/web/public/js/settings.js.map +1 -0
  159. package/dist/web/server.js +1 -404
  160. package/dist/web/server.js.map +1 -0
  161. package/package.json +8 -2
  162. package/.github/ISSUE_TEMPLATE/JitAccess.yml +0 -28
  163. package/.github/acl/access.yml +0 -20
  164. package/.github/compliance/inventory.yml +0 -5
  165. package/.github/policies/jit.yml +0 -19
  166. package/.github/workflows/build.yml +0 -28
  167. package/.roo/rules-code/rules.md +0 -88
  168. package/dist/cli/commands/start.d.ts +0 -2
  169. package/dist/cli/commands/start.js +0 -32
  170. package/dist/cli/commands/sync.d.ts +0 -2
  171. package/dist/cli/commands/sync.js +0 -17
  172. package/dist/core/ConfigurationLoader.d.ts +0 -32
  173. package/dist/core/ConfigurationLoader.js +0 -236
  174. package/dist/core/ConfigurationProvider.d.ts +0 -35
  175. package/dist/core/ConfigurationProvider.js +0 -375
  176. package/dist/core/InstallationService.d.ts +0 -50
  177. package/dist/core/InstallationService.js +0 -350
  178. package/dist/core/MCPManager.d.ts +0 -28
  179. package/dist/core/MCPManager.js +0 -188
  180. package/dist/core/RequirementService.d.ts +0 -40
  181. package/dist/core/RequirementService.js +0 -110
  182. package/dist/core/ServerSchemaLoader.d.ts +0 -11
  183. package/dist/core/ServerSchemaLoader.js +0 -43
  184. package/dist/core/ServerSchemaProvider.d.ts +0 -17
  185. package/dist/core/ServerSchemaProvider.js +0 -120
  186. package/dist/core/constants.d.ts +0 -47
  187. package/dist/core/constants.js +0 -94
  188. package/dist/core/installers/BaseInstaller.d.ts +0 -74
  189. package/dist/core/installers/BaseInstaller.js +0 -253
  190. package/dist/core/installers/ClientInstaller.d.ts +0 -23
  191. package/dist/core/installers/ClientInstaller.js +0 -564
  192. package/dist/core/installers/CommandInstaller.d.ts +0 -37
  193. package/dist/core/installers/CommandInstaller.js +0 -173
  194. package/dist/core/installers/GeneralInstaller.d.ts +0 -33
  195. package/dist/core/installers/GeneralInstaller.js +0 -85
  196. package/dist/core/installers/InstallerFactory.d.ts +0 -54
  197. package/dist/core/installers/InstallerFactory.js +0 -97
  198. package/dist/core/installers/NpmInstaller.d.ts +0 -26
  199. package/dist/core/installers/NpmInstaller.js +0 -127
  200. package/dist/core/installers/PipInstaller.d.ts +0 -28
  201. package/dist/core/installers/PipInstaller.js +0 -127
  202. package/dist/core/installers/RequirementInstaller.d.ts +0 -33
  203. package/dist/core/installers/RequirementInstaller.js +0 -3
  204. package/dist/core/types.d.ts +0 -166
  205. package/dist/core/types.js +0 -16
  206. package/dist/services/InstallRequestValidator.d.ts +0 -21
  207. package/dist/services/InstallRequestValidator.js +0 -99
  208. package/dist/web/public/js/modal/installHandler.js +0 -227
  209. package/dist/web/public/js/modal/loadingUI.js +0 -74
  210. package/dist/web/public/js/modal/messageQueue.js +0 -112
  211. package/dist/web/public/js/modal/modalUI.js +0 -214
  212. package/dist/web/public/js/modal/version.js +0 -20
  213. package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +0 -370
  214. package/docs/ONBOARDING_PAGE_DESIGN.md +0 -260
  215. package/docs/Telemetry.md +0 -136
  216. package/memory-bank/activeContext.md +0 -26
  217. package/memory-bank/decisionLog.md +0 -91
  218. package/memory-bank/productContext.md +0 -41
  219. package/memory-bank/progress.md +0 -35
  220. package/memory-bank/systemPatterns.md +0 -10
  221. package/src/cli/commands/install.ts +0 -139
  222. package/src/cli/commands/list.ts +0 -113
  223. package/src/cli/commands/pull.ts +0 -16
  224. package/src/cli/commands/serve.ts +0 -39
  225. package/src/cli/commands/uninstall.ts +0 -64
  226. package/src/cli/index.ts +0 -82
  227. package/src/core/installers/clients/BaseClientInstaller.ts +0 -341
  228. package/src/core/installers/clients/ClientInstaller.ts +0 -222
  229. package/src/core/installers/clients/ClientInstallerFactory.ts +0 -43
  230. package/src/core/installers/clients/ClineInstaller.ts +0 -35
  231. package/src/core/installers/clients/ExtensionInstaller.ts +0 -165
  232. package/src/core/installers/clients/GithubCopilotInstaller.ts +0 -79
  233. package/src/core/installers/clients/MSRooCodeInstaller.ts +0 -32
  234. package/src/core/installers/index.ts +0 -11
  235. package/src/core/installers/requirements/BaseInstaller.ts +0 -85
  236. package/src/core/installers/requirements/CommandInstaller.ts +0 -231
  237. package/src/core/installers/requirements/GeneralInstaller.ts +0 -133
  238. package/src/core/installers/requirements/InstallerFactory.ts +0 -114
  239. package/src/core/installers/requirements/NpmInstaller.ts +0 -271
  240. package/src/core/installers/requirements/NugetInstaller.ts +0 -203
  241. package/src/core/installers/requirements/PipInstaller.ts +0 -207
  242. package/src/core/installers/requirements/RequirementInstaller.ts +0 -42
  243. package/src/core/loaders/ConfigurationLoader.ts +0 -298
  244. package/src/core/loaders/ConfigurationProvider.ts +0 -462
  245. package/src/core/loaders/InstallOperationManager.ts +0 -367
  246. package/src/core/loaders/ServerSchemaLoader.ts +0 -117
  247. package/src/core/loaders/ServerSchemaProvider.ts +0 -99
  248. package/src/core/loaders/SystemSettingsManager.ts +0 -278
  249. package/src/core/metadatas/constants.ts +0 -122
  250. package/src/core/metadatas/recordingConstants.ts +0 -65
  251. package/src/core/metadatas/types.ts +0 -202
  252. package/src/core/onboard/FeedOnboardService.ts +0 -501
  253. package/src/core/onboard/OnboardProcessor.ts +0 -356
  254. package/src/core/onboard/OnboardStatus.ts +0 -60
  255. package/src/core/onboard/OnboardStatusManager.ts +0 -416
  256. package/src/core/validators/FeedValidator.ts +0 -135
  257. package/src/core/validators/IServerValidator.ts +0 -21
  258. package/src/core/validators/SSEServerValidator.ts +0 -43
  259. package/src/core/validators/ServerValidatorFactory.ts +0 -51
  260. package/src/core/validators/StdioServerValidator.ts +0 -313
  261. package/src/index.ts +0 -44
  262. package/src/services/InstallationService.ts +0 -102
  263. package/src/services/MCPManager.ts +0 -249
  264. package/src/services/RequirementService.ts +0 -627
  265. package/src/services/ServerService.ts +0 -161
  266. package/src/services/TelemetryService.ts +0 -59
  267. package/src/utils/UpdateCheckTracker.ts +0 -86
  268. package/src/utils/adoUtils.ts +0 -293
  269. package/src/utils/clientUtils.ts +0 -72
  270. package/src/utils/feedUtils.ts +0 -31
  271. package/src/utils/githubAuth.ts +0 -212
  272. package/src/utils/githubUtils.ts +0 -164
  273. package/src/utils/logger.ts +0 -195
  274. package/src/utils/macroExpressionUtils.ts +0 -104
  275. package/src/utils/osUtils.ts +0 -700
  276. package/src/utils/versionUtils.ts +0 -114
  277. package/src/web/contract/serverContract.ts +0 -74
  278. package/src/web/public/css/detailsWidget.css +0 -235
  279. package/src/web/public/css/modal.css +0 -757
  280. package/src/web/public/css/notifications.css +0 -101
  281. package/src/web/public/css/onboard.css +0 -107
  282. package/src/web/public/css/serverCategoryList.css +0 -120
  283. package/src/web/public/css/serverDetails.css +0 -139
  284. package/src/web/public/index.html +0 -359
  285. package/src/web/public/js/api.js +0 -132
  286. package/src/web/public/js/detailsWidget.js +0 -264
  287. package/src/web/public/js/flights/flights.js +0 -127
  288. package/src/web/public/js/modal/index.js +0 -52
  289. package/src/web/public/js/modal/installModal.js +0 -162
  290. package/src/web/public/js/modal/installation.js +0 -266
  291. package/src/web/public/js/modal/loadingModal.js +0 -182
  292. package/src/web/public/js/modal/modalSetup.js +0 -595
  293. package/src/web/public/js/modal/modalUtils.js +0 -37
  294. package/src/web/public/js/modal/versionUtils.js +0 -20
  295. package/src/web/public/js/modal.js +0 -42
  296. package/src/web/public/js/notifications.js +0 -137
  297. package/src/web/public/js/onboard/formProcessor.js +0 -1037
  298. package/src/web/public/js/onboard/index.js +0 -374
  299. package/src/web/public/js/onboard/publishHandler.js +0 -172
  300. package/src/web/public/js/onboard/state.js +0 -76
  301. package/src/web/public/js/onboard/templates.js +0 -342
  302. package/src/web/public/js/onboard/uiHandlers.js +0 -1076
  303. package/src/web/public/js/onboard/validationHandlers.js +0 -493
  304. package/src/web/public/js/serverCategoryDetails.js +0 -364
  305. package/src/web/public/js/serverCategoryList.js +0 -241
  306. package/src/web/public/js/settings.js +0 -314
  307. package/src/web/public/modal.html +0 -84
  308. package/src/web/public/onboard.html +0 -296
  309. package/src/web/public/settings.html +0 -135
  310. package/src/web/public/styles.css +0 -277
  311. package/src/web/server.ts +0 -478
  312. package/tsconfig.json +0 -18
  313. package/wiki/Installation.md +0 -3
  314. package/wiki/Publish.md +0 -3
@@ -1,493 +0,0 @@
1
- // src/web/public/js/onboard/validationHandlers.js
2
- import { showToast } from '../notifications.js';
3
- import { getFormData } from './formProcessor.js';
4
- import { toggleSectionContent } from './uiHandlers.js'; // Assuming this is correctly in uiHandlers.js and exported
5
-
6
- /**
7
- * Shows validation message under an input field.
8
- * @param {HTMLElement} element - The input element to show validation message for.
9
- * @param {string} message - The validation message to display.
10
- * @param {boolean} isError - Whether this is an error message (true) or success message (false).
11
- */
12
- export function showValidationMessage(element, message, isError = true) {
13
- // Remove any existing validation message
14
- const existingMessage = element.nextElementSibling;
15
- if (existingMessage && existingMessage.classList.contains('validation-message')) {
16
- existingMessage.remove();
17
- }
18
-
19
- // Create new validation message element
20
- const messageDiv = document.createElement('div');
21
- messageDiv.className = `validation-message text-xs mt-1 ${isError ? 'text-red-500' : 'text-green-500'}`;
22
- messageDiv.textContent = message;
23
-
24
- // Insert the message after the input element
25
- element.insertAdjacentElement('afterend', messageDiv);
26
-
27
- // Add visual feedback to the input field
28
- if (isError) {
29
- element.classList.add('border-red-500');
30
- element.classList.remove('border-green-500');
31
- } else {
32
- element.classList.add('border-green-500');
33
- element.classList.remove('border-red-500');
34
- }
35
- }
36
-
37
- /**
38
- * Common form field validation used by both validate and publish handlers
39
- * @param {HTMLFormElement} form - The form to validate
40
- * @param {string} activeTab - The active tab ('create-category' or 'create-server')
41
- * @returns {{isValid: boolean, errors: string[]}} Validation result with error messages
42
- */
43
- export function validateFormFields(form, activeTab) {
44
- // Clear any existing validation messages
45
- form.querySelectorAll('.validation-message').forEach(el => el.remove());
46
-
47
- let hasErrors = false;
48
- const errors = [];
49
-
50
- // Check for empty required fields and show validation messages
51
- const emptyRequiredFields = Array.from(form.querySelectorAll('[required]'));
52
- emptyRequiredFields.forEach(field => {
53
- if (!field.value.trim()) {
54
- showValidationMessage(field, 'This field is required', true);
55
- hasErrors = true;
56
- errors.push(`${field.name || 'Field'} is required`);
57
- }
58
- });
59
-
60
- // Check category name format if this is the create category tab
61
- if (activeTab === 'create-category') {
62
- const nameInput = form.querySelector('input[name="name"]');
63
- if (nameInput && nameInput.value.trim()) {
64
- if (!/^[a-zA-Z0-9-_]+$/.test(nameInput.value.trim())) {
65
- showValidationMessage(nameInput, 'Only alphanumeric characters, hyphens, and underscores allowed', true);
66
- hasErrors = true;
67
- errors.push('Category name must only contain alphanumeric characters, hyphens, and underscores');
68
- }
69
- }
70
- }
71
-
72
- // Check for other validation errors
73
- const envNameFields = form.querySelectorAll('input[name$=".env\\[\\].name"]');
74
- envNameFields.forEach(field => {
75
- const value = field.value.trim();
76
- if (value && !/^[A-Z_][A-Z0-9_]*$/.test(value)) {
77
- showValidationMessage(field, 'Must be uppercase with only letters, numbers, and underscores', true);
78
- hasErrors = true;
79
- errors.push('Environment variable names must be uppercase with only letters, numbers, and underscores');
80
- }
81
- });
82
-
83
- const urlFields = form.querySelectorAll('input[name$=".url"]');
84
- urlFields.forEach(field => {
85
- const value = field.value.trim();
86
- if (value) {
87
- try {
88
- new URL(value);
89
- } catch (e) {
90
- showValidationMessage(field, 'Invalid URL format', true);
91
- hasErrors = true;
92
- errors.push('Invalid URL format');
93
- }
94
- }
95
- });
96
-
97
- return {
98
- isValid: !hasErrors,
99
- errors
100
- };
101
- }
102
-
103
- const POLLING_INTERVAL = 3000; // 3 seconds
104
- let pollingIntervalId = null;
105
-
106
- /**
107
- * Updates the operation status display.
108
- * @param {object} data - The data object from the API response.
109
- * @param {HTMLElement} contentElement - The HTML element to update.
110
- */
111
- export function updateOperationDisplay(data, contentElement) { // Renamed from updateValidationDisplay
112
- const { status, message, validationStatus, prInfo, errorMessage: operationErrorMessage, operationType, steps } = data; // Added steps
113
- const upperStatus = typeof status === 'string' ? status.toUpperCase() : ''; // Overall status
114
- const isInProgressOverall = upperStatus === 'PENDING' || upperStatus === 'VALIDATING' || upperStatus === 'PRCREATING' || upperStatus === 'IN_PROGRESS' || upperStatus === 'PUBLISHING';
115
-
116
- let htmlContent = `<p><strong>Overall Status:</strong> <span class="${upperStatus === 'COMPLETED' || upperStatus === 'SUCCEEDED' ? 'text-green-600' : (upperStatus === 'FAILED' ? 'text-red-600' : 'text-yellow-600')}">${status} ${isInProgressOverall ? "<i class='bx bx-loader-alt bx-spin ml-2'></i>" : ""}</span></p>`;
117
- if (operationType) htmlContent += `<p><strong>Operation Type:</strong> ${operationType}</p>`;
118
- // Show message if provided, especially useful for direct success/failure from API.
119
- if (message) htmlContent += `<p><strong>Message:</strong> ${message}</p>`;
120
- if (operationErrorMessage) htmlContent += `<p class="text-red-500"><strong>Overall Error:</strong> ${operationErrorMessage}</p>`;
121
-
122
- // Display Steps
123
- if (Array.isArray(steps) && steps.length > 0) {
124
- const progressListId = `progress-steps-list-${contentElement.id}`; // Unique ID for the steps list
125
- // Ensure the toggle icon reflects the initial state (expanded, so 'bx-chevron-up')
126
- // The UL itself won't have 'hidden' class initially.
127
- htmlContent += `
128
- <div class="progress-section-container mt-4">
129
- <h4 class="font-semibold mb-2 text-gray-700 cursor-pointer flex items-center progress-section-toggle" data-target-id="${progressListId}">
130
- Progress
131
- <i class='bx bx-chevron-up toggle-icon-progress ml-2 text-gray-500'></i>
132
- </h4>
133
- <ul id="${progressListId}" class="list-none space-y-2 border-l-2 border-blue-500 pl-4 py-2">`; // Added py-2 for padding
134
- steps.forEach((step, index) => {
135
- const stepTimestamp = new Date(step.timestamp).toLocaleString();
136
- let stepStatusIcon = '';
137
- let stepTextColor = 'text-gray-700'; // Default text color
138
-
139
- const isLastStep = index === steps.length - 1;
140
-
141
- if (step.errorMessage || step.status === 'failed') {
142
- stepStatusIcon = "<i class='bx bx-x-circle text-red-500 mr-2'></i>";
143
- stepTextColor = 'text-red-600';
144
- } else if (isLastStep && isInProgressOverall) {
145
- // Current active step if overall process is still running
146
- stepStatusIcon = "<i class='bx bx-loader-alt bx-spin text-blue-500 mr-2'></i>";
147
- stepTextColor = 'text-blue-700';
148
- } else {
149
- // Completed, non-failed step
150
- stepStatusIcon = "<i class='bx bx-check-circle text-green-500 mr-2'></i>";
151
- stepTextColor = 'text-gray-700'; // Keep default gray for completed steps, icon is green
152
- }
153
-
154
- htmlContent += `<li class="text-sm ${stepTextColor}">`;
155
- htmlContent += `${stepStatusIcon}<strong>${step.stepName}</strong>`;
156
- if (step.serverName) htmlContent += ` (Server: ${step.serverName})`;
157
- htmlContent += `<span class="text-xs text-gray-500 ml-2">- ${stepTimestamp}</span>`;
158
- if (step.errorMessage) {
159
- htmlContent += `<p class="text-xs text-red-400 pl-6">Error: ${step.errorMessage}</p>`;
160
- }
161
- htmlContent += `</li>`;
162
- });
163
- htmlContent += '</ul>';
164
- }
165
-
166
- if (validationStatus) {
167
- htmlContent += '<h4 class="font-semibold mt-4 mb-2 text-gray-700">Detailed Validation Results:</h4>';
168
- htmlContent += '<ul class="list-disc list-inside space-y-1">';
169
- let hasDetailedItems = false;
170
- // Check for serverResults array first
171
- if (Array.isArray(validationStatus.serverResults)) {
172
- validationStatus.serverResults.forEach(serverResult => {
173
- if (serverResult && typeof serverResult.serverName === 'string' && typeof serverResult.isValid === 'boolean') {
174
- hasDetailedItems = true;
175
- const icon = serverResult.isValid ? "<i class='bx bx-check-circle text-green-500'></i>" : "<i class='bx bx-x-circle text-red-500'></i>";
176
- let serverMessage = serverResult.message ? `: ${serverResult.message}` : (serverResult.isValid ? ': Valid' : ': Invalid');
177
- htmlContent += `<li>${icon} <strong>Server "${serverResult.serverName}"</strong>${serverMessage}</li>`;
178
- }
179
- });
180
- }
181
-
182
- // Fallback for other keys in validationStatus or if serverResults is not the primary detail
183
- for (const key in validationStatus) {
184
- if (key === 'serverResults') continue; // Already processed
185
-
186
- const item = validationStatus[key];
187
- // Handle simple {isValid, message} structure directly under validationStatus
188
- if (key === 'isValid' && typeof item === 'boolean' && typeof validationStatus.message === 'string' && !hasDetailedItems) {
189
- hasDetailedItems = true;
190
- const icon = item ? "<i class='bx bx-check-circle text-green-500'></i>" : "<i class='bx bx-x-circle text-red-500'></i>";
191
- htmlContent += `<li>${icon} <strong>Overall Validation:</strong> ${validationStatus.message}</li>`;
192
- break; // Assume this is the main summary if serverResults wasn't present or detailed
193
- } else if (typeof item === 'object' && item !== null && 'isValid' in item && 'message' in item) {
194
- // Handle other named detailed items
195
- hasDetailedItems = true;
196
- const icon = item.isValid ? "<i class='bx bx-check-circle text-green-500'></i>" : "<i class='bx bx-x-circle text-red-500'></i>";
197
- htmlContent += `<li>${icon} <strong>${key.replace(/([A-Z])/g, ' $1').trim()}:</strong> ${item.message}</li>`;
198
- }
199
- }
200
-
201
- if (!hasDetailedItems && validationStatus.isValid === true && validationStatus.message) {
202
- // Catch-all for a simple success message if no other details were parsed
203
- hasDetailedItems = true;
204
- const icon = "<i class='bx bx-check-circle text-green-500'></i>";
205
- htmlContent += `<li>${icon} <strong>Overall:</strong> ${validationStatus.message}</li>`;
206
- } else if (!hasDetailedItems) {
207
- htmlContent += '<li>No detailed validation information available or format is unexpected.</li>';
208
- }
209
- htmlContent += '</ul>';
210
- }
211
-
212
- if (prInfo && prInfo.url) {
213
- htmlContent += `<p class="mt-3"><strong>PR Info:</strong> <a href="${prInfo.url}" target="_blank" class="text-blue-600 hover:underline">${prInfo.url}</a></p>`;
214
- }
215
- contentElement.innerHTML = htmlContent;
216
- // After updating content, ensure the toggle listener is active for the new/updated progress section
217
- if (Array.isArray(steps) && steps.length > 0) {
218
- ensureProgressToggleListener(contentElement);
219
- }
220
- }
221
-
222
- /**
223
- * Ensures that a click listener is attached to the statusContentElement
224
- * to handle toggling the visibility of the progress steps list.
225
- * This listener is attached only once.
226
- * @param {HTMLElement} statusContentElement - The parent element where progress is displayed.
227
- */
228
- export function ensureProgressToggleListener(statusContentElement) {
229
- if (statusContentElement && !statusContentElement.dataset.progressToggleListenerAttached) {
230
- statusContentElement.addEventListener('click', (event) => {
231
- const toggleHeader = event.target.closest('.progress-section-toggle');
232
- if (toggleHeader) {
233
- const targetId = toggleHeader.dataset.targetId;
234
- const iconElement = toggleHeader.querySelector('.toggle-icon-progress');
235
- // Assuming toggleSectionContent is imported from uiHandlers.js and is in scope
236
- if (targetId && iconElement && typeof toggleSectionContent === 'function') {
237
- toggleSectionContent(targetId, iconElement);
238
- }
239
- }
240
- });
241
- statusContentElement.dataset.progressToggleListenerAttached = 'true';
242
- }
243
- }
244
-
245
-
246
- /**
247
- * Polls the server for operation status.
248
- * @param {string} categoryName - The name of the category.
249
- * @param {string} contentId - The ID of the status content element.
250
- * @param {string} validateBtnId - The ID of the validate button.
251
- * @param {string} publishBtnId - The ID of the publish button.
252
- * @param {string} operationInitiator - 'validate' or 'publish' to restore correct button text.
253
- * @param {string} operationType - The type of operation to poll for (e.g., 'VALIDATION_ONLY', 'FULL_ONBOARDING').
254
- * @returns {Promise<boolean>} - Promise resolving to true if polling should continue, false otherwise.
255
- */
256
- export async function pollOperationStatus(categoryName, contentId, validateBtnId, publishBtnId, operationInitiator, operationType) {
257
- const statusContentElement = document.getElementById(contentId);
258
- ensureProgressToggleListener(statusContentElement); // Ensure listener is active during polling updates
259
-
260
- const validateButton = document.getElementById(validateBtnId);
261
- const publishButton = document.getElementById(publishBtnId);
262
-
263
- // Helper function to update button states based on operation status
264
- const updateButtonStates = (isCompleted = false) => {
265
- if (validateButton && publishButton) {
266
- if (isCompleted) {
267
- // On completion, enable both buttons and restore their original state
268
- validateButton.disabled = false;
269
- validateButton.innerHTML = "<i class='bx bx-check-shield mr-2'></i>Validate";
270
- validateButton.classList.remove('opacity-50');
271
- publishButton.disabled = false;
272
- publishButton.innerHTML = "<i class='bx bx-cloud-upload mr-2'></i>Publish";
273
- publishButton.classList.remove('opacity-50');
274
- } else {
275
- // During operation, handle buttons based on which operation is running
276
- if (operationInitiator === 'validate') {
277
- validateButton.disabled = true;
278
- validateButton.innerHTML = "<i class='bx bx-loader-alt bx-spin mr-2'></i>Validating...";
279
- publishButton.disabled = true;
280
- publishButton.innerHTML = "<i class='bx bx-cloud-upload mr-2'></i>Publish";
281
- publishButton.classList.add('opacity-50');
282
- } else if (operationInitiator === 'publish') {
283
- publishButton.disabled = true;
284
- publishButton.innerHTML = "<i class='bx bx-loader-alt bx-spin mr-2'></i>Publishing...";
285
- validateButton.disabled = true;
286
- validateButton.innerHTML = "<i class='bx bx-check-shield mr-2'></i>Validate";
287
- validateButton.classList.add('opacity-50');
288
- }
289
- }
290
- }
291
- };
292
-
293
- try {
294
- // Add operationType as a query parameter
295
- const response = await fetch(`/api/categories/${categoryName}/onboard/status?operationType=${encodeURIComponent(operationType)}`);
296
- const result = await response.json();
297
-
298
- if (result.success && result.data) {
299
- updateOperationDisplay(result.data, statusContentElement);
300
-
301
- const currentStatus = result.data.status ? String(result.data.status).toUpperCase() : ''; // Ensure uppercase for comparison
302
- // Use string literals for status comparison, include 'succeeded'
303
- if (currentStatus === 'COMPLETED' || currentStatus === 'FAILED' || currentStatus === 'SUCCEEDED') {
304
- updateButtonStates(true);
305
- return false; // Stop polling
306
- } else {
307
- // Operation is still in progress
308
- updateButtonStates(false);
309
- return true; // Continue polling
310
- }
311
- } else {
312
- statusContentElement.innerHTML = `<p class="text-red-500">Error polling status: ${result.error || 'Unknown error'}</p>`;
313
- updateButtonStates(true);
314
- return false; // Stop polling
315
- }
316
- } catch (error) {
317
- console.error('Error polling operation status:', error);
318
- statusContentElement.innerHTML = `<p class="text-red-500">An error occurred while polling status. Please check the console.</p>`;
319
- updateButtonStates(true);
320
- return false; // Stop polling
321
- }
322
- }
323
-
324
- /**
325
- * Handles the validation process for the onboarding form.
326
- * It initiates validation, displays status, and polls for updates.
327
- * @param {Event} event - The click event.
328
- * @param {string} activeTab - Identifier for the active tab ('create-category' or 'create-server').
329
- * @param {object|null} currentSelectedCategoryData - Data for the currently selected category if activeTab is 'create-server'.
330
- */
331
- export async function handleValidation(event, activeTab, currentSelectedCategoryData = null) {
332
- const { panelId, contentId, formId, validateButtonId, publishButtonId } = getElementIdsByTab(activeTab);
333
-
334
- const statusContentElement = document.getElementById(contentId);
335
- ensureProgressToggleListener(statusContentElement); // Ensure listener is active for initial display
336
-
337
- const onboardForm = document.getElementById(formId);
338
- const validateButton = document.getElementById(validateButtonId);
339
- const publishButton = document.getElementById(publishButtonId);
340
-
341
- if (!onboardForm || !statusContentElement || !validateButton || !publishButton) {
342
- console.error('Required form or panel elements not found for validation.');
343
- showToast('Required form or panel elements not found for validation.', 'error');
344
- return;
345
- }
346
-
347
- const validationResult = validateFormFields(onboardForm, activeTab);
348
- if (!validationResult.isValid) {
349
- showToast('Please fix all validation errors before proceeding.', 'error');
350
- validateButton.disabled = false;
351
- validateButton.innerHTML = "<i class='bx bx-check-shield mr-2'></i>Validate";
352
- return;
353
- }
354
-
355
- // Additional validation for new category form
356
- if (activeTab === 'create-category') {
357
- const formData = getFormData(onboardForm, false);
358
- if (!formData.mcpServers || formData.mcpServers.length === 0) {
359
- showToast('At least one MCP server must be configured for a new category.', 'error');
360
- return;
361
- }
362
- }
363
-
364
- // Disable buttons and show appropriate states
365
- validateButton.disabled = true;
366
- validateButton.innerHTML = "<i class='bx bx-loader-alt bx-spin mr-2'></i>Validating...";
367
- publishButton.disabled = true;
368
- publishButton.innerHTML = "<i class='bx bx-cloud-upload mr-2'></i>Publish";
369
- publishButton.classList.add('opacity-50'); // Add gray state to inactive button
370
-
371
- if (pollingIntervalId) {
372
- clearInterval(pollingIntervalId); // Clear any existing polling
373
- pollingIntervalId = null;
374
- }
375
-
376
- const forExistingCategoryTab = activeTab === 'create-server';
377
- const newServersData = getFormData(onboardForm, forExistingCategoryTab, currentSelectedCategoryData);
378
- let finalFeedConfiguration;
379
-
380
- if (forExistingCategoryTab && currentSelectedCategoryData) {
381
- finalFeedConfiguration = JSON.parse(JSON.stringify(currentSelectedCategoryData)); // Deep clone
382
-
383
- // Replace MCP Servers and Requirements with the current state from the form (newServersData).
384
- // newServersData, generated by getFormData, already contains the correct, complete list
385
- // of servers (including original, adhoc, and newly added ones) and their derived global requirements.
386
- finalFeedConfiguration.mcpServers = newServersData.mcpServers || [];
387
- finalFeedConfiguration.requirements = newServersData.requirements || [];
388
- } else {
389
- finalFeedConfiguration = newServersData;
390
- }
391
-
392
- statusContentElement.innerHTML = '<p class="text-gray-500">Initiating validation...</p>';
393
- ensureStatusPanelVisible(panelId, contentId);
394
-
395
-
396
- try {
397
- const response = await fetch('/api/categories/onboard/validate', {
398
- method: 'POST',
399
- headers: {
400
- 'Content-Type': 'application/json',
401
- },
402
- body: JSON.stringify({
403
- categoryData: finalFeedConfiguration,
404
- forExistingCategory: forExistingCategoryTab
405
- }),
406
- });
407
-
408
- const result = await response.json();
409
-
410
- if (result.success && result.data) {
411
- updateOperationDisplay(result.data, statusContentElement);
412
- // The onboardingId from the response is the combined ID (categoryName_operationType).
413
- // We need the categoryName for polling, which we already have as a parameter.
414
- // The operationType is also passed to pollOperationStatus.
415
- const categoryNameForPolling = finalFeedConfiguration.name; // Use the original category name
416
- const operationTypeForPolling = 'VALIDATION_ONLY'; // Validation always initiates 'VALIDATION_ONLY'
417
- const initialStatus = result.data.status;
418
-
419
- // Use string literals for status comparison, include 'succeeded'
420
- const upperInitialStatus = typeof initialStatus === 'string' ? initialStatus.toUpperCase() : '';
421
- if (categoryNameForPolling && upperInitialStatus !== 'COMPLETED' && upperInitialStatus !== 'FAILED' && upperInitialStatus !== 'SUCCEEDED') {
422
- pollingIntervalId = setInterval(async () => {
423
- const shouldContinue = await pollOperationStatus(categoryNameForPolling, contentId, validateButtonId, publishButtonId, 'validate', operationTypeForPolling);
424
- if (!shouldContinue) {
425
- clearInterval(pollingIntervalId);
426
- pollingIntervalId = null;
427
- }
428
- }, POLLING_INTERVAL);
429
- } else {
430
- validateButton.disabled = false;
431
- validateButton.innerHTML = "<i class='bx bx-check-shield mr-2'></i>Validate";
432
- publishButton.disabled = false;
433
- publishButton.classList.remove('opacity-50'); // Remove gray state
434
- }
435
- } else {
436
- statusContentElement.innerHTML = `<p class="text-red-500">Validation request failed: ${result.error || 'Unknown error'}</p>`;
437
- validateButton.disabled = false;
438
- validateButton.innerHTML = "<i class='bx bx-check-shield mr-2'></i>Validate";
439
- publishButton.disabled = false;
440
- publishButton.classList.remove('opacity-50'); // Remove gray state on error
441
- }
442
- } catch (error) {
443
- console.error('Error during validation:', error);
444
- statusContentElement.innerHTML = `<p class="text-red-500">An error occurred while initiating validation. Please check the console.</p>`;
445
- validateButton.disabled = false;
446
- validateButton.innerHTML = "<i class='bx bx-check-shield mr-2'></i>Validate";
447
- publishButton.disabled = false;
448
- publishButton.classList.remove('opacity-50'); // Remove gray state on error
449
- }
450
- }
451
-
452
- /**
453
- * Gets common element IDs based on the active tab.
454
- * @param {string} activeTab - Identifier for the active tab.
455
- * @returns {object} Object containing element IDs.
456
- */
457
- export function getElementIdsByTab(activeTab) {
458
- const isCreateCategoryTab = activeTab === 'create-category';
459
- return {
460
- panelId: isCreateCategoryTab ? 'validationStatusPanelNewCategory' : 'validationStatusPanelExistingCategory',
461
- contentId: isCreateCategoryTab ? 'validationStatusContentNewCategory' : 'validationStatusContentExistingCategoryTab',
462
- formId: isCreateCategoryTab ? 'onboardForm' : 'onboardServerForm',
463
- validateButtonId: isCreateCategoryTab ? 'validateButtonNewCategory' : 'validateButtonExistingCategory',
464
- publishButtonId: isCreateCategoryTab ? 'publishButtonNewCategory' : 'publishButtonExistingCategory',
465
- };
466
- }
467
-
468
- /**
469
- * Ensures the status panel is visible and expanded.
470
- * @param {string} panelId - The ID of the status panel.
471
- * @param {string} contentId - The ID of the status content area.
472
- */
473
- export function ensureStatusPanelVisible(panelId, contentId) {
474
- const statusPanel = document.getElementById(panelId);
475
- const statusContent = document.getElementById(contentId);
476
-
477
- if (!statusPanel || !statusContent) return;
478
-
479
- statusPanel.classList.remove('hidden');
480
- if (statusContent.classList.contains('hidden')) {
481
- const headerIcon = statusPanel.querySelector('.toggle-icon');
482
- if (headerIcon && typeof toggleSectionContent === 'function') {
483
- toggleSectionContent(contentId, headerIcon);
484
- } else if (headerIcon) {
485
- console.warn('toggleSectionContent function not available for status panel.');
486
- statusContent.classList.remove('hidden');
487
- headerIcon.classList.remove('bx-chevron-down');
488
- headerIcon.classList.add('bx-chevron-up');
489
- } else {
490
- statusContent.classList.remove('hidden');
491
- }
492
- }
493
- }