imcp 0.0.16 → 0.0.18

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 (151) hide show
  1. package/dist/cli/commands/install.js +2 -2
  2. package/dist/cli/commands/list.js +2 -2
  3. package/dist/cli/commands/serve.js +3 -2
  4. package/dist/core/RequirementService.d.ts +0 -12
  5. package/dist/core/RequirementService.js +0 -24
  6. package/dist/core/installers/clients/BaseClientInstaller.d.ts +26 -3
  7. package/dist/core/installers/clients/BaseClientInstaller.js +121 -0
  8. package/dist/core/installers/clients/ClientInstaller.d.ts +1 -1
  9. package/dist/core/installers/clients/ClientInstaller.js +1 -1
  10. package/dist/core/installers/clients/ClientInstallerFactory.js +1 -1
  11. package/dist/core/installers/clients/ClineInstaller.d.ts +1 -6
  12. package/dist/core/installers/clients/ClineInstaller.js +1 -94
  13. package/dist/core/installers/clients/ExtensionInstaller.js +1 -1
  14. package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +1 -6
  15. package/dist/core/installers/clients/GithubCopilotInstaller.js +1 -94
  16. package/dist/core/installers/clients/MSRooCodeInstaller.d.ts +1 -5
  17. package/dist/core/installers/clients/MSRooCodeInstaller.js +1 -94
  18. package/dist/core/installers/requirements/BaseInstaller.d.ts +1 -1
  19. package/dist/core/installers/requirements/BaseInstaller.js +1 -1
  20. package/dist/core/installers/requirements/CommandInstaller.d.ts +1 -1
  21. package/dist/core/installers/requirements/CommandInstaller.js +1 -1
  22. package/dist/core/installers/requirements/GeneralInstaller.d.ts +1 -1
  23. package/dist/core/installers/requirements/InstallerFactory.d.ts +1 -1
  24. package/dist/core/installers/requirements/NpmInstaller.d.ts +1 -1
  25. package/dist/core/installers/requirements/NpmInstaller.js +1 -1
  26. package/dist/core/installers/requirements/PipInstaller.d.ts +1 -1
  27. package/dist/core/installers/requirements/RequirementInstaller.d.ts +1 -1
  28. package/dist/core/loaders/ConfigurationLoader.d.ts +35 -0
  29. package/dist/core/loaders/ConfigurationLoader.js +257 -0
  30. package/dist/core/loaders/ConfigurationProvider.d.ts +38 -0
  31. package/dist/core/loaders/ConfigurationProvider.js +384 -0
  32. package/dist/core/loaders/ServerSchemaLoader.d.ts +22 -0
  33. package/dist/core/loaders/ServerSchemaLoader.js +109 -0
  34. package/dist/core/loaders/ServerSchemaProvider.d.ts +14 -0
  35. package/dist/core/loaders/ServerSchemaProvider.js +90 -0
  36. package/dist/core/metadatas/constants.d.ts +47 -0
  37. package/dist/core/metadatas/constants.js +94 -0
  38. package/dist/core/metadatas/types.d.ts +167 -0
  39. package/dist/core/metadatas/types.js +16 -0
  40. package/dist/core/onboard/FeedOnboardService.d.ts +15 -8
  41. package/dist/core/onboard/FeedOnboardService.js +215 -130
  42. package/dist/core/onboard/OnboardProcessor.d.ts +8 -2
  43. package/dist/core/onboard/OnboardProcessor.js +53 -9
  44. package/dist/core/onboard/OnboardStatus.d.ts +7 -2
  45. package/dist/core/onboard/OnboardStatusManager.d.ts +71 -25
  46. package/dist/core/onboard/OnboardStatusManager.js +231 -47
  47. package/dist/core/validators/FeedValidator.d.ts +8 -3
  48. package/dist/core/validators/FeedValidator.js +61 -7
  49. package/dist/core/validators/IServerValidator.d.ts +1 -1
  50. package/dist/core/validators/SSEServerValidator.d.ts +1 -1
  51. package/dist/core/validators/ServerValidatorFactory.d.ts +1 -1
  52. package/dist/core/validators/StdioServerValidator.d.ts +1 -1
  53. package/dist/core/validators/StdioServerValidator.js +85 -33
  54. package/dist/index.d.ts +3 -3
  55. package/dist/index.js +3 -3
  56. package/dist/services/InstallationService.d.ts +50 -0
  57. package/dist/services/InstallationService.js +350 -0
  58. package/dist/services/MCPManager.d.ts +29 -0
  59. package/dist/services/MCPManager.js +192 -0
  60. package/dist/services/RequirementService.d.ts +40 -0
  61. package/dist/services/RequirementService.js +110 -0
  62. package/dist/services/ServerService.d.ts +2 -2
  63. package/dist/services/ServerService.js +6 -6
  64. package/dist/utils/adoUtils.d.ts +2 -2
  65. package/dist/utils/adoUtils.js +1 -1
  66. package/dist/utils/feedUtils.js +1 -1
  67. package/dist/utils/githubUtils.d.ts +1 -1
  68. package/dist/utils/githubUtils.js +1 -1
  69. package/dist/utils/logger.d.ts +2 -0
  70. package/dist/utils/logger.js +11 -1
  71. package/dist/utils/macroExpressionUtils.d.ts +1 -1
  72. package/dist/utils/osUtils.d.ts +1 -1
  73. package/dist/utils/osUtils.js +1 -1
  74. package/dist/web/contract/serverContract.d.ts +1 -1
  75. package/dist/web/public/index.html +1 -3
  76. package/dist/web/public/js/api.js +2 -80
  77. package/dist/web/public/js/modal/installation.js +1 -1
  78. package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +41 -9
  79. package/dist/web/public/js/onboard/formProcessor.js +200 -34
  80. package/dist/web/public/js/onboard/index.js +2 -2
  81. package/dist/web/public/js/onboard/publishHandler.js +30 -22
  82. package/dist/web/public/js/onboard/templates.js +34 -40
  83. package/dist/web/public/js/onboard/uiHandlers.js +175 -84
  84. package/dist/web/public/js/onboard/validationHandlers.js +147 -64
  85. package/dist/web/public/js/serverCategoryDetails.js +19 -4
  86. package/dist/web/public/js/serverCategoryList.js +13 -1
  87. package/dist/web/public/onboard.html +1 -1
  88. package/dist/web/server.js +21 -8
  89. package/package.json +1 -1
  90. package/src/cli/commands/install.ts +3 -3
  91. package/src/cli/commands/list.ts +2 -2
  92. package/src/cli/commands/serve.ts +3 -2
  93. package/src/cli/index.ts +1 -1
  94. package/src/core/installers/clients/BaseClientInstaller.ts +134 -3
  95. package/src/core/installers/clients/ClientInstaller.ts +3 -3
  96. package/src/core/installers/clients/ClientInstallerFactory.ts +1 -1
  97. package/src/core/installers/clients/ClineInstaller.ts +1 -101
  98. package/src/core/installers/clients/ExtensionInstaller.ts +1 -1
  99. package/src/core/installers/clients/GithubCopilotInstaller.ts +1 -101
  100. package/src/core/installers/clients/MSRooCodeInstaller.ts +1 -102
  101. package/src/core/installers/requirements/BaseInstaller.ts +2 -2
  102. package/src/core/installers/requirements/CommandInstaller.ts +1 -1
  103. package/src/core/installers/requirements/GeneralInstaller.ts +1 -1
  104. package/src/core/installers/requirements/InstallerFactory.ts +1 -1
  105. package/src/core/installers/requirements/NpmInstaller.ts +12 -12
  106. package/src/core/installers/requirements/PipInstaller.ts +1 -1
  107. package/src/core/installers/requirements/RequirementInstaller.ts +1 -1
  108. package/src/core/{ConfigurationLoader.ts → loaders/ConfigurationLoader.ts} +31 -7
  109. package/src/core/{ConfigurationProvider.ts → loaders/ConfigurationProvider.ts} +18 -10
  110. package/src/core/loaders/ServerSchemaLoader.ts +117 -0
  111. package/src/core/loaders/ServerSchemaProvider.ts +99 -0
  112. package/src/core/{types.ts → metadatas/types.ts} +3 -2
  113. package/src/core/onboard/FeedOnboardService.ts +270 -146
  114. package/src/core/onboard/OnboardProcessor.ts +60 -11
  115. package/src/core/onboard/OnboardStatus.ts +7 -2
  116. package/src/core/onboard/OnboardStatusManager.ts +270 -43
  117. package/src/core/validators/FeedValidator.ts +65 -9
  118. package/src/core/validators/IServerValidator.ts +1 -1
  119. package/src/core/validators/SSEServerValidator.ts +2 -2
  120. package/src/core/validators/ServerValidatorFactory.ts +1 -1
  121. package/src/core/validators/StdioServerValidator.ts +86 -34
  122. package/src/index.ts +3 -3
  123. package/src/{core → services}/InstallationService.ts +5 -5
  124. package/src/{core → services}/MCPManager.ts +10 -5
  125. package/src/{core → services}/RequirementService.ts +2 -31
  126. package/src/services/ServerService.ts +7 -7
  127. package/src/utils/adoUtils.ts +3 -3
  128. package/src/utils/feedUtils.ts +2 -2
  129. package/src/utils/githubUtils.ts +2 -2
  130. package/src/utils/logger.ts +13 -1
  131. package/src/utils/macroExpressionUtils.ts +1 -1
  132. package/src/utils/osUtils.ts +4 -4
  133. package/src/web/contract/serverContract.ts +2 -2
  134. package/src/web/public/index.html +1 -3
  135. package/src/web/public/js/api.js +2 -80
  136. package/src/web/public/js/modal/installation.js +1 -1
  137. package/src/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +41 -9
  138. package/src/web/public/js/onboard/formProcessor.js +200 -34
  139. package/src/web/public/js/onboard/index.js +2 -2
  140. package/src/web/public/js/onboard/publishHandler.js +30 -22
  141. package/src/web/public/js/onboard/templates.js +34 -40
  142. package/src/web/public/js/onboard/uiHandlers.js +175 -84
  143. package/src/web/public/js/onboard/validationHandlers.js +147 -64
  144. package/src/web/public/js/serverCategoryDetails.js +19 -4
  145. package/src/web/public/js/serverCategoryList.js +13 -1
  146. package/src/web/public/onboard.html +1 -1
  147. package/src/web/server.ts +30 -14
  148. package/src/core/ServerSchemaLoader.ts +0 -48
  149. package/src/core/ServerSchemaProvider.ts +0 -137
  150. package/src/services/InstallRequestValidator.ts +0 -112
  151. /package/src/core/{constants.ts → metadatas/constants.ts} +0 -0
