imcp 0.0.16 → 0.0.17
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.
- package/dist/cli/commands/install.js +2 -2
- package/dist/cli/commands/list.js +2 -2
- package/dist/cli/commands/serve.js +1 -1
- package/dist/core/RequirementService.d.ts +0 -12
- package/dist/core/RequirementService.js +0 -24
- package/dist/core/installers/clients/BaseClientInstaller.d.ts +1 -1
- package/dist/core/installers/clients/ClientInstaller.d.ts +1 -1
- package/dist/core/installers/clients/ClientInstaller.js +1 -1
- package/dist/core/installers/clients/ClientInstallerFactory.js +1 -1
- package/dist/core/installers/clients/ClineInstaller.d.ts +1 -1
- package/dist/core/installers/clients/ClineInstaller.js +1 -1
- package/dist/core/installers/clients/ExtensionInstaller.js +1 -1
- package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +1 -1
- package/dist/core/installers/clients/GithubCopilotInstaller.js +1 -1
- package/dist/core/installers/clients/MSRooCodeInstaller.d.ts +1 -1
- package/dist/core/installers/clients/MSRooCodeInstaller.js +1 -1
- package/dist/core/installers/requirements/BaseInstaller.d.ts +1 -1
- package/dist/core/installers/requirements/BaseInstaller.js +1 -1
- package/dist/core/installers/requirements/CommandInstaller.d.ts +1 -1
- package/dist/core/installers/requirements/CommandInstaller.js +1 -1
- package/dist/core/installers/requirements/GeneralInstaller.d.ts +1 -1
- package/dist/core/installers/requirements/InstallerFactory.d.ts +1 -1
- package/dist/core/installers/requirements/NpmInstaller.d.ts +1 -1
- package/dist/core/installers/requirements/NpmInstaller.js +1 -1
- package/dist/core/installers/requirements/PipInstaller.d.ts +1 -1
- package/dist/core/installers/requirements/RequirementInstaller.d.ts +1 -1
- package/dist/core/loaders/ConfigurationLoader.d.ts +32 -0
- package/dist/core/loaders/ConfigurationLoader.js +236 -0
- package/dist/core/loaders/ConfigurationProvider.d.ts +35 -0
- package/dist/core/loaders/ConfigurationProvider.js +375 -0
- package/dist/core/loaders/ServerSchemaLoader.d.ts +11 -0
- package/{src/core/ServerSchemaLoader.ts → dist/core/loaders/ServerSchemaLoader.js} +43 -48
- package/dist/core/loaders/ServerSchemaProvider.d.ts +17 -0
- package/{src/core/ServerSchemaProvider.ts → dist/core/loaders/ServerSchemaProvider.js} +120 -137
- package/dist/core/metadatas/constants.d.ts +47 -0
- package/dist/core/metadatas/constants.js +94 -0
- package/dist/core/metadatas/types.d.ts +166 -0
- package/dist/core/metadatas/types.js +16 -0
- package/dist/core/onboard/FeedOnboardService.d.ts +1 -1
- package/dist/core/onboard/FeedOnboardService.js +1 -1
- package/dist/core/onboard/OnboardProcessor.d.ts +1 -1
- package/dist/core/onboard/OnboardProcessor.js +1 -1
- package/dist/core/onboard/OnboardStatus.d.ts +1 -1
- package/dist/core/onboard/OnboardStatusManager.d.ts +1 -1
- package/dist/core/onboard/OnboardStatusManager.js +1 -1
- package/dist/core/validators/FeedValidator.d.ts +1 -1
- package/dist/core/validators/IServerValidator.d.ts +1 -1
- package/dist/core/validators/SSEServerValidator.d.ts +1 -1
- package/dist/core/validators/ServerValidatorFactory.d.ts +1 -1
- package/dist/core/validators/StdioServerValidator.d.ts +1 -1
- package/dist/core/validators/StdioServerValidator.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/services/InstallationService.d.ts +50 -0
- package/dist/services/InstallationService.js +350 -0
- package/dist/services/MCPManager.d.ts +28 -0
- package/dist/services/MCPManager.js +188 -0
- package/dist/services/RequirementService.d.ts +40 -0
- package/dist/services/RequirementService.js +110 -0
- package/dist/services/ServerService.d.ts +2 -2
- package/dist/services/ServerService.js +5 -5
- package/dist/utils/adoUtils.d.ts +2 -2
- package/dist/utils/adoUtils.js +1 -1
- package/dist/utils/feedUtils.js +1 -1
- package/dist/utils/githubUtils.d.ts +1 -1
- package/dist/utils/githubUtils.js +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/macroExpressionUtils.d.ts +1 -1
- package/dist/utils/osUtils.d.ts +1 -1
- package/dist/utils/osUtils.js +1 -1
- package/dist/web/contract/serverContract.d.ts +1 -1
- package/dist/web/public/index.html +1 -3
- package/dist/web/public/js/api.js +2 -80
- package/dist/web/server.js +2 -2
- package/package.json +1 -1
- package/src/cli/commands/install.ts +3 -3
- package/src/cli/commands/list.ts +2 -2
- package/src/cli/commands/serve.ts +3 -2
- package/src/cli/index.ts +1 -1
- package/src/core/installers/clients/BaseClientInstaller.ts +134 -3
- package/src/core/installers/clients/ClientInstaller.ts +3 -3
- package/src/core/installers/clients/ClientInstallerFactory.ts +1 -1
- package/src/core/installers/clients/ClineInstaller.ts +1 -101
- package/src/core/installers/clients/ExtensionInstaller.ts +1 -1
- package/src/core/installers/clients/GithubCopilotInstaller.ts +1 -101
- package/src/core/installers/clients/MSRooCodeInstaller.ts +1 -102
- package/src/core/installers/requirements/BaseInstaller.ts +2 -2
- package/src/core/installers/requirements/CommandInstaller.ts +1 -1
- package/src/core/installers/requirements/GeneralInstaller.ts +1 -1
- package/src/core/installers/requirements/InstallerFactory.ts +1 -1
- package/src/core/installers/requirements/NpmInstaller.ts +12 -12
- package/src/core/installers/requirements/PipInstaller.ts +1 -1
- package/src/core/installers/requirements/RequirementInstaller.ts +1 -1
- package/src/core/{ConfigurationLoader.ts → loaders/ConfigurationLoader.ts} +31 -7
- package/src/core/{ConfigurationProvider.ts → loaders/ConfigurationProvider.ts} +18 -10
- package/src/core/loaders/ServerSchemaLoader.ts +117 -0
- package/src/core/loaders/ServerSchemaProvider.ts +99 -0
- package/src/core/{types.ts → metadatas/types.ts} +3 -2
- package/src/core/onboard/FeedOnboardService.ts +270 -146
- package/src/core/onboard/OnboardProcessor.ts +60 -11
- package/src/core/onboard/OnboardStatus.ts +7 -2
- package/src/core/onboard/OnboardStatusManager.ts +270 -43
- package/src/core/validators/FeedValidator.ts +65 -9
- package/src/core/validators/IServerValidator.ts +1 -1
- package/src/core/validators/SSEServerValidator.ts +2 -2
- package/src/core/validators/ServerValidatorFactory.ts +1 -1
- package/src/core/validators/StdioServerValidator.ts +86 -34
- package/src/index.ts +3 -3
- package/src/{core → services}/InstallationService.ts +5 -5
- package/src/{core → services}/MCPManager.ts +10 -5
- package/src/{core → services}/RequirementService.ts +2 -31
- package/src/services/ServerService.ts +7 -7
- package/src/utils/adoUtils.ts +3 -3
- package/src/utils/feedUtils.ts +2 -2
- package/src/utils/githubUtils.ts +2 -2
- package/src/utils/logger.ts +13 -1
- package/src/utils/macroExpressionUtils.ts +1 -1
- package/src/utils/osUtils.ts +4 -4
- package/src/web/contract/serverContract.ts +2 -2
- package/src/web/public/index.html +1 -3
- package/src/web/public/js/api.js +2 -80
- package/src/web/public/js/modal/installation.js +1 -1
- package/src/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +41 -9
- package/src/web/public/js/onboard/formProcessor.js +200 -34
- package/src/web/public/js/onboard/index.js +2 -2
- package/src/web/public/js/onboard/publishHandler.js +30 -22
- package/src/web/public/js/onboard/templates.js +34 -40
- package/src/web/public/js/onboard/uiHandlers.js +175 -84
- package/src/web/public/js/onboard/validationHandlers.js +147 -64
- package/src/web/public/js/serverCategoryDetails.js +19 -4
- package/src/web/public/js/serverCategoryList.js +13 -1
- package/src/web/public/onboard.html +1 -1
- package/src/web/server.ts +30 -14
- package/src/services/InstallRequestValidator.ts +0 -112
- /package/src/core/{constants.ts → metadatas/constants.ts} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../core/metadatas/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service responsible for managing requirements installation and status
|
|
4
|
+
*/
|
|
5
|
+
export declare class RequirementService {
|
|
6
|
+
private static instance;
|
|
7
|
+
private installerFactory;
|
|
8
|
+
private constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Get the singleton instance of RequirementService
|
|
11
|
+
* @returns The RequirementService instance
|
|
12
|
+
*/
|
|
13
|
+
static getInstance(): RequirementService;
|
|
14
|
+
/**
|
|
15
|
+
* Check the installation status of a requirement
|
|
16
|
+
* @param requirement The requirement to check
|
|
17
|
+
* @returns The installation status
|
|
18
|
+
*/
|
|
19
|
+
checkRequirementStatus(requirement: RequirementConfig, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
20
|
+
/**
|
|
21
|
+
* Check if updates are available for a requirement
|
|
22
|
+
* @param requirement The requirement to check for updates
|
|
23
|
+
* @returns Updated status with available updates information
|
|
24
|
+
*/
|
|
25
|
+
checkRequirementForUpdates(requirement: RequirementConfig, currentStatus: RequirementStatus): Promise<RequirementStatus>;
|
|
26
|
+
/**
|
|
27
|
+
* Update a requirement to a new version
|
|
28
|
+
* @param requirement The requirement configuration
|
|
29
|
+
* @param updateVersion The version to update to
|
|
30
|
+
* @returns The updated requirement status
|
|
31
|
+
*/
|
|
32
|
+
updateRequirement(requirement: RequirementConfig, updateVersion: string, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
33
|
+
/**
|
|
34
|
+
* Validate a requirement configuration
|
|
35
|
+
* @param requirement The requirement to validate
|
|
36
|
+
* @throws Error if the requirement is invalid
|
|
37
|
+
*/
|
|
38
|
+
private validateRequirement;
|
|
39
|
+
}
|
|
40
|
+
export declare const requirementService: RequirementService;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createInstallerFactory } from '../core/installers/index.js';
|
|
2
|
+
import { exec } from 'child_process';
|
|
3
|
+
import util from 'util';
|
|
4
|
+
/**
|
|
5
|
+
* Service responsible for managing requirements installation and status
|
|
6
|
+
*/
|
|
7
|
+
export class RequirementService {
|
|
8
|
+
static instance;
|
|
9
|
+
installerFactory = createInstallerFactory(util.promisify(exec));
|
|
10
|
+
constructor() { }
|
|
11
|
+
/**
|
|
12
|
+
* Get the singleton instance of RequirementService
|
|
13
|
+
* @returns The RequirementService instance
|
|
14
|
+
*/
|
|
15
|
+
static getInstance() {
|
|
16
|
+
if (!RequirementService.instance) {
|
|
17
|
+
RequirementService.instance = new RequirementService();
|
|
18
|
+
}
|
|
19
|
+
return RequirementService.instance;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check the installation status of a requirement
|
|
23
|
+
* @param requirement The requirement to check
|
|
24
|
+
* @returns The installation status
|
|
25
|
+
*/
|
|
26
|
+
async checkRequirementStatus(requirement, options) {
|
|
27
|
+
// Validate requirement
|
|
28
|
+
this.validateRequirement(requirement);
|
|
29
|
+
// Check the installation status
|
|
30
|
+
return await this.installerFactory.checkInstallation(requirement, options);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if updates are available for a requirement
|
|
34
|
+
* @param requirement The requirement to check for updates
|
|
35
|
+
* @returns Updated status with available updates information
|
|
36
|
+
*/
|
|
37
|
+
async checkRequirementForUpdates(requirement, currentStatus) {
|
|
38
|
+
// Validate requirement
|
|
39
|
+
this.validateRequirement(requirement);
|
|
40
|
+
// Get current status
|
|
41
|
+
// Check for updates using the appropriate installer
|
|
42
|
+
const installer = this.installerFactory.getInstaller(requirement);
|
|
43
|
+
if (!installer || !installer.supportCheckUpdates()) {
|
|
44
|
+
return currentStatus;
|
|
45
|
+
}
|
|
46
|
+
// Pass pythonEnv from currentStatus if it exists for pip packages
|
|
47
|
+
const options = requirement.type === 'pip' && currentStatus.pythonEnv
|
|
48
|
+
? { settings: { pythonEnv: currentStatus.pythonEnv } }
|
|
49
|
+
: undefined;
|
|
50
|
+
const status = await this.checkRequirementStatus(requirement, options);
|
|
51
|
+
return await installer.checkForUpdates(requirement, status);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Update a requirement to a new version
|
|
55
|
+
* @param requirement The requirement configuration
|
|
56
|
+
* @param updateVersion The version to update to
|
|
57
|
+
* @returns The updated requirement status
|
|
58
|
+
*/
|
|
59
|
+
async updateRequirement(requirement, updateVersion, options) {
|
|
60
|
+
// Validate requirement
|
|
61
|
+
this.validateRequirement(requirement);
|
|
62
|
+
// Create an updated requirement with the new version
|
|
63
|
+
const updatedRequirement = {
|
|
64
|
+
...requirement,
|
|
65
|
+
version: requirement.version.includes('latest') ? requirement.version : updateVersion,
|
|
66
|
+
};
|
|
67
|
+
// Install the updated version
|
|
68
|
+
return await this.installerFactory.install(updatedRequirement, options);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validate a requirement configuration
|
|
72
|
+
* @param requirement The requirement to validate
|
|
73
|
+
* @throws Error if the requirement is invalid
|
|
74
|
+
*/
|
|
75
|
+
validateRequirement(requirement) {
|
|
76
|
+
// Ensure requirement has required fields
|
|
77
|
+
if (!requirement.name) {
|
|
78
|
+
throw new Error('Requirement name is required');
|
|
79
|
+
}
|
|
80
|
+
if (!requirement.type) {
|
|
81
|
+
throw new Error('Requirement type is required');
|
|
82
|
+
}
|
|
83
|
+
// For type 'other', registry must be specified
|
|
84
|
+
if (requirement.type === 'other' && !requirement.registry) {
|
|
85
|
+
throw new Error('Registry must be specified for requirement type "other"');
|
|
86
|
+
}
|
|
87
|
+
// Validate registry configuration if provided
|
|
88
|
+
if (requirement.registry) {
|
|
89
|
+
const { githubRelease, artifacts } = requirement.registry;
|
|
90
|
+
// Validate GitHub release configuration
|
|
91
|
+
if (githubRelease) {
|
|
92
|
+
if (!githubRelease.repository) {
|
|
93
|
+
throw new Error('Repository is required for GitHub release registry');
|
|
94
|
+
}
|
|
95
|
+
if (!githubRelease.assetName) {
|
|
96
|
+
throw new Error('Asset name is required for GitHub release registry');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Validate artifacts registry configuration
|
|
100
|
+
if (artifacts) {
|
|
101
|
+
if (!artifacts.registryUrl) {
|
|
102
|
+
throw new Error('Registry URL is required for artifacts registry');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Export a singleton instance
|
|
109
|
+
export const requirementService = RequirementService.getInstance();
|
|
110
|
+
//# sourceMappingURL=RequirementService.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ServerSchema } from '../core/ServerSchemaProvider.js';
|
|
2
|
-
import { MCPServerCategory, ServerInstallOptions, ServerCategoryListOptions, ServerOperationResult, ServerUninstallOptions, FeedConfiguration } from '../core/types.js';
|
|
1
|
+
import { ServerSchema } from '../core/loaders/ServerSchemaProvider.js';
|
|
2
|
+
import { MCPServerCategory, ServerInstallOptions, ServerCategoryListOptions, ServerOperationResult, ServerUninstallOptions, FeedConfiguration } from '../core/metadatas/types.js';
|
|
3
3
|
import { OperationStatus } from '../core/onboard/OnboardStatus.js';
|
|
4
4
|
/**
|
|
5
5
|
* ServerService provides a unified interface for server management operations.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
3
|
import { Logger } from '../utils/logger.js';
|
|
4
|
-
import { getServerSchemaProvider } from '../core/ServerSchemaProvider.js';
|
|
5
|
-
import { mcpManager } from '
|
|
6
|
-
import { UPDATE_CHECK_INTERVAL_MS } from '../core/constants.js';
|
|
4
|
+
import { getServerSchemaProvider } from '../core/loaders/ServerSchemaProvider.js';
|
|
5
|
+
import { mcpManager } from './MCPManager.js';
|
|
6
|
+
import { UPDATE_CHECK_INTERVAL_MS } from '../core/metadatas/constants.js';
|
|
7
7
|
import { updateCheckTracker } from '../utils/UpdateCheckTracker.js';
|
|
8
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
/**
|
|
@@ -53,8 +53,8 @@ export class ServerService {
|
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
try {
|
|
56
|
-
const { requirementService } = await import('
|
|
57
|
-
const { configProvider } = await import('../core/ConfigurationProvider.js');
|
|
56
|
+
const { requirementService } = await import('./RequirementService.js');
|
|
57
|
+
const { configProvider } = await import('../core/loaders/ConfigurationProvider.js');
|
|
58
58
|
for (const requirement of serverCategory.feedConfiguration.requirements) {
|
|
59
59
|
if (requirement.version.includes('latest')) {
|
|
60
60
|
// Get current status if available
|
package/dist/utils/adoUtils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequirementConfig, RegistryConfig } from '../core/types.js';
|
|
1
|
+
import { RequirementConfig, RegistryConfig } from '../core/metadatas/types.js';
|
|
2
2
|
export interface AdoArtifactResult {
|
|
3
3
|
type: 'npm' | 'pip';
|
|
4
4
|
package: string;
|
|
@@ -25,5 +25,5 @@ targetDir?: string): Promise<AdoArtifactResult>;
|
|
|
25
25
|
* @param options Optional server install options (e.g., for pythonCommand).
|
|
26
26
|
* @returns The latest version string, or undefined if not found or an error occurs.
|
|
27
27
|
*/
|
|
28
|
-
export declare function getArtifactLatestVersion(requirement: RequirementConfig, registry: RegistryConfig['artifacts'], options?: import('../core/types.js').ServerInstallOptions, // Added import for ServerInstallOptions
|
|
28
|
+
export declare function getArtifactLatestVersion(requirement: RequirementConfig, registry: RegistryConfig['artifacts'], options?: import('../core/metadatas/types.js').ServerInstallOptions, // Added import for ServerInstallOptions
|
|
29
29
|
targetDir?: string): Promise<string | undefined>;
|
package/dist/utils/adoUtils.js
CHANGED
package/dist/utils/feedUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import { Logger } from './logger.js';
|
|
3
|
-
import { LOCAL_FEEDS_DIR } from '../core/constants.js';
|
|
3
|
+
import { LOCAL_FEEDS_DIR } from '../core/metadatas/constants.js';
|
|
4
4
|
/**
|
|
5
5
|
* Checks if local feeds exist in the LOCAL_FEEDS_DIR
|
|
6
6
|
* Returns true if the directory exists and contains at least one .json file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RegistryConfig, RequirementConfig } from '../core/types.js';
|
|
1
|
+
import { RegistryConfig, RequirementConfig } from '../core/metadatas/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Get the latest version available for a GitHub repository
|
|
4
4
|
* @param execPromise The promise-based exec function
|
|
@@ -3,7 +3,7 @@ import util from 'util';
|
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { extractZipFile } from './clientUtils.js';
|
|
6
|
-
import { SETTINGS_DIR } from '../core/constants.js';
|
|
6
|
+
import { SETTINGS_DIR } from '../core/metadatas/constants.js';
|
|
7
7
|
const execAsync = util.promisify(exec);
|
|
8
8
|
/**
|
|
9
9
|
* Get the latest version available for a GitHub repository
|
package/dist/utils/logger.js
CHANGED
package/dist/utils/osUtils.d.ts
CHANGED
package/dist/utils/osUtils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DependencyConfig, RegistryConfig, ServerInstallOptions } from '../../core/types.js';
|
|
1
|
+
import { DependencyConfig, RegistryConfig, ServerInstallOptions } from '../../core/metadatas/types.js';
|
|
2
2
|
export interface OnboardServerConfig {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
|
|
168
168
|
<!-- Module scripts -->
|
|
169
169
|
<script type="module">
|
|
170
|
-
import { fetchServerCategories, handleInstallServer,
|
|
170
|
+
import { fetchServerCategories, handleInstallServer, uninstallTool } from './js/api.js';
|
|
171
171
|
import { setupSearch } from './js/serverCategoryList.js';
|
|
172
172
|
import { showServerDetails } from './js/serverCategoryDetails.js';
|
|
173
173
|
import { showInstallModal, closeModal, setupModalOutsideClick } from './js/modal.js';
|
|
@@ -182,8 +182,6 @@
|
|
|
182
182
|
// If other parts of the app call window.showOnboardModal, they'll need updating too.
|
|
183
183
|
window.closeModal = closeModal;
|
|
184
184
|
window.handleInstallServer = handleInstallServer;
|
|
185
|
-
window.installRequirement = installRequirement;
|
|
186
|
-
window.upgradeRequirement = upgradeRequirement;
|
|
187
185
|
window.uninstallTool = uninstallTool;
|
|
188
186
|
|
|
189
187
|
// Initialize
|
|
@@ -42,7 +42,7 @@ async function fetchServerCategories() {
|
|
|
42
42
|
async function handleInstallServer(event, categoryName, serverName, callback, options = {}) {
|
|
43
43
|
event.preventDefault(); // Prevent page reload
|
|
44
44
|
console.log("Handling install for:", categoryName, serverName);
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
// Get selected targets from the form if not provided in options
|
|
47
47
|
const selectedTargets = options.targets || [...document.querySelectorAll('input[name="targets"]:checked')]
|
|
48
48
|
.map(cb => cb.value);
|
|
@@ -71,7 +71,7 @@ async function handleInstallServer(event, categoryName, serverName, callback, op
|
|
|
71
71
|
const response = await fetch(`/api/categories/${categoryName}/install`, {
|
|
72
72
|
method: 'POST',
|
|
73
73
|
headers: { 'Content-Type': 'application/json' },
|
|
74
|
-
body: JSON.stringify({serverList: serverList})
|
|
74
|
+
body: JSON.stringify({ serverList: serverList })
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
if (!response.ok) {
|
|
@@ -90,82 +90,6 @@ async function handleInstallServer(event, categoryName, serverName, callback, op
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// Install requirement handler
|
|
94
|
-
async function installRequirement(reqName) {
|
|
95
|
-
const detailsDiv = document.getElementById('serverCategoryDetails');
|
|
96
|
-
const serverTitle = detailsDiv.querySelector('h3');
|
|
97
|
-
if (!serverTitle) {
|
|
98
|
-
showToast('No server selected.', 'error');
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
let serverName = serverTitle.textContent;
|
|
102
|
-
if (serverName.includes(' for ')) {
|
|
103
|
-
serverName = serverName.split(' for ')[0];
|
|
104
|
-
}
|
|
105
|
-
const confirmed = await showConfirm(`Do you want to install requirement '${reqName}' for ${serverName}?`);
|
|
106
|
-
if (!confirmed) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const btn = Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'Install' && b.onclick?.toString().includes(reqName));
|
|
111
|
-
if (btn) btn.disabled = true;
|
|
112
|
-
|
|
113
|
-
try {
|
|
114
|
-
const response = await fetch(`/api/categories/${serverName}/install-requirement`, {
|
|
115
|
-
method: 'POST',
|
|
116
|
-
headers: { 'Content-Type': 'application/json' },
|
|
117
|
-
body: JSON.stringify({ requirementName: reqName })
|
|
118
|
-
});
|
|
119
|
-
if (!response.ok) {
|
|
120
|
-
const errorData = await response.text();
|
|
121
|
-
throw new Error(`Installation failed: ${errorData || response.statusText}`);
|
|
122
|
-
}
|
|
123
|
-
showToast(`Requirement '${reqName}' installation initiated successfully!`, 'success');
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
fetchServerCategories();
|
|
126
|
-
window.showServerDetails(serverName);
|
|
127
|
-
}, 1000);
|
|
128
|
-
} catch (error) {
|
|
129
|
-
console.error('Error installing requirement:', error);
|
|
130
|
-
showToast(`Error installing requirement: ${error.message}. Please check console.`, 'error');
|
|
131
|
-
} finally {
|
|
132
|
-
if (btn) btn.disabled = false;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Handle upgrade/uninstall actions
|
|
137
|
-
async function upgradeRequirement(name) {
|
|
138
|
-
const serverTitle = document.querySelector('#serverCategoryDetails h3')?.textContent;
|
|
139
|
-
if (!serverTitle) {
|
|
140
|
-
showToast('No server selected.', 'error');
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const upgradeConfirmed = await showConfirm(`Do you want to upgrade requirement '${name}' for ${serverTitle}?`);
|
|
145
|
-
if (!upgradeConfirmed) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
const response = await fetch(`/api/categories/${serverTitle}/upgrade-requirement`, {
|
|
151
|
-
method: 'POST',
|
|
152
|
-
headers: { 'Content-Type': 'application/json' },
|
|
153
|
-
body: JSON.stringify({ requirementName: name })
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
if (!response.ok) {
|
|
157
|
-
const errorData = await response.text();
|
|
158
|
-
throw new Error(`Upgrade failed: ${errorData || response.statusText}`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
showToast(`Requirement '${name}' upgrade initiated successfully!`, 'success');
|
|
162
|
-
fetchServerCategories();
|
|
163
|
-
window.showServerDetails(serverTitle);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error('Error upgrading requirement:', error);
|
|
166
|
-
showToast(`Error upgrading requirement: ${error.message}`, 'error');
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
93
|
|
|
170
94
|
async function uninstallTool(name) {
|
|
171
95
|
const serverTitle = document.querySelector('#serverCategoryDetails h3')?.textContent;
|
|
@@ -204,7 +128,5 @@ export {
|
|
|
204
128
|
allServerCategoriesData,
|
|
205
129
|
fetchServerCategories,
|
|
206
130
|
handleInstallServer,
|
|
207
|
-
installRequirement,
|
|
208
|
-
upgradeRequirement,
|
|
209
131
|
uninstallTool
|
|
210
132
|
};
|
package/dist/web/server.js
CHANGED
|
@@ -2,12 +2,12 @@ import express from 'express';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { OnboardingProcessStatus } from '../core/onboard/OnboardStatus.js';
|
|
5
|
-
import { SUPPORTED_CLIENT_NAMES } from '../core/constants.js';
|
|
5
|
+
import { SUPPORTED_CLIENT_NAMES } from '../core/metadatas/constants.js';
|
|
6
6
|
import { serverService } from '../services/ServerService.js';
|
|
7
7
|
import { feedOnboardService } from '../core/onboard/FeedOnboardService.js';
|
|
8
8
|
import { openBrowser } from '../utils/osUtils.js';
|
|
9
9
|
import { Logger } from '../utils/logger.js';
|
|
10
|
-
import { configProvider } from '../core/ConfigurationProvider.js';
|
|
10
|
+
import { configProvider } from '../core/loaders/ConfigurationProvider.js';
|
|
11
11
|
import { onboardStatusManager } from '../core/onboard/OnboardStatusManager.js';
|
|
12
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
13
|
const app = express();
|
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { serverService } from '../../services/ServerService.js';
|
|
3
3
|
import { Logger } from '../../utils/logger.js';
|
|
4
4
|
import { hasLocalFeeds } from '../../utils/feedUtils.js';
|
|
5
|
-
import { ServerInstallOptions } from '../../core/types.js';
|
|
6
|
-
import { SUPPORTED_CLIENT_NAMES } from '../../core/constants.js';
|
|
7
|
-
import { mcpManager } from '../../
|
|
5
|
+
import { ServerInstallOptions } from '../../core/metadatas/types.js';
|
|
6
|
+
import { SUPPORTED_CLIENT_NAMES } from '../../core/metadatas/constants.js';
|
|
7
|
+
import { mcpManager } from '../../services/MCPManager.js';
|
|
8
8
|
|
|
9
9
|
export function createInstallCommand(): Command {
|
|
10
10
|
return new Command('install')
|
package/src/cli/commands/list.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { LOCAL_FEEDS_DIR } from '../../core/constants.js';
|
|
5
|
-
import { mcpManager } from '../../
|
|
4
|
+
import { LOCAL_FEEDS_DIR } from '../../core/metadatas/constants.js';
|
|
5
|
+
import { mcpManager } from '../../services/MCPManager.js';
|
|
6
6
|
import { Logger } from '../../utils/logger.js';
|
|
7
7
|
|
|
8
8
|
interface SimplifiedServer {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { startWebServer } from '../../web/server.js';
|
|
3
|
-
import { mcpManager } from '../../
|
|
3
|
+
import { mcpManager } from '../../services/MCPManager.js';
|
|
4
4
|
import { checkGithubAuth } from '../../utils/githubAuth.js';
|
|
5
5
|
import { Logger } from '../../utils/logger.js';
|
|
6
6
|
|
|
@@ -9,13 +9,14 @@ export function createServeCommand(): Command {
|
|
|
9
9
|
.description('Serve local web interface')
|
|
10
10
|
.option('-p, --port <port>', 'Port to run the server on', '3000')
|
|
11
11
|
.option('-f, --feed-file <filepath>', 'Path to a custom feed configuration file')
|
|
12
|
+
.option('-s, --schemas-directory <path>', 'Path to a directory containing adhoc schema files')
|
|
12
13
|
.action(async (options) => {
|
|
13
14
|
try {
|
|
14
15
|
// Sync feeds before start the local UI
|
|
15
16
|
await mcpManager.syncFeeds();
|
|
16
17
|
|
|
17
18
|
// Ensure MCP manager is initialized before starting the web server
|
|
18
|
-
await mcpManager.initialize(options.feedFile);
|
|
19
|
+
await mcpManager.initialize(options.feedFile, options.schemasDirectory);
|
|
19
20
|
|
|
20
21
|
const port = parseInt(options.port, 10);
|
|
21
22
|
if (isNaN(port) || port < 1 || port > 65535) {
|
package/src/cli/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { createListCommand } from './commands/list.js';
|
|
|
6
6
|
import { createInstallCommand } from './commands/install.js';
|
|
7
7
|
import { createUninstallCommand } from './commands/uninstall.js';
|
|
8
8
|
import { createPullCommand } from './commands/pull.js';
|
|
9
|
-
import { mcpManager } from '../
|
|
9
|
+
import { mcpManager } from '../services/MCPManager.js';
|
|
10
10
|
import { Logger } from '../utils/logger.js';
|
|
11
11
|
import axios from 'axios';
|
|
12
12
|
import path from 'path';
|
|
@@ -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
|
-
*
|
|
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
|
}
|