imcp 0.0.12 → 0.0.14

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 (81) hide show
  1. package/dist/core/ConfigurationProvider.d.ts +2 -1
  2. package/dist/core/ConfigurationProvider.js +20 -24
  3. package/dist/core/InstallationService.d.ts +17 -0
  4. package/dist/core/InstallationService.js +127 -61
  5. package/dist/core/MCPManager.d.ts +1 -0
  6. package/dist/core/MCPManager.js +3 -0
  7. package/dist/core/RequirementService.d.ts +4 -4
  8. package/dist/core/RequirementService.js +11 -7
  9. package/dist/core/ServerSchemaProvider.d.ts +1 -1
  10. package/dist/core/ServerSchemaProvider.js +15 -10
  11. package/dist/core/constants.d.ts +3 -0
  12. package/dist/core/constants.js +4 -1
  13. package/dist/core/installers/clients/ClientInstaller.js +58 -40
  14. package/dist/core/installers/requirements/PipInstaller.js +10 -5
  15. package/dist/core/onboard/FeedOnboardService.d.ts +35 -0
  16. package/dist/core/onboard/FeedOnboardService.js +137 -0
  17. package/dist/core/types.d.ts +6 -1
  18. package/dist/core/validators/FeedValidator.d.ts +13 -0
  19. package/dist/core/validators/FeedValidator.js +27 -0
  20. package/dist/services/ServerService.d.ts +5 -0
  21. package/dist/services/ServerService.js +15 -0
  22. package/dist/utils/githubAuth.js +0 -10
  23. package/dist/utils/githubUtils.d.ts +16 -0
  24. package/dist/utils/githubUtils.js +55 -39
  25. package/dist/web/contract/serverContract.d.ts +64 -0
  26. package/dist/web/contract/serverContract.js +2 -0
  27. package/dist/web/public/css/detailsWidget.css +157 -32
  28. package/dist/web/public/css/onboard.css +44 -0
  29. package/dist/web/public/css/serverDetails.css +35 -19
  30. package/dist/web/public/index.html +16 -10
  31. package/dist/web/public/js/detailsWidget.js +43 -40
  32. package/dist/web/public/js/modal/index.js +58 -0
  33. package/dist/web/public/js/modal/installHandler.js +227 -0
  34. package/dist/web/public/js/modal/installModal.js +163 -0
  35. package/dist/web/public/js/modal/installation.js +281 -0
  36. package/dist/web/public/js/modal/loadingModal.js +52 -0
  37. package/dist/web/public/js/modal/loadingUI.js +74 -0
  38. package/dist/web/public/js/modal/messageQueue.js +112 -0
  39. package/dist/web/public/js/modal/modalSetup.js +512 -0
  40. package/dist/web/public/js/modal/modalUI.js +214 -0
  41. package/dist/web/public/js/modal/modalUtils.js +49 -0
  42. package/dist/web/public/js/modal/version.js +20 -0
  43. package/dist/web/public/js/modal/versionUtils.js +20 -0
  44. package/dist/web/public/js/modal.js +25 -1041
  45. package/dist/web/public/js/onboard/formProcessor.js +309 -0
  46. package/dist/web/public/js/onboard/index.js +131 -0
  47. package/dist/web/public/js/onboard/state.js +32 -0
  48. package/dist/web/public/js/onboard/templates.js +375 -0
  49. package/dist/web/public/js/onboard/uiHandlers.js +196 -0
  50. package/dist/web/public/js/serverCategoryDetails.js +211 -123
  51. package/dist/web/public/onboard.html +150 -0
  52. package/dist/web/server.js +25 -0
  53. package/package.json +3 -4
  54. package/src/core/ConfigurationProvider.ts +37 -29
  55. package/src/core/InstallationService.ts +176 -62
  56. package/src/core/MCPManager.ts +4 -0
  57. package/src/core/RequirementService.ts +12 -8
  58. package/src/core/ServerSchemaLoader.ts +48 -0
  59. package/src/core/ServerSchemaProvider.ts +137 -0
  60. package/src/core/constants.ts +4 -1
  61. package/src/core/installers/clients/ClientInstaller.ts +66 -49
  62. package/src/core/installers/requirements/PipInstaller.ts +10 -5
  63. package/src/core/types.ts +6 -1
  64. package/src/services/ServerService.ts +15 -0
  65. package/src/utils/githubAuth.ts +14 -27
  66. package/src/utils/githubUtils.ts +84 -47
  67. package/src/web/public/css/detailsWidget.css +235 -0
  68. package/src/web/public/css/serverDetails.css +126 -0
  69. package/src/web/public/index.html +16 -10
  70. package/src/web/public/js/detailsWidget.js +264 -0
  71. package/src/web/public/js/modal/index.js +58 -0
  72. package/src/web/public/js/modal/installModal.js +163 -0
  73. package/src/web/public/js/modal/installation.js +281 -0
  74. package/src/web/public/js/modal/loadingModal.js +52 -0
  75. package/src/web/public/js/modal/messageQueue.js +112 -0
  76. package/src/web/public/js/modal/modalSetup.js +512 -0
  77. package/src/web/public/js/modal/modalUtils.js +49 -0
  78. package/src/web/public/js/modal/versionUtils.js +20 -0
  79. package/src/web/public/js/modal.js +25 -1041
  80. package/src/web/public/js/serverCategoryDetails.js +211 -123
  81. package/src/web/server.ts +31 -0