@@ -1,11 +1,14 @@
1
1
  import { Logger } from '../../../utils/logger.js';
2
2
  import { exec } from 'child_process';
3
3
  import { promisify } from 'util';
4
+ import { isCommandAvailable } from '../../../utils/osUtils.js';
5
+ import { ExtensionInstaller } from './ExtensionInstaller.js';
6
+ import { SUPPORTED_CLIENTS } from '../../metadatas/constants.js';
4
7
  import {
5
8
  OperationStatus,
6
9
  McpConfig,
7
10
  ServerInstallOptions,
8
- } from '../../types.js';
11
+ } from '../../metadatas/types.js';
9
12
  import {
10
13
  MACRO_EXPRESSIONS,
11
14
  MacroResolverFunctions
@@ -17,6 +20,7 @@ const execAsync = promisify(exec);
17
20
  * Base class for client installers with shared functionality
18
21
  */
19
22
  export abstract class BaseClientInstaller {
23
+ protected abstract readonly clientName: string;
20
24
  /**
21
25
  * Generate a unique operation ID for tracking installations
22
26
  */
@@ -189,8 +193,135 @@ export abstract class BaseClientInstaller {
189
193
  }
190
194
 
191
195
  /**
192
- * Abstract methods that must be implemented by client-specific installers
196
+ * Checks if VS Code or VS Code Insiders is installed and installs the client extension.
197
+ * @param operationId The operation ID for tracking.
198
+ * @returns An OperationStatus object if checks fail or installation fails, otherwise undefined.
199
+ */
200
+ protected async checkVSCodeAndInstallExtension(operationId: string): Promise<OperationStatus | undefined> {
201
+ // Check if VS Code or VS Code Insiders is installed
202
+ const isVSCodeInstalled = await isCommandAvailable('code');
203
+ const isVSCodeInsidersInstalled = await isCommandAvailable('code-insiders');
204
+
205
+ if (!isVSCodeInstalled && !isVSCodeInsidersInstalled) {
206
+ return {
207
+ status: 'failed',
208
+ type: 'install',
209
+ target: 'server',
210
+ message: 'Failed to install as neither VS Code nor VS Code Insiders are installed on this system. Please run `code` or `code-insiders` to make sure they are installed. Relaunch imcp after installation.',
211
+ operationId
212
+ };
213
+ }
214
+
215
+ // Install extension
216
+ const extensionResult = await ExtensionInstaller.installExtension(this.clientName);
217
+ if (!extensionResult) {
218
+ Logger.debug(`Failed to install ${this.clientName} extension`);
219
+ return {
220
+ status: 'failed',
221
+ type: 'install',
222
+ target: 'server',
223
+ message: `Failed to install ${this.clientName} extension`,
224
+ operationId
225
+ };
226
+ }
227
+ return undefined;
228
+ }
229
+
230
+ /**
231
+ * Update VS Code settings for both VS Code and VS Code Insiders if installed
232
+ * @param serverName The name of the server to configure
233
+ * @param installConfig The installation configuration
234
+ * @returns Array of results indicating success/failure for each VS Code variant
235
+ */
236
+ protected async updateVSCodeSettings(serverName: string, installConfig: any): Promise<Array<{ success: boolean; path: string; error?: string }>> {
237
+ const results: Array<{ success: boolean; path: string; error?: string }> = [];
238
+ const isVSCodeInstalled = await isCommandAvailable('code');
239
+ const isVSCodeInsidersInstalled = await isCommandAvailable('code-insiders');
240
+
241
+ // Update settings for VS Code if installed
242
+ if (isVSCodeInstalled) {
243
+ try {
244
+ const settingPath = SUPPORTED_CLIENTS[this.clientName].codeSettingPath;
245
+ await this.setupClientSettings(settingPath, serverName, installConfig);
246
+ results.push({ success: true, path: settingPath });
247
+ } catch (error) {
248
+ results.push({
249
+ success: false,
250
+ path: SUPPORTED_CLIENTS[this.clientName].codeSettingPath,
251
+ error: error instanceof Error ? error.message : String(error)
252
+ });
253
+ }
254
+ }
255
+
256
+ // Update settings for VS Code Insiders if installed
257
+ if (isVSCodeInsidersInstalled) {
258
+ try {
259
+ const settingPath = SUPPORTED_CLIENTS[this.clientName].codeInsiderSettingPath;
260
+ await this.setupClientSettings(settingPath, serverName, installConfig);
261
+ results.push({ success: true, path: settingPath });
262
+ } catch (error) {
263
+ results.push({
264
+ success: false,
265
+ path: SUPPORTED_CLIENTS[this.clientName].codeInsiderSettingPath,
266
+ error: error instanceof Error ? error.message : String(error)
267
+ });
268
+ }
269
+ }
270
+
271
+ return results;
272
+ }
273
+
274
+ /**
275
+ * Install the client
276
+ * @param serverConfig Server configuration
277
+ * @param options Installation options including environment variables and arguments
278
+ */
279
+ async install(serverConfig: McpConfig, options: ServerInstallOptions): Promise<OperationStatus> {
280
+ const operationId = this.generateOperationId();
281
+
282
+ try {
283
+ const vsCodeCheckResult = await this.checkVSCodeAndInstallExtension(operationId);
284
+ if (vsCodeCheckResult) {
285
+ return vsCodeCheckResult;
286
+ }
287
+
288
+ const installConfig = await this.setupInstallConfig(serverConfig, options);
289
+ if (serverConfig.mode) {
290
+ installConfig.mode = serverConfig.mode;
291
+ }
292
+
293
+ // Update VS Code settings
294
+ const results = await this.updateVSCodeSettings(serverConfig.name, installConfig);
295
+
296
+ // Determine overall success
297
+ const anySuccess = results.some(r => r.success);
298
+ const successPaths = results.filter(r => r.success).map(r => r.path);
299
+ const errors = results.filter(r => !r.success).map(r => r.error);
300
+
301
+ return {
302
+ status: anySuccess ? 'completed' : 'failed',
303
+ type: 'install',
304
+ target: 'server',
305
+ message: anySuccess
306
+ ? `Successfully installed ${this.clientName} client. Updated settings in: ${successPaths.join(', ')}`
307
+ : `Failed to install ${this.clientName} client. Errors: ${errors.join('; ')}`,
308
+ operationId,
309
+ error: anySuccess ? undefined : errors.join('; ')
310
+ };
311
+ } catch (error) {
312
+ return {
313
+ status: 'failed',
314
+ type: 'install',
315
+ target: 'server',
316
+ message: `Unexpected error installing ${this.clientName} client: ${error instanceof Error ? error.message : String(error)}`,
317
+ operationId,
318
+ error: error instanceof Error ? error.message : String(error)
319
+ };
320
+ }
321
+ }
322
+
323
+ /**
324
+ * Abstract method that must be implemented by client-specific installers
193
325
  */
194
- abstract install(serverConfig: McpConfig, options: ServerInstallOptions): Promise<OperationStatus>;
195
326
  abstract setupClientSettings(settingPath: string, serverName: string, installConfig: any): Promise<void>;
196
327
  }
@@ -1,12 +1,12 @@
1
- import { ConfigurationProvider } from '../../ConfigurationProvider.js';
2
- import { SUPPORTED_CLIENTS } from '../../constants.js';
1
+ import { ConfigurationProvider } from '../../loaders/ConfigurationProvider.js';
2
+ import { SUPPORTED_CLIENTS } from '../../metadatas/constants.js';
3
3
  import {
4
4
  ServerOperationResult,
5
5
  OperationStatus,
6
6
  ServerInstallOptions,
7
7
  McpConfig,
8
8
  RequirementStatus
9
- } from '../../types.js';
9
+ } from '../../metadatas/types.js';
10
10
  import { Logger } from '../../../utils/logger.js';
11
11
  import { ClientInstallerFactory } from './ClientInstallerFactory.js';
12
12
 
@@ -2,7 +2,7 @@ import { MSRooCodeInstaller } from './MSRooCodeInstaller.js';
2
2
  import { ClineInstaller } from './ClineInstaller.js';
3
3
  import { GithubCopilotInstaller } from './GithubCopilotInstaller.js';
4
4
  import { BaseClientInstaller } from './BaseClientInstaller.js';
5
- import { SUPPORTED_CLIENTS } from '../../constants.js';
5
+ import { SUPPORTED_CLIENTS } from '../../metadatas/constants.js';
6
6
 
7
7
  /**
8
8
  * Factory for creating client-specific installers
@@ -1,112 +1,12 @@
1
1
  import { BaseClientInstaller } from './BaseClientInstaller.js';
2
- import { Logger } from '../../../utils/logger.js';
3
2
  import { readJsonFile, writeJsonFile } from '../../../utils/clientUtils.js';
4
- import { ServerInstallOptions, OperationStatus, McpConfig } from '../../types.js';
5
- import { ExtensionInstaller } from './ExtensionInstaller.js';
6
- import { SUPPORTED_CLIENTS } from '../../constants.js';
7
- import { isCommandAvailable } from '../../../utils/osUtils.js';
8
3
 
9
4
  /**
10
5
  * Cline client installer implementation
11
6
  * Handles installation of Cline client including extension installation and settings configuration
12
7
  */