@@ -0,0 +1,58 @@
1
+ // Import all modal-related functionality
2
+ import { compareVersions } from './versionUtils.js';
3
+ import { delayedAppendInstallLoadingMessage } from './messageQueue.js';
4
+ import { showInstallLoadingModal, appendInstallLoadingMessage, hideInstallLoadingModal } from './loadingModal.js';
5
+ import { closeModal, setupModalOutsideClick } from './modalUtils.js';
6
+ import { handleBulkClientInstall, uninstallTools } from './installation.js';
7
+ import { showInstallModal } from './installModal.js';
8
+ import {
9
+ setupClientItems,
10
+ setupEnvironmentVariables,
11
+ setupInstallationArguments,
12
+ setupServerRequirements,
13
+ setupFormSubmitHandler
14
+ } from './modalSetup.js';
15
+
16
+ // Export all modal functionality
17
+ export {
18
+ // Version utilities
19
+ compareVersions,
20
+
21
+ // Message queue
22
+ delayedAppendInstallLoadingMessage,
23
+
24
+ // Loading modal
25
+ showInstallLoadingModal,
26
+ appendInstallLoadingMessage,
27
+ hideInstallLoadingModal,
28
+
29
+ // Modal utilities
30
+ closeModal,
31
+ setupModalOutsideClick,
32
+
33
+ // Installation
34
+ handleBulkClientInstall,
35
+ uninstallTools,
36
+
37
+ // Install modal
38
+ showInstallModal,
39
+
40
+ // Modal setup
41
+ setupClientItems,
42
+ setupEnvironmentVariables,
43
+ setupInstallationArguments,
44
+ setupServerRequirements,
45
+ setupFormSubmitHandler
46
+ };
47
+
48
+ // Initialize modal functionality
49
+ document.addEventListener('DOMContentLoaded', () => {
50
+ setupModalOutsideClick();
51
+ });
52
+
53
+ // Make certain functions available globally
54
+ window.showInstallModal = showInstallModal;
55
+ window.showInstallLoadingModal = showInstallLoadingModal;
56
+ window.appendInstallLoadingMessage = appendInstallLoadingMessage;
57
+ window.hideInstallLoadingModal = hideInstallLoadingModal;
58
+ window.uninstallTools = uninstallTools;
@@ -0,0 +1,227 @@
1
+ import { showLoadingModal, appendLoadingMessage } from './loadingUI.js';
2
+ import { compareVersions } from './version.js';
3
+
4
+ /**
5
+ * Handle bulk client installations
6
+ * @param {string} categoryName Category name
7
+ * @param {string} serverName Server name
8
+ * @param {string[]} targets Target clients
9
+ * @param {Object} options Installation options
10
+ */
11
+ export async function handleInstallation(categoryName, serverName, targets, options = {}) {
12
+ const { envVars = {}, installingMessage = "Starting installation...", serverData = null } = options;
13
+
14
+ hideInstallModal();
15
+ initializeInstallation(installingMessage, serverData, serverName, targets);
16
+
17
+ try {
18
+ await executeInstallation(categoryName, serverName, targets, options);
19
+ } catch (error) {
20
+ handleInstallationError(error);
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Handle uninstallation of tools
26
+ * @param {string} categoryName Category name
27
+ * @param {Object|Array} serverList Servers to uninstall
28
+ * @param {string[]} targets Target clients
29
+ */
30
+ export async function handleUninstallation(categoryName, serverList, targets) {
31
+ const selectedTargets = getSelectedTargets(targets);
32
+ validateTargets(selectedTargets);
33
+
34
+ try {
35
+ await executeUninstallation(categoryName, serverList, selectedTargets);
36
+ } catch (error) {
37
+ handleUninstallationError(error);
38
+ throw error;
39
+ }
40
+ }
41
+
42
+ // Private helper functions
43
+
44
+ function hideInstallModal() {
45
+ const installModal = document.getElementById('installModal');
46
+ if (installModal) {
47
+ installModal.style.display = "none";
48
+ }
49
+ }
50
+
51
+ function initializeInstallation(installingMessage, serverData, serverName, targets) {
52
+ showLoadingModal();
53
+
54
+ if (hasExistingStatus(serverData, serverName, targets)) {
55
+ const existingMessage = getExistingMessage(serverData, serverName, targets[0]);
56
+ if (existingMessage && existingMessage !== "Starting installation...") {
57
+ appendLoadingMessage(existingMessage);
58
+ }
59
+ }
60
+
61
+ appendLoadingMessage(installingMessage);
62
+ }
63
+
64
+ function hasExistingStatus(serverData, serverName, targets) {
65
+ return serverData?.data?.installationStatus?.serversStatus &&
66
+ targets?.length > 0;
67
+ }
68
+
69
+ function getExistingMessage(serverData, serverName, target) {
70
+ const serverStatuses = serverData.data.installationStatus.serversStatus;
71
+ const serverStatus = serverStatuses[serverName] || { installedStatus: {} };
72
+ return serverStatus.installedStatus?.[target]?.message;
73
+ }
74
+
75
+ async function executeInstallation(categoryName, serverName, targets, options) {
76
+ appendLoadingMessage("Installing, please wait...");
77
+
78
+ const requestBody = buildInstallRequestBody(serverName, targets, options);
79
+ const response = await fetchWithErrorHandling(
80
+ `api/categories/${categoryName}/install`,
81
+ requestBody
82
+ );
83
+
84
+ if (response.success) {
85
+ startStatusPolling(categoryName, serverName, targets, options);
86
+ }
87
+ }
88
+
89
+ function buildInstallRequestBody(serverName, targets, options) {
90
+ const { envVars = {}, args = [], pythonEnv, requirements = [] } = options;
91
+
92
+ const serverOptions = {
93
+ targetClients: targets,
94
+ env: envVars,
95
+ args: args,
96
+ settings: pythonEnv ? { pythonEnv } : undefined
97
+ };
98
+
99
+ if (requirements.length > 0) {
100
+ serverOptions.requirements = requirements;
101
+ }
102
+
103
+ return {
104
+ serverList: {
105
+ [serverName]: serverOptions
106
+ }
107
+ };
108
+ }
109
+
110
+ async function executeUninstallation(categoryName, serverList, selectedTargets) {
111
+ appendLoadingMessage('Starting uninstallation...');
112
+
113
+ const formattedServerList = formatServerList(serverList);
114
+ await fetchWithErrorHandling(
115
+ `api/categories/${categoryName}/uninstall`,
116
+ {
117
+ serverList: formattedServerList,
118
+ options: {
119
+ targets: selectedTargets,
120
+ removeData: true
121
+ }
122
+ }
123
+ );
124
+
125
+ appendLoadingMessage(`Successfully uninstalled from ${selectedTargets.join(', ')}`, true);
126
+ window.selectedClients = [];
127
+ }
128
+
129
+ function formatServerList(serverList) {
130
+ if (Array.isArray(serverList)) {
131
+ return serverList.reduce((acc, server) => {
132
+ acc[server] = { removeData: true };
133
+ return acc;
134
+ }, {});
135
+ }
136
+ return serverList;
137
+ }
138
+
139
+ async function fetchWithErrorHandling(endpoint, body) {
140
+ const response = await fetch(endpoint, {
141
+ method: 'POST',
142
+ headers: {
143
+ 'Content-Type': 'application/json',
144
+ 'Accept': 'application/json'
145
+ },
146
+ body: JSON.stringify(body)
147
+ });
148
+
149
+ if (!response.ok) {
150
+ const errorData = await response.text();
151
+ throw new Error(`Operation failed: ${errorData || response.statusText}`);
152
+ }
153
+
154
+ const result = await response.json();
155
+ if (!result.success) {
156
+ throw new Error(result.error || 'Operation failed');
157
+ }
158
+
159
+ return result;
160
+ }
161
+
162
+ function handleInstallationError(error) {
163
+ console.error('[LoadingModal] Error:', error);
164
+ appendLoadingMessage(`<span style="color:red;">Error: ${error.message}</span>`);
165
+ }
166
+
167
+ function handleUninstallationError(error) {
168
+ console.error('Error uninstalling tools:', error);
169
+ appendLoadingMessage(`Error: ${error.message}`, true);
170
+ }
171
+
172
+ function getSelectedTargets(targets) {
173
+ return window.selectedClients || (Array.isArray(targets) ? targets : [targets]);
174
+ }
175
+
176
+ function validateTargets(selectedTargets) {
177
+ if (!selectedTargets || selectedTargets.length === 0) {
178
+ throw new Error('Please select at least one client to uninstall.');
179
+ }
180
+ }
181
+
182
+ // Status polling functionality
183
+ async function startStatusPolling(categoryName, serverName, targets, options) {
184
+ const { requirements = [] } = options;
185
+ let lastMessages = {};
186
+ let lastRequirementMessages = {};
187
+ let lastRequirementErrorMessages = {};
188
+ let completionMessageSent = false;
189
+
190
+ const startTime = Date.now();
191
+ const maxTimeout = 10 * 60 * 1000; // 10 minutes
192
+
193
+ while (Date.now() - startTime < maxTimeout) {
194
+ try {
195
+ const status = await pollStatus(categoryName, serverName, targets, requirements);
196
+
197
+ if (status.isComplete) {
198
+ sendCompletionMessage(status, targets);
199
+ return;
200
+ }
201
+
202
+ updateMessages(status, lastMessages, lastRequirementMessages, lastRequirementErrorMessages);
203
+ } catch (error) {
204
+ console.error('[LoadingModal] Error polling status:', error);
205
+ }
206
+
207
+ await new Promise(resolve => setTimeout(resolve, 2000));
208
+ }
209
+
210
+ handlePollingTimeout(completionMessageSent);
211
+ }
212
+
213
+ async function pollStatus(categoryName, serverName, targets, requirements) {
214
+ const response = await fetch(`api/categories/${categoryName}`);
215
+ if (!response.ok) {
216
+ throw new Error('Failed to fetch status');
217
+ }
218
+
219
+ const data = await response.json();
220
+ return processStatusData(data, serverName, targets, requirements);
221
+ }
222
+
223
+ function processStatusData(data, serverName, targets, requirements) {
224
+ // Implementation details for processing status data
225
+ // This would include checking requirements status and target status
226
+ // Returns an object with status information
227
+ }
@@ -0,0 +1,163 @@
1
+ import { showToast, showConfirm } from '../notifications.js';
2
+ import { compareVersions } from './versionUtils.js';
3
+ import { delayedAppendInstallLoadingMessage } from './messageQueue.js';
4
+ import { showInstallLoadingModal } from './loadingModal.js';
5
+ import { setupModalOutsideClick, closeModal, setupToggleStyles } from './modalUtils.js';
6
+ import { handleBulkClientInstall, uninstallTools } from './installation.js';
7
+ import {
8
+ setupClientItems,
9
+ setupEnvironmentVariables,
10
+ setupInstallationArguments,
11
+ setupServerRequirements,
12
+ setupFormSubmitHandler
13
+ } from './modalSetup.js';
14
+
15
+ // Initialize modal functionality when DOM is loaded
16
+ document.addEventListener('DOMContentLoaded', () => {
17
+ setupModalOutsideClick();
18
+ setupToggleStyles();
19
+ });
20
+
21
+ /**
22
+ * Show install modal for MCP tools
23
+ * @param {string} categoryName - The category name
24
+ * @param {string} serverName - The server name
25
+ * @param {Function} callback - Optional callback function
26
+ */
27
+ export async function showInstallModal(categoryName, serverName, callback) {
28
+ console.log("Showing install modal for:", serverName);
29
+
30
+ // Wait for a short delay to ensure modal is loaded
31
+ await new Promise(resolve => setTimeout(resolve, 100));
32
+
33
+ const modal = document.getElementById('installModal');
34
+ if (!modal) {
35
+ console.error('Modal container not found');
36
+ return;
37
+ }
38
+
39
+ const title = modal.querySelector('#modalTitle');
40
+ const envInputsDiv = modal.querySelector('#modalEnvInputs');
41
+ const targetDiv = modal.querySelector('#modalTargets');
42
+ const modalRequirements = modal.querySelector('#modalRequirements');
43
+ const modalArguments = modal.querySelector('#modalArguments');
44
+
45
+ // Global array to track selected clients
46
+ window.selectedClients = [];
47
+
48
+ // Verify all required modal elements exist
49
+ if (!title || !envInputsDiv || !targetDiv || !modalRequirements || !modalArguments) {
50
+ console.error('Required modal elements not found');
51
+ return;
52
+ }
53
+
54
+ title.textContent = `Install ${serverName}`;
55
+ envInputsDiv.innerHTML = ''; // Clear previous inputs
56
+ targetDiv.innerHTML = ''; // Clear previous targets
57
+ modalRequirements.innerHTML = ''; // Clear previous requirements
58
+ modalArguments.innerHTML = ''; // Clear previous arguments
59
+
60
+ try {
61
+ // Fetch both targets and server data simultaneously
62
+ const [targetResponse, serverResponse] = await Promise.all([
63
+ fetch('/api/targets'),
64
+ fetch(`/api/categories/${categoryName}`)
65
+ ]);
66
+
67
+ if (!targetResponse.ok || !serverResponse.ok) {
68
+ throw new Error('Failed to fetch required data');
69
+ }
70
+
71
+ const [targetData, serverData] = await Promise.all([
72
+ targetResponse.json(),
73
+ serverResponse.json()
74
+ ]);
75
+
76
+ if (!targetData.success || !serverData.success) {
77
+ throw new Error('Invalid data received');
78
+ }
79
+
80
+ const mcpServer = serverData.data.feedConfiguration.mcpServers.find(server => server.name === serverName);
81
+ if (!mcpServer) {
82
+ throw new Error('Server configuration not found');
83
+ }
84
+
85
+ // Add mode indicator
86
+ const modeSpan = document.createElement('span');
87
+ modeSpan.textContent = mcpServer.mode || 'stdio';
88
+ modeSpan.className = 'ml-2 px-2 py-0.5 text-xs bg-gray-200 text-gray-600 rounded';
89
+ title.appendChild(modeSpan);
90
+ const installationStatus = serverData.data.installationStatus || {};
91
+ const serverStatuses = installationStatus.serversStatus || {};
92
+ const serverStatus = serverStatuses[serverName] || { installedStatus: {} };
93
+
94
+ await setupModalContent(
95
+ targetData,
96
+ mcpServer,
97
+ serverStatus,
98
+ categoryName,
99
+ serverName,
100
+ serverStatuses,
101
+ serverData,
102
+ targetDiv,
103
+ envInputsDiv,
104
+ modalArguments,
105
+ modalRequirements
106
+ );
107
+
108
+ } catch (error) {
109
+ console.error("Error loading data:", error);
110
+ targetDiv.innerHTML = `<p class="text-red-500">Error: ${error.message}</p>`;
111
+ }
112
+
113
+ modal.style.display = "block";
114
+ }
115
+
116
+ /**
117
+ * Set up the modal content including client list, environment variables, and requirements
118
+ * @private
119
+ */
120
+ async function setupModalContent(
121
+ targetData,
122
+ mcpServer,
123
+ serverStatus,
124
+ categoryName,
125
+ serverName,
126
+ serverStatuses,
127
+ serverData,
128
+ targetDiv,
129
+ envInputsDiv,
130
+ modalArguments,
131
+ modalRequirements
132
+ ) {
133
+ // Create client items
134
+ setupClientItems(targetData.data, serverStatus, categoryName, serverName, targetDiv);
135
+
136
+ // Handle environment variables section
137
+ setupEnvironmentVariables(mcpServer, envInputsDiv, targetData);
138
+
139
+ // Handle installation arguments section
140
+ setupInstallationArguments(mcpServer.installation, modalArguments, mcpServer);
141
+
142
+ // Handle server requirements section
143
+ setupServerRequirements(mcpServer, serverData, categoryName, serverName, modalRequirements);
144
+
145
+ // Set up the install form submit handler
146
+ const installForm = document.getElementById('installForm');
147
+ setupFormSubmitHandler(
148
+ installForm,
149
+ envInputsDiv,
150
+ modalArguments,
151
+ modalRequirements,
152
+ categoryName,
153
+ serverName,
154
+ serverStatuses,
155
+ serverData,
156
+ mcpServer
157
+ );
158
+ }
159
+
160
+ // Make functions available globally
161
+ window.showInstallModal = showInstallModal;
162
+ window.closeModal = closeModal;
163
+ window.uninstallTools = uninstallTools;