13
8
  export class ClineInstaller extends BaseClientInstaller {
14
- /**
15
- * Install Cline client
16
- * @param options Installation options including environment variables and arguments
17
- */
18
- async install(serverConfig: McpConfig, options: ServerInstallOptions): Promise<OperationStatus> {
19
- const operationId = this.generateOperationId();
20
-
21
- try {
22
- // Check if VS Code or VS Code Insiders is installed
23
- const isVSCodeInstalled = await isCommandAvailable('code');
24
- const isVSCodeInsidersInstalled = await isCommandAvailable('code-insiders');
25
-
26
- if (!isVSCodeInstalled && !isVSCodeInsidersInstalled) {
27
- return {
28
- status: 'failed',
29
- type: 'install',
30
- target: 'server',
31
- message: 'Neither VS Code nor VS Code Insiders are installed on this system',
32
- operationId
33
- };
34
- }
35
-
36
- // Install extension
37
- const extensionResult = await ExtensionInstaller.installExtension('Cline');
38
- if (!extensionResult) {
39
- Logger.debug('Failed to install Cline extension');
40
- return {
41
- status: 'failed',
42
- type: 'install',
43
- target: 'server',
44
- message: 'Failed to install Cline extension',
45
- operationId
46
- };
47
- }
48
-
49
-
50
- const installConfig = await this.setupInstallConfig(serverConfig, options);
51
- // Track success for both VS Code variants
52
- const results: Array<{ success: boolean; path: string; error?: string }> = [];
53
-
54
- // Update settings for VS Code if installed
55
- if (isVSCodeInstalled) {
56
- try {
57
- const settingPath = SUPPORTED_CLIENTS['Cline'].codeSettingPath;
58
- await this.setupClientSettings(settingPath, serverConfig.name, installConfig);
59
- results.push({ success: true, path: settingPath });
60
- } catch (error) {
61
- results.push({
62
- success: false,
63
- path: SUPPORTED_CLIENTS['Cline'].codeSettingPath,
64
- error: error instanceof Error ? error.message : String(error)
65
- });
66
- }
67
- }
68
-
69
- // Update settings for VS Code Insiders if installed
70
- if (isVSCodeInsidersInstalled) {
71
- try {
72
- const settingPath = SUPPORTED_CLIENTS['Cline'].codeInsiderSettingPath;
73
- await this.setupClientSettings(settingPath, serverConfig.name, installConfig);
74
- results.push({ success: true, path: settingPath });
75
- } catch (error) {
76
- results.push({
77
- success: false,
78
- path: SUPPORTED_CLIENTS['Cline'].codeInsiderSettingPath,
79
- error: error instanceof Error ? error.message : String(error)
80
- });
81
- }
82
- }
83
-
84
- // Determine overall success
85
- const anySuccess = results.some(r => r.success);
86
- const successPaths = results.filter(r => r.success).map(r => r.path);
87
- const errors = results.filter(r => !r.success).map(r => r.error);
88
-
89
- return {
90
- status: anySuccess ? 'completed' : 'failed',
91
- type: 'install',
92
- target: 'server',
93
- message: anySuccess
94
- ? `Successfully installed Cline client. Updated settings in: ${successPaths.join(', ')}`
95
- : `Failed to install Cline client. Errors: ${errors.join('; ')}`,
96
- operationId,
97
- error: anySuccess ? undefined : errors.join('; ')
98
- };
99
- } catch (error) {
100
- return {
101
- status: 'failed',
102
- type: 'install',
103
- target: 'server',
104
- message: `Unexpected error installing Cline client: ${error instanceof Error ? error.message : String(error)}`,
105
- operationId,
106
- error: error instanceof Error ? error.message : String(error)
107
- };
108
- }
109
- }
9
+ protected readonly clientName: string = 'Cline';
110
10
 
111
11
  /**
112
12
  * Set up Cline client settings
@@ -1,6 +1,6 @@
1
1
  import { exec } from 'child_process';
2
2
  import { promisify } from 'util';
3
- import { SUPPORTED_CLIENTS } from '../../constants.js';
3
+ import { SUPPORTED_CLIENTS } from '../../metadatas/constants.js';
4
4
  import { Logger } from '../../../utils/logger.js';
5
5
  import { handleGitHubRelease } from '../../../utils/githubUtils.js';
6
6
  import { compareVersions } from '../../../utils/versionUtils.js';
@@ -1,113 +1,13 @@
1
1
  import { BaseClientInstaller } from './BaseClientInstaller.js';
2
- import { Logger } from '../../../utils/logger.js';
3
2
  import { readJsonFile, writeJsonFile } from '../../../utils/clientUtils.js';
4
- import { ServerInstallOptions, OperationStatus, McpConfig } from '../../types.js';
5
- import { ExtensionInstaller } from './ExtensionInstaller.js';
6
- import { SUPPORTED_CLIENTS } from '../../constants.js';
7
- import { isCommandAvailable } from '../../../utils/osUtils.js';
8
3
 
9
4
  /**
10
5
  * Github Copilot client installer implementation
11
6
  * Handles installation of Github Copilot client including extension installation and settings configuration
12
7
  */
13
8
  export class GithubCopilotInstaller extends BaseClientInstaller {
9
+ protected readonly clientName: string = 'GithubCopilot';
14
10
 
15
- /**
16
- * Install Github Copilot client
17
- * @param options Installation options including environment variables and arguments
18
- */
19
- async install(serverConfig: McpConfig, options: ServerInstallOptions): Promise<OperationStatus> {
20
- const operationId = this.generateOperationId();
21
-
22
- try {
23
- // Check if VS Code or VS Code Insiders is installed
24
- const isVSCodeInstalled = await isCommandAvailable('code');
25
- const isVSCodeInsidersInstalled = await isCommandAvailable('code-insiders');
26
-
27
- if (!isVSCodeInstalled && !isVSCodeInsidersInstalled) {
28
- return {
29
- status: 'failed',
30
- type: 'install',
31
- target: 'server',
32
- message: 'Neither VS Code nor VS Code Insiders are installed on this system',
33
- operationId
34
- };
35
- }
36
-
37
- // Install extension
38
- const extensionResult = await ExtensionInstaller.installExtension('GithubCopilot');
39
- if (!extensionResult) {
40
- Logger.debug('Failed to install Github Copilot extension');
41
- return {
42
- status: 'failed',
43
- type: 'install',
44
- target: 'server',
45
- message: 'Failed to install Github Copilot extension',
46
- operationId
47
- };
48
- }
49
-
50
- const installConfig = await this.setupInstallConfig(serverConfig, options);
51
-
52
- // Track success for both VS Code variants
53
- const results: Array<{ success: boolean; path: string; error?: string }> = [];
54
-
55
- // Update settings for VS Code if installed
56
- if (isVSCodeInstalled) {
57
- try {
58
- const settingPath = SUPPORTED_CLIENTS['GithubCopilot'].codeSettingPath;
59
- await this.setupClientSettings(settingPath, serverConfig.name, installConfig);
60
- results.push({ success: true, path: settingPath });
61
- } catch (error) {
62
- results.push({
63
- success: false,
64
- path: SUPPORTED_CLIENTS['GithubCopilot'].codeSettingPath,
65
- error: error instanceof Error ? error.message : String(error)
66
- });
67
- }
68
- }
69
-
70
- // Update settings for VS Code Insiders if installed
71
- if (isVSCodeInsidersInstalled) {
72
- try {
73
- const settingPath = SUPPORTED_CLIENTS['GithubCopilot'].codeInsiderSettingPath;
74
- await this.setupClientSettings(settingPath, serverConfig.name, installConfig);
75
- results.push({ success: true, path: settingPath });
76
- } catch (error) {
77
- results.push({
78
- success: false,
79
- path: SUPPORTED_CLIENTS['GithubCopilot'].codeInsiderSettingPath,
80
- error: error instanceof Error ? error.message : String(error)
81
- });
82
- }
83
- }
84
-
85
- // Determine overall success
86
- const anySuccess = results.some(r => r.success);
87
- const successPaths = results.filter(r => r.success).map(r => r.path);
88
- const errors = results.filter(r => !r.success).map(r => r.error);
89
-
90
- return {
91
- status: anySuccess ? 'completed' : 'failed',
92
- type: 'install',
93
- target: 'server',
94
- message: anySuccess
95
- ? `Successfully installed Github Copilot client. Updated settings in: ${successPaths.join(', ')}`
96
- : `Failed to install Github Copilot client. Errors: ${errors.join('; ')}`,
97
- operationId,
98
- error: anySuccess ? undefined : errors.join('; ')
99
- };
100
- } catch (error) {
101
- return {
102
- status: 'failed',
103
- type: 'install',
104
- target: 'server',
105
- message: `Unexpected error installing Github Copilot client: ${error instanceof Error ? error.message : String(error)}`,
106
- operationId,
107
- error: error instanceof Error ? error.message : String(error)
108
- };
109
- }
110
- }
111
11
 
112
12
  /**
113
13
  * Initialize settings with GithubCopilot-specific structure
@@ -1,112 +1,11 @@
1
1
  import { BaseClientInstaller } from './BaseClientInstaller.js';
2
- import { Logger } from '../../../utils/logger.js';
3
2
  import { readJsonFile, writeJsonFile } from '../../../utils/clientUtils.js';
4
- import { ServerInstallOptions, OperationStatus, McpConfig } from '../../types.js';
5
- import { ExtensionInstaller } from './ExtensionInstaller.js';
6
- import { SUPPORTED_CLIENTS } from '../../constants.js';
7
- import { isCommandAvailable } from '../../../utils/osUtils.js';
8
3
 
9
4
  /**
10
5
  * MSRooCode client installer implementation
11
6
  */
12
7
  export class MSRooCodeInstaller extends BaseClientInstaller {
13
- /**
14
- * Install MSRooCode client
15
- */
16
- async install(serverConfig: McpConfig, options: ServerInstallOptions): Promise<OperationStatus> {
17
- const operationId = this.generateOperationId();
18
-
19
- try {
20
- // Check if VS Code or VS Code Insiders is installed
21
- const isVSCodeInstalled = await isCommandAvailable('code');
22
- const isVSCodeInsidersInstalled = await isCommandAvailable('code-insiders');
23
-
24
- if (!isVSCodeInstalled && !isVSCodeInsidersInstalled) {
25
- return {
26
- status: 'failed',
27
- type: 'install',
28
- target: 'server',
29
- message: 'Neither VS Code nor VS Code Insiders are installed on this system',
30
- operationId
31
- };
32
- }
33
-
34
- // Install extension
35
- const extensionResult = await ExtensionInstaller.installExtension('MSRooCode');
36
- if (!extensionResult) {
37
- Logger.debug('Failed to install MSRooCode extension');
38
- return {
39
- status: 'failed',
40
- type: 'install',
41
- target: 'server',
42
- message: 'Failed to install MSRooCode extension',
43
- operationId
44
- };
45
- }
46
-
47
- const installConfig = await this.setupInstallConfig(serverConfig, options);
48
- installConfig.mode = serverConfig.mode;
49
-
50
- // Track success for both VS Code variants
51
- const results: Array<{ success: boolean; path: string; error?: string }> = [];
52
-
53
- // Update settings for VS Code if installed
54
- if (isVSCodeInstalled) {
55
- try {
56
- const settingPath = SUPPORTED_CLIENTS['MSRooCode'].codeSettingPath;
57
- await this.setupClientSettings(settingPath, serverConfig.name, installConfig);
58
- results.push({ success: true, path: settingPath });
59
- } catch (error) {
60
- results.push({
61
- success: false,
62
- path: SUPPORTED_CLIENTS['MSRooCode'].codeSettingPath,
63
- error: error instanceof Error ? error.message : String(error)
64
- });
65
- }
66
- }
67
-
68
- // Update settings for VS Code Insiders if installed
69
- if (isVSCodeInsidersInstalled) {
70
- try {
71
- const settingPath = SUPPORTED_CLIENTS['MSRooCode'].codeInsiderSettingPath;
72
- await this.setupClientSettings(settingPath, serverConfig.name, installConfig);
73
- results.push({ success: true, path: settingPath });
74
- } catch (error) {
75
- results.push({
76
- success: false,
77
- path: SUPPORTED_CLIENTS['MSRooCode'].codeInsiderSettingPath,
78
- error: error instanceof Error ? error.message : String(error)
79
- });
80
- }
81
- }
82
-
83
- // Determine overall success
84
- const anySuccess = results.some(r => r.success);
85
- const successPaths = results.filter(r => r.success).map(r => r.path);
86
- const errors = results.filter(r => !r.success).map(r => r.error);
87
-
88
- return {
89
- status: anySuccess ? 'completed' : 'failed',
90
- type: 'install',
91
- target: 'server',
92
- message: anySuccess
93
- ? `Successfully installed MSRooCode client. Updated settings in: ${successPaths.join(', ')}`
94
- : `Failed to install MSRooCode client. Errors: ${errors.join('; ')}`,
95
- operationId,
96
- error: anySuccess ? undefined : errors.join('; ')
97
- };
98
- } catch (error) {
99
- return {
100
- status: 'failed',
101
- type: 'install',
102
- target: 'server',
103
- message: `Unexpected error installing MSRooCode client: ${error instanceof Error ? error.message : String(error)}`,
104
- operationId,
105
- error: error instanceof Error ? error.message : String(error)
106
- };
107
- }
108
- }
109
-
8
+ protected readonly clientName: string = 'MSRooCode';
110
9
  /**
111
10
  * Set up MSRooCode client settings
112
11
  */
@@ -1,6 +1,6 @@
1
- import { RequirementConfig, RequirementStatus, RegistryConfig, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, RegistryConfig, ServerInstallOptions } from '../../metadatas/types.js';
2
2
  import path from 'path';
3
- import { SETTINGS_DIR } from '../../constants.js';
3
+ import { SETTINGS_DIR } from '../../metadatas/constants.js';
4
4
  import { RequirementInstaller } from './RequirementInstaller.js';
5
5
  import { Logger } from '../../../utils/logger.js';
6
6
 
@@ -1,4 +1,4 @@
1
- import { RequirementConfig, RequirementStatus, OSType, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, OSType, ServerInstallOptions } from '../../metadatas/types.js';
2
2
  import { BaseInstaller } from './BaseInstaller.js';
3
3
  import { getOSType, refreshPathEnv } from '../../../utils/osUtils.js';
4
4
  import { Logger } from '../../../utils/logger.js';
@@ -1,4 +1,4 @@
1
- import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
2
2
  import { BaseInstaller } from './BaseInstaller.js';
3
3
  import { handleGitHubRelease } from '../../../utils/githubUtils.js';
4
4
  import { handleArtifact } from '../../../utils/adoUtils.js';
@@ -1,4 +1,4 @@
1
- import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
2
2
  import { RequirementInstaller } from './RequirementInstaller.js';
3
3
  import { NpmInstaller } from './NpmInstaller.js';
4
4
  import { PipInstaller } from './PipInstaller.js';
@@ -1,4 +1,4 @@
1
- import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
2
2
  import { BaseInstaller } from './BaseInstaller.js';
3
3
  import { compareVersions } from '../../../utils/versionUtils.js';
4
4
  import { handleGitHubRelease, getGitHubLatestVersion } from '../../../utils/githubUtils.js';
@@ -6,7 +6,7 @@ import { handleGitHubRelease, getGitHubLatestVersion } from '../../../utils/gith
6
6
  import { handleArtifact as handleAdoArtifact, AdoArtifactResult, getArtifactLatestVersion } from '../../../utils/adoUtils.js';
7
7
  import path from 'path';
8
8
  import fs from 'fs/promises';
9
- import { SETTINGS_DIR } from '../../constants.js'; // Corrected path
9
+ import { SETTINGS_DIR } from '../../metadatas/constants.js'; // Corrected path
10
10
  import { Logger } from '../../../utils/logger.js';
11
11
  /**
12
12
  * Installer implementation for NPM packages
@@ -55,9 +55,9 @@ export class NpmInstaller extends BaseInstaller {
55
55
  */
56
56
  private _getRequirementFolderPath(requirement: RequirementConfig): string {
57
57
  return path.join(
58
- SETTINGS_DIR,
59
- 'npm_requirements',
60
- requirement.name,
58
+ SETTINGS_DIR,
59
+ 'npm_requirements',
60
+ requirement.name,
61
61
  requirement.version.includes('latest') ? 'latest' : requirement.version);
62
62
  }
63
63
 
@@ -156,11 +156,11 @@ export class NpmInstaller extends BaseInstaller {
156
156
  ): Promise<{ version: string }> {
157
157
  Logger.debug(`Installing NPM package from "${packageSource}" into "${targetDir}"`);
158
158
  await fs.mkdir(targetDir, { recursive: true });
159
-
159
+
160
160
  const installCommand = `npm install ${packageSource} --prefix "${targetDir}"`;
161
161
  Logger.debug(`Executing install command: ${installCommand}`);
162
162
  const requirementName = this._getRequirementName(requirement);
163
-
163
+
164
164
  try {
165
165
  const { stdout: installStdout, stderr: installStderr } = await this.execPromise(installCommand);
166
166
  Logger.debug(`NPM install stdout for ${packageSource} in ${targetDir}: ${installStdout}`);
@@ -194,7 +194,7 @@ export class NpmInstaller extends BaseInstaller {
194
194
  */
195
195
  async install(requirement: RequirementConfig, options?: ServerInstallOptions): Promise<RequirementStatus> {
196
196
  const targetDir = options?.settings?.folderName || this._getRequirementFolderPath(requirement);
197
- await fs.mkdir(targetDir, { recursive: true });
197
+ await fs.mkdir(targetDir, { recursive: true });
198
198
 
199
199
  try {
200
200
  const status = await this.checkInstallation(requirement, { settings: { folderName: targetDir } });
@@ -204,19 +204,19 @@ export class NpmInstaller extends BaseInstaller {
204
204
  }
205
205
 
206
206
  let resolvedVersion = requirement.version;
207
- let packageToInstall: string = `${requirement.name}@${requirement.version}`;
207
+ let packageToInstall: string = `${requirement.name}@${requirement.version}`;
208
208
 
209
209
  if (requirement.registry) {
210
210
  if (requirement.registry.githubRelease) {
211
211
  const result = await handleGitHubRelease(requirement, requirement.registry.githubRelease);
212
- packageToInstall = result.resolvedPath;
212
+ packageToInstall = result.resolvedPath;
213
213
  resolvedVersion = result.resolvedVersion;
214
214
  } else if (requirement.registry.artifacts) {
215
215
  const adoResult: AdoArtifactResult = await handleAdoArtifact(
216
216
  requirement,
217
217
  requirement.registry.artifacts,
218
- options?.settings?.pythonCommand,
219
- targetDir
218
+ options?.settings?.pythonCommand,
219
+ targetDir
220
220
  );
221
221
  packageToInstall = `${adoResult.package}@${adoResult.version}`;
222
222
  resolvedVersion = adoResult.version;
@@ -1,4 +1,4 @@
1
- import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
2
2
  import { BaseInstaller } from './BaseInstaller.js';
3
3
  import { handleGitHubRelease, getGitHubLatestVersion } from '../../../utils/githubUtils.js';
4
4
  // Assuming getArtifactLatestVersion will be available in adoUtils.ts
@@ -1,4 +1,4 @@
1
- import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../types.js';
1
+ import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
2
2
 
3
3
  /**
4
4
  * Interface for requirement installers.