imcp 0.1.6 → 0.1.8-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/install.js +1 -106
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/list.js +1 -90
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/pull.js +1 -16
- package/dist/cli/commands/pull.js.map +1 -0
- package/dist/cli/commands/serve.js +1 -33
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/uninstall.js +1 -46
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/index.js +1 -65
- package/dist/cli/index.js.map +1 -0
- package/dist/core/installers/clients/BaseClientInstaller.js +1 -282
- package/dist/core/installers/clients/BaseClientInstaller.js.map +1 -0
- package/dist/core/installers/clients/ClientInstaller.js +1 -163
- package/dist/core/installers/clients/ClientInstaller.js.map +1 -0
- package/dist/core/installers/clients/ClientInstallerFactory.js +1 -36
- package/dist/core/installers/clients/ClientInstallerFactory.js.map +1 -0
- package/dist/core/installers/clients/ClineInstaller.js +1 -30
- package/dist/core/installers/clients/ClineInstaller.js.map +1 -0
- package/dist/core/installers/clients/ExtensionInstaller.js +1 -151
- package/dist/core/installers/clients/ExtensionInstaller.js.map +1 -0
- package/dist/core/installers/clients/GithubCopilotInstaller.js +1 -68
- package/dist/core/installers/clients/GithubCopilotInstaller.js.map +1 -0
- package/dist/core/installers/clients/MSRooCodeInstaller.js +1 -28
- package/dist/core/installers/clients/MSRooCodeInstaller.js.map +1 -0
- package/dist/core/installers/index.js +1 -8
- package/dist/core/installers/index.js.map +1 -0
- package/dist/core/installers/requirements/BaseInstaller.js +1 -56
- package/dist/core/installers/requirements/BaseInstaller.js.map +1 -0
- package/dist/core/installers/requirements/CommandInstaller.js +1 -213
- package/dist/core/installers/requirements/CommandInstaller.js.map +1 -0
- package/dist/core/installers/requirements/GeneralInstaller.js +1 -126
- package/dist/core/installers/requirements/GeneralInstaller.js.map +1 -0
- package/dist/core/installers/requirements/InstallerFactory.js +1 -99
- package/dist/core/installers/requirements/InstallerFactory.js.map +1 -0
- package/dist/core/installers/requirements/NpmInstaller.js +1 -235
- package/dist/core/installers/requirements/NpmInstaller.js.map +1 -0
- package/dist/core/installers/requirements/NugetInstaller.js +1 -188
- package/dist/core/installers/requirements/NugetInstaller.js.map +1 -0
- package/dist/core/installers/requirements/PipInstaller.js +1 -192
- package/dist/core/installers/requirements/PipInstaller.js.map +1 -0
- package/dist/core/installers/requirements/RequirementInstaller.js +1 -2
- package/dist/core/installers/requirements/RequirementInstaller.js.map +1 -0
- package/dist/core/loaders/ConfigurationLoader.js +1 -256
- package/dist/core/loaders/ConfigurationLoader.js.map +1 -0
- package/dist/core/loaders/ConfigurationProvider.js +1 -383
- package/dist/core/loaders/ConfigurationProvider.js.map +1 -0
- package/dist/core/loaders/InstallOperationManager.js +1 -310
- package/dist/core/loaders/InstallOperationManager.js.map +1 -0
- package/dist/core/loaders/ServerSchemaLoader.js +1 -108
- package/dist/core/loaders/ServerSchemaLoader.js.map +1 -0
- package/dist/core/loaders/ServerSchemaProvider.js +1 -89
- package/dist/core/loaders/ServerSchemaProvider.js.map +1 -0
- package/dist/core/loaders/SystemSettingsManager.js +1 -256
- package/dist/core/loaders/SystemSettingsManager.js.map +1 -0
- package/dist/core/metadatas/constants.js +1 -100
- package/dist/core/metadatas/constants.js.map +1 -0
- package/dist/core/metadatas/recordingConstants.js +1 -46
- package/dist/core/metadatas/recordingConstants.js.map +1 -0
- package/dist/core/metadatas/types.js +1 -15
- package/dist/core/metadatas/types.js.map +1 -0
- package/dist/core/onboard/FeedOnboardService.js +1 -422
- package/dist/core/onboard/FeedOnboardService.js.map +1 -0
- package/dist/core/onboard/OnboardProcessor.js +1 -333
- package/dist/core/onboard/OnboardProcessor.js.map +1 -0
- package/dist/core/onboard/OnboardStatus.js +1 -9
- package/dist/core/onboard/OnboardStatus.js.map +1 -0
- package/dist/core/onboard/OnboardStatusManager.js +1 -360
- package/dist/core/onboard/OnboardStatusManager.js.map +1 -0
- package/dist/core/validators/FeedValidator.js +1 -133
- package/dist/core/validators/FeedValidator.js.map +1 -0
- package/dist/core/validators/IServerValidator.js +1 -1
- package/dist/core/validators/IServerValidator.js.map +1 -0
- package/dist/core/validators/SSEServerValidator.js +1 -38
- package/dist/core/validators/SSEServerValidator.js.map +1 -0
- package/dist/core/validators/ServerValidatorFactory.js +1 -44
- package/dist/core/validators/ServerValidatorFactory.js.map +1 -0
- package/dist/core/validators/StdioServerValidator.js +1 -281
- package/dist/core/validators/StdioServerValidator.js.map +1 -0
- package/dist/index.js +1 -18
- package/dist/index.js.map +1 -0
- package/dist/services/InstallationService.js +1 -81
- package/dist/services/InstallationService.js.map +1 -0
- package/dist/services/MCPManager.js +1 -197
- package/dist/services/MCPManager.js.map +1 -0
- package/dist/services/RequirementService.js +1 -548
- package/dist/services/RequirementService.js.map +1 -0
- package/dist/services/ServerService.js +1 -127
- package/dist/services/ServerService.js.map +1 -0
- package/dist/services/TelemetryService.js +1 -53
- package/dist/services/TelemetryService.js.map +1 -0
- package/dist/utils/UpdateCheckTracker.js +1 -79
- package/dist/utils/UpdateCheckTracker.js.map +1 -0
- package/dist/utils/adoUtils.js +1 -254
- package/dist/utils/adoUtils.js.map +1 -0
- package/dist/utils/clientUtils.js +1 -65
- package/dist/utils/clientUtils.js.map +1 -0
- package/dist/utils/feedUtils.js +1 -28
- package/dist/utils/feedUtils.js.map +1 -0
- package/dist/utils/githubAuth.js +1 -177
- package/dist/utils/githubAuth.js.map +1 -0
- package/dist/utils/githubUtils.js +1 -125
- package/dist/utils/githubUtils.js.map +1 -0
- package/dist/utils/logger.js +1 -176
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/macroExpressionUtils.js +1 -93
- package/dist/utils/macroExpressionUtils.js.map +1 -0
- package/dist/utils/osUtils.js +1 -664
- package/dist/utils/osUtils.js.map +1 -0
- package/dist/utils/versionUtils.js +1 -101
- package/dist/utils/versionUtils.js.map +1 -0
- package/dist/web/contract/serverContract.js +1 -1
- package/dist/web/contract/serverContract.js.map +1 -0
- package/dist/web/public/js/api.js +2 -132
- package/dist/web/public/js/api.js.map +1 -0
- package/dist/web/public/js/detailsWidget.js +2 -264
- package/dist/web/public/js/detailsWidget.js.map +1 -0
- package/dist/web/public/js/flights/flights.js +2 -127
- package/dist/web/public/js/flights/flights.js.map +1 -0
- package/dist/web/public/js/modal/index.js +2 -52
- package/dist/web/public/js/modal/index.js.map +1 -0
- package/dist/web/public/js/modal/installModal.js +2 -162
- package/dist/web/public/js/modal/installModal.js.map +1 -0
- package/dist/web/public/js/modal/installation.js +2 -266
- package/dist/web/public/js/modal/installation.js.map +1 -0
- package/dist/web/public/js/modal/loadingModal.js +2 -182
- package/dist/web/public/js/modal/loadingModal.js.map +1 -0
- package/dist/web/public/js/modal/modalSetup.js +2 -595
- package/dist/web/public/js/modal/modalSetup.js.map +1 -0
- package/dist/web/public/js/modal/modalUtils.js +2 -37
- package/dist/web/public/js/modal/modalUtils.js.map +1 -0
- package/dist/web/public/js/modal/versionUtils.js +2 -20
- package/dist/web/public/js/modal/versionUtils.js.map +1 -0
- package/dist/web/public/js/modal.js +2 -42
- package/dist/web/public/js/modal.js.map +1 -0
- package/dist/web/public/js/notifications.js +2 -137
- package/dist/web/public/js/notifications.js.map +1 -0
- package/dist/web/public/js/onboard/formProcessor.js +2 -1037
- package/dist/web/public/js/onboard/formProcessor.js.map +1 -0
- package/dist/web/public/js/onboard/index.js +2 -374
- package/dist/web/public/js/onboard/index.js.map +1 -0
- package/dist/web/public/js/onboard/publishHandler.js +2 -172
- package/dist/web/public/js/onboard/publishHandler.js.map +1 -0
- package/dist/web/public/js/onboard/state.js +2 -76
- package/dist/web/public/js/onboard/state.js.map +1 -0
- package/dist/web/public/js/onboard/templates.js +2 -342
- package/dist/web/public/js/onboard/templates.js.map +1 -0
- package/dist/web/public/js/onboard/uiHandlers.js +2 -1076
- package/dist/web/public/js/onboard/uiHandlers.js.map +1 -0
- package/dist/web/public/js/onboard/validationHandlers.js +2 -493
- package/dist/web/public/js/onboard/validationHandlers.js.map +1 -0
- package/dist/web/public/js/serverCategoryDetails.js +2 -364
- package/dist/web/public/js/serverCategoryDetails.js.map +1 -0
- package/dist/web/public/js/serverCategoryList.js +2 -241
- package/dist/web/public/js/serverCategoryList.js.map +1 -0
- package/dist/web/public/js/settings.js +2 -314
- package/dist/web/public/js/settings.js.map +1 -0
- package/dist/web/server.js +1 -404
- package/dist/web/server.js.map +1 -0
- package/package.json +8 -2
- package/.github/ISSUE_TEMPLATE/JitAccess.yml +0 -28
- package/.github/acl/access.yml +0 -20
- package/.github/compliance/inventory.yml +0 -5
- package/.github/policies/jit.yml +0 -19
- package/.github/workflows/build.yml +0 -28
- package/.roo/rules-code/rules.md +0 -88
- package/dist/cli/commands/start.d.ts +0 -2
- package/dist/cli/commands/start.js +0 -32
- package/dist/cli/commands/sync.d.ts +0 -2
- package/dist/cli/commands/sync.js +0 -17
- package/dist/core/ConfigurationLoader.d.ts +0 -32
- package/dist/core/ConfigurationLoader.js +0 -236
- package/dist/core/ConfigurationProvider.d.ts +0 -35
- package/dist/core/ConfigurationProvider.js +0 -375
- package/dist/core/InstallationService.d.ts +0 -50
- package/dist/core/InstallationService.js +0 -350
- package/dist/core/MCPManager.d.ts +0 -28
- package/dist/core/MCPManager.js +0 -188
- package/dist/core/RequirementService.d.ts +0 -40
- package/dist/core/RequirementService.js +0 -110
- package/dist/core/ServerSchemaLoader.d.ts +0 -11
- package/dist/core/ServerSchemaLoader.js +0 -43
- package/dist/core/ServerSchemaProvider.d.ts +0 -17
- package/dist/core/ServerSchemaProvider.js +0 -120
- package/dist/core/constants.d.ts +0 -47
- package/dist/core/constants.js +0 -94
- package/dist/core/installers/BaseInstaller.d.ts +0 -74
- package/dist/core/installers/BaseInstaller.js +0 -253
- package/dist/core/installers/ClientInstaller.d.ts +0 -23
- package/dist/core/installers/ClientInstaller.js +0 -564
- package/dist/core/installers/CommandInstaller.d.ts +0 -37
- package/dist/core/installers/CommandInstaller.js +0 -173
- package/dist/core/installers/GeneralInstaller.d.ts +0 -33
- package/dist/core/installers/GeneralInstaller.js +0 -85
- package/dist/core/installers/InstallerFactory.d.ts +0 -54
- package/dist/core/installers/InstallerFactory.js +0 -97
- package/dist/core/installers/NpmInstaller.d.ts +0 -26
- package/dist/core/installers/NpmInstaller.js +0 -127
- package/dist/core/installers/PipInstaller.d.ts +0 -28
- package/dist/core/installers/PipInstaller.js +0 -127
- package/dist/core/installers/RequirementInstaller.d.ts +0 -33
- package/dist/core/installers/RequirementInstaller.js +0 -3
- package/dist/core/types.d.ts +0 -166
- package/dist/core/types.js +0 -16
- package/dist/services/InstallRequestValidator.d.ts +0 -21
- package/dist/services/InstallRequestValidator.js +0 -99
- package/dist/web/public/js/modal/installHandler.js +0 -227
- package/dist/web/public/js/modal/loadingUI.js +0 -74
- package/dist/web/public/js/modal/messageQueue.js +0 -112
- package/dist/web/public/js/modal/modalUI.js +0 -214
- package/dist/web/public/js/modal/version.js +0 -20
- package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +0 -370
- package/docs/ONBOARDING_PAGE_DESIGN.md +0 -260
- package/docs/Telemetry.md +0 -136
- package/memory-bank/activeContext.md +0 -26
- package/memory-bank/decisionLog.md +0 -91
- package/memory-bank/productContext.md +0 -41
- package/memory-bank/progress.md +0 -35
- package/memory-bank/systemPatterns.md +0 -10
- package/src/cli/commands/install.ts +0 -139
- package/src/cli/commands/list.ts +0 -113
- package/src/cli/commands/pull.ts +0 -16
- package/src/cli/commands/serve.ts +0 -39
- package/src/cli/commands/uninstall.ts +0 -64
- package/src/cli/index.ts +0 -82
- package/src/core/installers/clients/BaseClientInstaller.ts +0 -341
- package/src/core/installers/clients/ClientInstaller.ts +0 -222
- package/src/core/installers/clients/ClientInstallerFactory.ts +0 -43
- package/src/core/installers/clients/ClineInstaller.ts +0 -35
- package/src/core/installers/clients/ExtensionInstaller.ts +0 -165
- package/src/core/installers/clients/GithubCopilotInstaller.ts +0 -79
- package/src/core/installers/clients/MSRooCodeInstaller.ts +0 -32
- package/src/core/installers/index.ts +0 -11
- package/src/core/installers/requirements/BaseInstaller.ts +0 -85
- package/src/core/installers/requirements/CommandInstaller.ts +0 -231
- package/src/core/installers/requirements/GeneralInstaller.ts +0 -133
- package/src/core/installers/requirements/InstallerFactory.ts +0 -114
- package/src/core/installers/requirements/NpmInstaller.ts +0 -271
- package/src/core/installers/requirements/NugetInstaller.ts +0 -203
- package/src/core/installers/requirements/PipInstaller.ts +0 -207
- package/src/core/installers/requirements/RequirementInstaller.ts +0 -42
- package/src/core/loaders/ConfigurationLoader.ts +0 -298
- package/src/core/loaders/ConfigurationProvider.ts +0 -462
- package/src/core/loaders/InstallOperationManager.ts +0 -367
- package/src/core/loaders/ServerSchemaLoader.ts +0 -117
- package/src/core/loaders/ServerSchemaProvider.ts +0 -99
- package/src/core/loaders/SystemSettingsManager.ts +0 -278
- package/src/core/metadatas/constants.ts +0 -122
- package/src/core/metadatas/recordingConstants.ts +0 -65
- package/src/core/metadatas/types.ts +0 -202
- package/src/core/onboard/FeedOnboardService.ts +0 -501
- package/src/core/onboard/OnboardProcessor.ts +0 -356
- package/src/core/onboard/OnboardStatus.ts +0 -60
- package/src/core/onboard/OnboardStatusManager.ts +0 -416
- package/src/core/validators/FeedValidator.ts +0 -135
- package/src/core/validators/IServerValidator.ts +0 -21
- package/src/core/validators/SSEServerValidator.ts +0 -43
- package/src/core/validators/ServerValidatorFactory.ts +0 -51
- package/src/core/validators/StdioServerValidator.ts +0 -313
- package/src/index.ts +0 -44
- package/src/services/InstallationService.ts +0 -102
- package/src/services/MCPManager.ts +0 -249
- package/src/services/RequirementService.ts +0 -627
- package/src/services/ServerService.ts +0 -161
- package/src/services/TelemetryService.ts +0 -59
- package/src/utils/UpdateCheckTracker.ts +0 -86
- package/src/utils/adoUtils.ts +0 -293
- package/src/utils/clientUtils.ts +0 -72
- package/src/utils/feedUtils.ts +0 -31
- package/src/utils/githubAuth.ts +0 -212
- package/src/utils/githubUtils.ts +0 -164
- package/src/utils/logger.ts +0 -195
- package/src/utils/macroExpressionUtils.ts +0 -104
- package/src/utils/osUtils.ts +0 -700
- package/src/utils/versionUtils.ts +0 -114
- package/src/web/contract/serverContract.ts +0 -74
- package/src/web/public/css/detailsWidget.css +0 -235
- package/src/web/public/css/modal.css +0 -757
- package/src/web/public/css/notifications.css +0 -101
- package/src/web/public/css/onboard.css +0 -107
- package/src/web/public/css/serverCategoryList.css +0 -120
- package/src/web/public/css/serverDetails.css +0 -139
- package/src/web/public/index.html +0 -359
- package/src/web/public/js/api.js +0 -132
- package/src/web/public/js/detailsWidget.js +0 -264
- package/src/web/public/js/flights/flights.js +0 -127
- package/src/web/public/js/modal/index.js +0 -52
- package/src/web/public/js/modal/installModal.js +0 -162
- package/src/web/public/js/modal/installation.js +0 -266
- package/src/web/public/js/modal/loadingModal.js +0 -182
- package/src/web/public/js/modal/modalSetup.js +0 -595
- package/src/web/public/js/modal/modalUtils.js +0 -37
- package/src/web/public/js/modal/versionUtils.js +0 -20
- package/src/web/public/js/modal.js +0 -42
- package/src/web/public/js/notifications.js +0 -137
- package/src/web/public/js/onboard/formProcessor.js +0 -1037
- package/src/web/public/js/onboard/index.js +0 -374
- package/src/web/public/js/onboard/publishHandler.js +0 -172
- package/src/web/public/js/onboard/state.js +0 -76
- package/src/web/public/js/onboard/templates.js +0 -342
- package/src/web/public/js/onboard/uiHandlers.js +0 -1076
- package/src/web/public/js/onboard/validationHandlers.js +0 -493
- package/src/web/public/js/serverCategoryDetails.js +0 -364
- package/src/web/public/js/serverCategoryList.js +0 -241
- package/src/web/public/js/settings.js +0 -314
- package/src/web/public/modal.html +0 -84
- package/src/web/public/onboard.html +0 -296
- package/src/web/public/settings.html +0 -135
- package/src/web/public/styles.css +0 -277
- package/src/web/server.ts +0 -478
- package/tsconfig.json +0 -18
- package/wiki/Installation.md +0 -3
- package/wiki/Publish.md +0 -3
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { SETTINGS_DIR } from '../metadatas/constants.js';
|
|
4
|
-
import { FeedConfiguration, McpConfig } from '../metadatas/types.js';
|
|
5
|
-
import { OnboardStatus, OnboardingProcessStatus, OperationType } from './OnboardStatus.js';
|
|
6
|
-
import { Logger } from '../../utils/logger.js';
|
|
7
|
-
|
|
8
|
-
import * as RecordingConstants from '../metadatas/recordingConstants.js';
|
|
9
|
-
const ONBOARD_STATUS_DIR = path.join(SETTINGS_DIR, 'onboard');
|
|
10
|
-
const CATEGORY_OPERATIONS_STATUS_FILE = path.join(ONBOARD_STATUS_DIR, 'OnboardStatus.json');
|
|
11
|
-
const FEED_CONFIG_DIR = path.join(ONBOARD_STATUS_DIR, 'feed_configs'); // Staging for feed configs during operation
|
|
12
|
-
|
|
13
|
-
const NON_COMPLETED_ONBOARDING_STATUSES: OnboardingProcessStatus[] = [
|
|
14
|
-
OnboardingProcessStatus.PENDING,
|
|
15
|
-
OnboardingProcessStatus.VALIDATING,
|
|
16
|
-
OnboardingProcessStatus.VALIDATED,
|
|
17
|
-
OnboardingProcessStatus.PR_CREATING,
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
export class OnboardStatusManager {
|
|
21
|
-
private static instance: OnboardStatusManager;
|
|
22
|
-
private activeCategoryOperations: Record<string, Partial<Record<OperationType, OnboardStatus>>> = {};
|
|
23
|
-
private statusLock: Promise<void> = Promise.resolve();
|
|
24
|
-
|
|
25
|
-
private constructor() {
|
|
26
|
-
this.loadStatuses().catch(error => Logger.error('Failed to initialize OnboardStatusManager:', error));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public static getInstance(): OnboardStatusManager {
|
|
30
|
-
if (!OnboardStatusManager.instance) {
|
|
31
|
-
OnboardStatusManager.instance = new OnboardStatusManager();
|
|
32
|
-
}
|
|
33
|
-
return OnboardStatusManager.instance;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
private async withLock<T>(operation: () => Promise<T>): Promise<T> {
|
|
37
|
-
const current = this.statusLock;
|
|
38
|
-
let resolve: () => void;
|
|
39
|
-
this.statusLock = new Promise<void>(r => resolve = r);
|
|
40
|
-
try {
|
|
41
|
-
await current;
|
|
42
|
-
return await operation();
|
|
43
|
-
} finally {
|
|
44
|
-
resolve!();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private async loadStatuses(): Promise<void> {
|
|
49
|
-
await this.withLock(async () => {
|
|
50
|
-
try {
|
|
51
|
-
await fs.mkdir(ONBOARD_STATUS_DIR, { recursive: true });
|
|
52
|
-
await fs.mkdir(FEED_CONFIG_DIR, { recursive: true });
|
|
53
|
-
const data = await fs.readFile(CATEGORY_OPERATIONS_STATUS_FILE, 'utf-8');
|
|
54
|
-
this.activeCategoryOperations = JSON.parse(data);
|
|
55
|
-
} catch (error) {
|
|
56
|
-
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
57
|
-
this.activeCategoryOperations = {};
|
|
58
|
-
await this.saveStatuses(); // Create the file if it doesn't exist
|
|
59
|
-
} else {
|
|
60
|
-
Logger.error('Failed to load onboarding statuses:', error);
|
|
61
|
-
this.activeCategoryOperations = {}; // Initialize with empty statuses in case of other errors
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private async saveStatuses(): Promise<void> {
|
|
68
|
-
await fs.mkdir(ONBOARD_STATUS_DIR, { recursive: true });
|
|
69
|
-
await fs.writeFile(CATEGORY_OPERATIONS_STATUS_FILE, JSON.stringify(this.activeCategoryOperations, null, 2));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Saves the feed configuration associated with a category's active operation.
|
|
74
|
-
* The operation is identified by the categoryName.
|
|
75
|
-
* @param categoryName The name of the category (acting as operationId).
|
|
76
|
-
* @param config The FeedConfiguration to save.
|
|
77
|
-
*/
|
|
78
|
-
public async saveFeedConfiguration(categoryName: string, operationType: OperationType, config: FeedConfiguration): Promise<void> {
|
|
79
|
-
await this.withLock(async () => {
|
|
80
|
-
try {
|
|
81
|
-
await fs.mkdir(FEED_CONFIG_DIR, { recursive: true });
|
|
82
|
-
// Suffix `_feed.json` to distinguish from potential status files if names overlap
|
|
83
|
-
const operationId = this.createOperationId(categoryName, operationType);
|
|
84
|
-
const configPath = path.join(FEED_CONFIG_DIR, `${operationId}_feed.json`);
|
|
85
|
-
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
86
|
-
Logger.debug(`Saved feed configuration for category ${categoryName} to ${configPath}`);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
Logger.error(`Failed to save feed configuration for category ${categoryName}:`, error);
|
|
89
|
-
throw error; // Re-throw to allow caller to handle
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Retrieves the feed configuration associated with a category's active operation.
|
|
96
|
-
* @param categoryName The name of the category (acting as operationId).
|
|
97
|
-
* @returns A promise that resolves to the FeedConfiguration, or undefined if not found.
|
|
98
|
-
*/
|
|
99
|
-
public async getFeedConfiguration(categoryName: string, operationType: OperationType): Promise<FeedConfiguration | undefined> {
|
|
100
|
-
return await this.withLock(async () => {
|
|
101
|
-
try {
|
|
102
|
-
const operationId = this.createOperationId(categoryName, operationType);
|
|
103
|
-
const configPath = path.join(FEED_CONFIG_DIR, `${operationId}_feed.json`);
|
|
104
|
-
const data = await fs.readFile(configPath, 'utf-8');
|
|
105
|
-
return JSON.parse(data) as FeedConfiguration;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
108
|
-
return undefined; // File not found, not an error state for this getter
|
|
109
|
-
}
|
|
110
|
-
// Log other errors but still return undefined as the config couldn't be retrieved.
|
|
111
|
-
Logger.error(`Failed to read feed configuration for category ${categoryName}:`, error);
|
|
112
|
-
return undefined; // Ensure undefined is returned on other errors too
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Retrieves the status of a specific operation for a category.
|
|
120
|
-
* @param categoryName The name of the category.
|
|
121
|
-
* @param operationType The type of operation.
|
|
122
|
-
* @returns A promise that resolves to the OnboardStatus, or undefined if no such operation or category.
|
|
123
|
-
*/
|
|
124
|
-
public async getStatus(categoryName: string, operationType: OperationType): Promise<OnboardStatus | undefined> {
|
|
125
|
-
await this.loadStatuses(); // Ensure latest statuses are loaded
|
|
126
|
-
return this.activeCategoryOperations[categoryName]?.[operationType];
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Retrieves all active category operation statuses, structured by category and then by operation type.
|
|
131
|
-
* @returns A promise that resolves to a record of all active OnboardStatus objects.
|
|
132
|
-
*/
|
|
133
|
-
public async getAllStatuses(): Promise<Record<string, Partial<Record<OperationType, OnboardStatus>>>> {
|
|
134
|
-
await this.loadStatuses();
|
|
135
|
-
return this.activeCategoryOperations;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Updates the status of a specific operation for a category.
|
|
140
|
-
* If a `stepName` is provided in `updates`, it will also add a new step.
|
|
141
|
-
* @param categoryName The name of the category.
|
|
142
|
-
* @param operationType The type of operation.
|
|
143
|
-
* @param updates Partial OnboardStatus object with fields to update. Can include `stepName` to record a new step.
|
|
144
|
-
* @param stepName Optional. If provided, a new step with this name will be recorded.
|
|
145
|
-
* @param stepStatus Optional. Status for the new step, if `stepName` is provided.
|
|
146
|
-
* @param errorMessage Optional. Error message for the new step, if `stepName` is provided.
|
|
147
|
-
* @returns A promise that resolves to the updated OnboardStatus.
|
|
148
|
-
*/
|
|
149
|
-
public async updateStatus(
|
|
150
|
-
categoryName: string,
|
|
151
|
-
operationType: OperationType,
|
|
152
|
-
updates: Partial<Omit<OnboardStatus, 'steps'>>, // Exclude steps from direct updates here
|
|
153
|
-
stepName?: string,
|
|
154
|
-
stepStatus?: OnboardingProcessStatus,
|
|
155
|
-
errorMessage?: string
|
|
156
|
-
): Promise<OnboardStatus> {
|
|
157
|
-
return await this.withLock(async () => {
|
|
158
|
-
const operationId = this.createOperationId(categoryName, operationType);
|
|
159
|
-
const categoryOps = this.activeCategoryOperations[categoryName] || {};
|
|
160
|
-
let existingStatus = categoryOps[operationType];
|
|
161
|
-
|
|
162
|
-
if (!existingStatus) {
|
|
163
|
-
// If no status exists, create an initial one.
|
|
164
|
-
// This might happen if updateStatus is called before createInitialStatus,
|
|
165
|
-
// though ideally createInitialStatus should be the entry point.
|
|
166
|
-
existingStatus = {
|
|
167
|
-
onboardingId: operationId,
|
|
168
|
-
feedName: categoryName,
|
|
169
|
-
status: updates.status || OnboardingProcessStatus.PENDING,
|
|
170
|
-
lastUpdated: new Date().toISOString(),
|
|
171
|
-
operationType: operationType,
|
|
172
|
-
steps: [],
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Apply general updates
|
|
177
|
-
let updatedStatus: OnboardStatus = {
|
|
178
|
-
...existingStatus,
|
|
179
|
-
...updates,
|
|
180
|
-
onboardingId: operationId,
|
|
181
|
-
feedName: categoryName,
|
|
182
|
-
operationType: operationType,
|
|
183
|
-
lastUpdated: new Date().toISOString(),
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
// If stepName is provided, add it as a new step
|
|
187
|
-
if (stepName) {
|
|
188
|
-
const newStep = {
|
|
189
|
-
stepName,
|
|
190
|
-
timestamp: new Date().toISOString(),
|
|
191
|
-
status: stepStatus ?? updates.status ?? existingStatus.status,
|
|
192
|
-
errorMessage: errorMessage ?? updates.errorMessage,
|
|
193
|
-
};
|
|
194
|
-
updatedStatus.steps = [...(existingStatus.steps || []), newStep];
|
|
195
|
-
|
|
196
|
-
// If the step has a specific status, it might also update the overall status
|
|
197
|
-
if (newStep.status && newStep.status !== updatedStatus.status) {
|
|
198
|
-
updatedStatus.status = newStep.status;
|
|
199
|
-
}
|
|
200
|
-
if (newStep.errorMessage && !updatedStatus.errorMessage) {
|
|
201
|
-
updatedStatus.errorMessage = newStep.errorMessage;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
categoryOps[operationType] = updatedStatus;
|
|
206
|
-
this.activeCategoryOperations[categoryName] = categoryOps;
|
|
207
|
-
await this.saveStatuses();
|
|
208
|
-
return updatedStatus;
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* A more specific method to record a step, which can also update the overall status.
|
|
214
|
-
* This is intended to replace the local `updateStatus` functions in validators/services.
|
|
215
|
-
* @param categoryName The name of the category (e.g., feed name).
|
|
216
|
-
* @param operationType The type of operation.
|
|
217
|
-
* @param stepName The description of the current step.
|
|
218
|
-
* @param serverName Optional server context for this step.
|
|
219
|
-
* @param newStatus Optional overall status to set for the operation.
|
|
220
|
-
* @param errorMessage Optional error message if this step resulted in a failure.
|
|
221
|
-
* @returns A promise that resolves to the updated OnboardStatus.
|
|
222
|
-
*/
|
|
223
|
-
public async recordStep(
|
|
224
|
-
categoryName: string,
|
|
225
|
-
operationType: OperationType,
|
|
226
|
-
stepName: string,
|
|
227
|
-
serverName?: string, // Added serverName to be part of the step if relevant
|
|
228
|
-
newStatus?: OnboardingProcessStatus,
|
|
229
|
-
errorMessage?: string
|
|
230
|
-
): Promise<OnboardStatus> {
|
|
231
|
-
return await this.withLock(async () => {
|
|
232
|
-
const operationId = this.createOperationId(categoryName, operationType);
|
|
233
|
-
const categoryOps = this.activeCategoryOperations[categoryName] || {};
|
|
234
|
-
let currentStatus = categoryOps[operationType];
|
|
235
|
-
|
|
236
|
-
if (!currentStatus) {
|
|
237
|
-
currentStatus = await this.createInitialStatus(categoryName, operationType, serverName);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const stepToAdd = {
|
|
241
|
-
stepName,
|
|
242
|
-
timestamp: new Date().toISOString(),
|
|
243
|
-
status: newStatus ?? (errorMessage ? OnboardingProcessStatus.FAILED : currentStatus.status), // Step inherits current or becomes FAILED
|
|
244
|
-
errorMessage: errorMessage,
|
|
245
|
-
...(serverName && { serverName }), // Include serverName in the step if provided
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
const updatedSteps = [...(currentStatus.steps || []), stepToAdd];
|
|
249
|
-
|
|
250
|
-
const statusUpdatePayload: Partial<OnboardStatus> = {
|
|
251
|
-
steps: updatedSteps,
|
|
252
|
-
lastUpdated: new Date().toISOString(),
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
if (newStatus) {
|
|
256
|
-
statusUpdatePayload.status = newStatus;
|
|
257
|
-
} else if (errorMessage && currentStatus.status !== OnboardingProcessStatus.FAILED) {
|
|
258
|
-
// If an error occurs and we're not already FAILED, mark as FAILED.
|
|
259
|
-
statusUpdatePayload.status = OnboardingProcessStatus.FAILED;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (errorMessage && !currentStatus.errorMessage) { // Store the first error message
|
|
263
|
-
statusUpdatePayload.errorMessage = errorMessage;
|
|
264
|
-
}
|
|
265
|
-
if (serverName && !currentStatus.serverName) { // Store serverName if not already set at top level
|
|
266
|
-
statusUpdatePayload.serverName = serverName;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
const updatedStatus: OnboardStatus = {
|
|
271
|
-
...currentStatus,
|
|
272
|
-
...statusUpdatePayload,
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
categoryOps[operationType] = updatedStatus;
|
|
276
|
-
this.activeCategoryOperations[categoryName] = categoryOps;
|
|
277
|
-
await this.saveStatuses();
|
|
278
|
-
return updatedStatus;
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Creates an operation ID that combines category name and operation type.
|
|
284
|
-
* @param categoryName The name of the category.
|
|
285
|
-
* @param operationType The type of operation.
|
|
286
|
-
* @returns Combined operation ID string.
|
|
287
|
-
*/
|
|
288
|
-
private createOperationId(categoryName: string, operationType: OperationType): string {
|
|
289
|
-
return `${categoryName}_${operationType}`;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Creates an initial status for a new category-wide operation.
|
|
294
|
-
* The operation is identified by the categoryName.
|
|
295
|
-
* @param categoryName The name of the category (also used as feedName and operationId).
|
|
296
|
-
* @param operationType The type of operation (e.g., FULL_ONBOARDING, VALIDATION_ONLY).
|
|
297
|
-
* @param serverName Optional: if the operation has a specific server context (e.g. validating a single new server in an existing category).
|
|
298
|
-
* However, the primary operation tracking is still by categoryName.
|
|
299
|
-
* @returns A promise that resolves to the initial OnboardStatus.
|
|
300
|
-
*/
|
|
301
|
-
public async createInitialStatus(categoryName: string, operationType: OperationType, serverName?: string): Promise<OnboardStatus> {
|
|
302
|
-
// Create operation ID that includes both category and operation type
|
|
303
|
-
const operationId = this.createOperationId(categoryName, operationType);
|
|
304
|
-
|
|
305
|
-
const initialStatus: OnboardStatus = {
|
|
306
|
-
onboardingId: operationId,
|
|
307
|
-
feedName: categoryName,
|
|
308
|
-
serverName,
|
|
309
|
-
status: OnboardingProcessStatus.PENDING,
|
|
310
|
-
steps: [{ stepName: RecordingConstants.STEP_INITIATED, timestamp: new Date().toISOString() }],
|
|
311
|
-
lastUpdated: new Date().toISOString(),
|
|
312
|
-
operationType,
|
|
313
|
-
errorMessage: undefined,
|
|
314
|
-
prInfo: undefined
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
// Save directly without using updateStatus, into the new structure
|
|
318
|
-
await this.withLock(async () => {
|
|
319
|
-
const categoryOps = this.activeCategoryOperations[categoryName] || {};
|
|
320
|
-
categoryOps[operationType] = initialStatus;
|
|
321
|
-
this.activeCategoryOperations[categoryName] = categoryOps;
|
|
322
|
-
await this.saveStatuses();
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
return initialStatus;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Finds a succeeded operation for a given feed name and operation type that has a matching feed configuration.
|
|
331
|
-
* @param feedName The name of the feed.
|
|
332
|
-
* @param operationType The type of operation.
|
|
333
|
-
* @param currentConfig The current feed configuration to compare against.
|
|
334
|
-
* @returns A promise that resolves to the OnboardStatus of the succeeded operation, or undefined if not found.
|
|
335
|
-
*/
|
|
336
|
-
public async findSucceededOperation(
|
|
337
|
-
feedName: string,
|
|
338
|
-
operationType: OperationType,
|
|
339
|
-
currentConfig: FeedConfiguration
|
|
340
|
-
): Promise<OnboardStatus | undefined> {
|
|
341
|
-
return await this.withLock(async () => {
|
|
342
|
-
for (const categoryName in this.activeCategoryOperations) {
|
|
343
|
-
const operations = this.activeCategoryOperations[categoryName];
|
|
344
|
-
if (operations) {
|
|
345
|
-
const specificOperationStatus = operations[operationType];
|
|
346
|
-
if (
|
|
347
|
-
specificOperationStatus &&
|
|
348
|
-
specificOperationStatus.feedName === feedName &&
|
|
349
|
-
specificOperationStatus.status === OnboardingProcessStatus.SUCCEEDED
|
|
350
|
-
) {
|
|
351
|
-
// The FeedConfiguration is stored in the result of the SUCCEEDED operation
|
|
352
|
-
const savedConfig = specificOperationStatus.result?.feedConfiguration as FeedConfiguration;
|
|
353
|
-
|
|
354
|
-
if (savedConfig && this.isFeedConfigurationEqual(savedConfig, currentConfig)) {
|
|
355
|
-
return specificOperationStatus;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
return undefined;
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* Compares two feed configurations for equality.
|
|
366
|
-
* @param config1 First feed configuration.
|
|
367
|
-
* @param config2 Second feed configuration.
|
|
368
|
-
* @returns True if the configurations are identical, false otherwise.
|
|
369
|
-
*/
|
|
370
|
-
private isFeedConfigurationEqual(config1: FeedConfiguration, config2: FeedConfiguration): boolean {
|
|
371
|
-
// Compare basic properties
|
|
372
|
-
if (config1.name !== config2.name) return false;
|
|
373
|
-
|
|
374
|
-
// Compare arrays with specific order handling
|
|
375
|
-
const compareArrays = <T>(arr1: T[], arr2: T[], sortFn?: (a: T, b: T) => number): boolean => {
|
|
376
|
-
if (arr1.length !== arr2.length) return false;
|
|
377
|
-
const sorted1 = sortFn ? [...arr1].sort(sortFn) : arr1;
|
|
378
|
-
const sorted2 = sortFn ? [...arr2].sort(sortFn) : arr2;
|
|
379
|
-
return JSON.stringify(sorted1) === JSON.stringify(sorted2);
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
// Compare requirements array
|
|
383
|
-
if (!compareArrays(config1.requirements || [], config2.requirements || [])) return false;
|
|
384
|
-
|
|
385
|
-
// Compare MCP servers with name-based sorting
|
|
386
|
-
const sortByName = (a: McpConfig, b: McpConfig) => (a.name || '').localeCompare(b.name || '');
|
|
387
|
-
if (!compareArrays(config1.mcpServers || [], config2.mcpServers || [], sortByName)) return false;
|
|
388
|
-
|
|
389
|
-
return true;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Finds an existing non-completed operation for a given feed name, server name, and operation type.
|
|
394
|
-
* @param feedName The name of the feed.
|
|
395
|
-
* @param operationType The type of operation.
|
|
396
|
-
* @returns A promise that resolves to the OnboardStatus of the existing operation, or undefined if not found.
|
|
397
|
-
*/
|
|
398
|
-
public async _findExistingNonCompletedOperation(
|
|
399
|
-
feedName: string,
|
|
400
|
-
operationType: OperationType
|
|
401
|
-
): Promise<OnboardStatus | undefined> {
|
|
402
|
-
const allCategoryStatuses = await this.getAllStatuses();
|
|
403
|
-
// feedName is the categoryName
|
|
404
|
-
const categoryOperations = allCategoryStatuses[feedName];
|
|
405
|
-
if (categoryOperations) {
|
|
406
|
-
const specificOperationStatus = categoryOperations[operationType];
|
|
407
|
-
if (specificOperationStatus && NON_COMPLETED_ONBOARDING_STATUSES.includes(specificOperationStatus.status)) {
|
|
408
|
-
return specificOperationStatus;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return undefined;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// Export singleton instance
|
|
416
|
-
export const onboardStatusManager = OnboardStatusManager.getInstance();
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { FeedConfiguration, McpConfig } from "../metadatas/types.js";
|
|
4
|
-
import { serverValidatorFactory } from "./ServerValidatorFactory.js";
|
|
5
|
-
import { Logger } from "../../utils/logger.js";
|
|
6
|
-
import { onboardStatusManager } from "../onboard/OnboardStatusManager.js";
|
|
7
|
-
import { OnboardingProcessStatus, OperationType } from "../onboard/OnboardStatus.js";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Validates feed configurations to ensure they meet required criteria
|
|
11
|
-
*/
|
|
12
|
-
export class FeedValidator {
|
|
13
|
-
/**
|
|
14
|
-
* Validates a feed configuration
|
|
15
|
-
* @param config The feed configuration to validate
|
|
16
|
-
* @param categoryName The name of the category (feed name) for status updates
|
|
17
|
-
* @param operationType The type of operation for status updates
|
|
18
|
-
* @returns true if valid, throws error if invalid
|
|
19
|
-
*/
|
|
20
|
-
public async validate(config: FeedConfiguration, categoryName: string, operationType: OperationType): Promise<boolean> {
|
|
21
|
-
try {
|
|
22
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Starting feed validation for '${config.name}'`);
|
|
23
|
-
Logger.debug(`Validating feed configuration: ${config.name}`);
|
|
24
|
-
|
|
25
|
-
// Validate required fields
|
|
26
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Validating required fields for '${config.name}'`);
|
|
27
|
-
if (!config.name) throw new Error('Feed name is required');
|
|
28
|
-
if (!config.displayName) throw new Error('Feed display name is required');
|
|
29
|
-
if (!config.description) throw new Error('Feed description is required');
|
|
30
|
-
|
|
31
|
-
// Validate MCP servers array
|
|
32
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Validating MCP servers array for '${config.name}'`);
|
|
33
|
-
if (!Array.isArray(config.mcpServers) || config.mcpServers.length === 0) {
|
|
34
|
-
throw new Error('Feed must contain at least one MCP server');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Validate requirements if present
|
|
38
|
-
if (config.requirements) {
|
|
39
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Validating requirements for '${config.name}'`);
|
|
40
|
-
for (const req of config.requirements) {
|
|
41
|
-
if (!req.name) throw new Error('Requirement name is required');
|
|
42
|
-
if (!req.type) throw new Error('Requirement type is required');
|
|
43
|
-
if (!req.version) throw new Error('Requirement version is required');
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Feed validation successful for '${config.name}'`, undefined, OnboardingProcessStatus.VALIDATING); // Still in progress until all servers validated
|
|
48
|
-
Logger.debug(`Feed configuration validation successful: ${config.name}`);
|
|
49
|
-
return true;
|
|
50
|
-
} catch (error) {
|
|
51
|
-
const errorMsg = `Feed validation failed for '${config.name}': ${error instanceof Error ? error.message : String(error)}`;
|
|
52
|
-
Logger.error(errorMsg);
|
|
53
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Feed validation failed for '${config.name}'`, undefined, OnboardingProcessStatus.FAILED, errorMsg);
|
|
54
|
-
throw new Error(errorMsg);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Validates a single MCP server configuration using the appropriate validator
|
|
60
|
-
* @param server The MCP server configuration to validate
|
|
61
|
-
* @param config The feed configuration containing shared requirements
|
|
62
|
-
* @param categoryName The name of the category (feed name) for status updates
|
|
63
|
-
* @param operationType The type of operation for status updates
|
|
64
|
-
* @returns true if valid, throws error if invalid
|
|
65
|
-
*/
|
|
66
|
-
public async validateServer(server: McpConfig, config: FeedConfiguration, categoryName: string, operationType: OperationType): Promise<boolean> {
|
|
67
|
-
const feedName = config.name; // categoryName is the feedName in this context
|
|
68
|
-
const serverDisplayName = server.name;
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Starting server validation for '${serverDisplayName}' in feed '${feedName}'`, server.name);
|
|
72
|
-
Logger.debug(`Validating server configuration: ${serverDisplayName} in feed ${feedName}`);
|
|
73
|
-
|
|
74
|
-
// Validate basic required fields
|
|
75
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Validating basic fields for server '${serverDisplayName}'`, server.name);
|
|
76
|
-
if (!server.name) throw new Error('Server name is required');
|
|
77
|
-
if (!server.description) throw new Error('Server description is required');
|
|
78
|
-
if (!server.mode) throw new Error('Server mode is required');
|
|
79
|
-
if (!server.installation) throw new Error('Server installation configuration is required');
|
|
80
|
-
|
|
81
|
-
// Validate schema file existence if schemas is defined
|
|
82
|
-
if (server.schemas) {
|
|
83
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Validating schema file for server '${serverDisplayName}'`, server.name);
|
|
84
|
-
try {
|
|
85
|
-
// Assuming server.schemas is a relative path from the project root or a path that needs to be resolved.
|
|
86
|
-
// For now, let's assume it's relative to the feed file's location or an absolute path.
|
|
87
|
-
// If it's relative to the feed file, we might need the feed file's path.
|
|
88
|
-
// For simplicity, let's assume it's a path that can be directly accessed.
|
|
89
|
-
// If the schema path is relative to the feed config file, this logic will need adjustment.
|
|
90
|
-
// For now, we'll treat it as a path that `fs.access` can check.
|
|
91
|
-
// It's more likely that schema paths are relative to the feed definition file itself.
|
|
92
|
-
// However, the task description implies `server.schemas` is a path to be checked.
|
|
93
|
-
// Let's assume for now it's a path that should exist.
|
|
94
|
-
// If the schemas are stored within the repo, their paths would be relative to the repo root.
|
|
95
|
-
// During validation, we might not have the repo context directly here.
|
|
96
|
-
// This needs clarification on how schema paths are resolved during validation.
|
|
97
|
-
// For now, we'll proceed with a direct check.
|
|
98
|
-
// If the schema is part of the feed package, its path might be relative to the package root.
|
|
99
|
-
// Let's assume the path is resolvable from the current working directory or is absolute.
|
|
100
|
-
// This part might need refinement based on where schema files are expected to be.
|
|
101
|
-
// The task implies `server.schemas` is a string path.
|
|
102
|
-
const schemaPath = server.schemas; // This path needs to be correctly resolved.
|
|
103
|
-
// If it's relative to the feed file, we need that context.
|
|
104
|
-
// For now, we'll assume it's a path that can be checked.
|
|
105
|
-
// This might be an issue if it's relative to a file not yet in the repo.
|
|
106
|
-
// Let's assume it's a path that should be resolvable.
|
|
107
|
-
await fs.access(schemaPath);
|
|
108
|
-
Logger.debug(`Schema file ${schemaPath} exists for server ${serverDisplayName}`);
|
|
109
|
-
} catch (fileAccessError) {
|
|
110
|
-
throw new Error(`Schema file '${server.schemas}' not found for server '${serverDisplayName}'.`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Get the appropriate validator for this server type
|
|
115
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Obtaining specific validator for server '${serverDisplayName}'`, server.name);
|
|
116
|
-
const validator = serverValidatorFactory.getValidatorForServer(server);
|
|
117
|
-
|
|
118
|
-
// Perform mode-specific validation with feed config
|
|
119
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Performing mode-specific validation for server '${serverDisplayName}'`, server.name);
|
|
120
|
-
await validator.validateServer(server, config); // This internal call won't have status updates unless modified too
|
|
121
|
-
|
|
122
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Server validation successful for '${serverDisplayName}'`, server.name, OnboardingProcessStatus.VALIDATING); // Still in progress until all servers validated
|
|
123
|
-
Logger.debug(`Server configuration validation successful: ${serverDisplayName}`);
|
|
124
|
-
return true;
|
|
125
|
-
} catch (error) {
|
|
126
|
-
const errorMsg = `Server validation failed for '${serverDisplayName}' in feed '${feedName}': ${error instanceof Error ? error.message : String(error)}`;
|
|
127
|
-
Logger.error(errorMsg);
|
|
128
|
-
await onboardStatusManager.recordStep(categoryName, operationType, `Server validation failed for '${serverDisplayName}'`, server.name, OnboardingProcessStatus.FAILED, errorMsg);
|
|
129
|
-
throw new Error(errorMsg);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Export singleton instance
|
|
135
|
-
export const feedValidator = new FeedValidator();
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { McpConfig, FeedConfiguration } from "../metadatas/types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Interface for MCP server configuration validators
|
|
5
|
-
* Defines common validation operations for server configurations
|
|
6
|
-
*/
|
|
7
|
-
export interface IServerValidator {
|
|
8
|
-
/**
|
|
9
|
-
* Validates a specific MCP server configuration
|
|
10
|
-
* Implementation varies based on server mode (stdio/sse)
|
|
11
|
-
* @param server The MCP server configuration to validate
|
|
12
|
-
* @param config The feed configuration containing shared requirements
|
|
13
|
-
* @returns true if valid, throws error if invalid
|
|
14
|
-
*/
|
|
15
|
-
validateServer(server: McpConfig, config: FeedConfiguration): Promise<boolean>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Valid validator types for MCP servers
|
|
20
|
-
*/
|
|
21
|
-
export type ValidatorType = 'stdio' | 'sse';
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { McpConfig, FeedConfiguration } from "../metadatas/types.js";
|
|
2
|
-
import { IServerValidator } from "./IServerValidator.js";
|
|
3
|
-
import { Logger } from "../../utils/logger.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Validates MCP server configurations for SSE mode
|
|
7
|
-
*/
|
|
8
|
-
export class SSEServerValidator implements IServerValidator {
|
|
9
|
-
/**
|
|
10
|
-
* Validates SSE-specific MCP server configuration
|
|
11
|
-
* Checks installation URL, requirements, and environment variables
|
|
12
|
-
* @param server The MCP server configuration to validate
|
|
13
|
-
* @param config The feed configuration containing shared requirements
|
|
14
|
-
* @returns true if valid, throws error if invalid
|
|
15
|
-
*/
|
|
16
|
-
public async validateServer(server: McpConfig, config: FeedConfiguration): Promise<boolean> {
|
|
17
|
-
try {
|
|
18
|
-
Logger.debug(`Validating SSE server configuration: ${server.name}`);
|
|
19
|
-
|
|
20
|
-
if (!server.installation?.url) {
|
|
21
|
-
throw new Error('SSE server URL is required in installation configuration');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
new URL(server.installation.url);
|
|
26
|
-
} catch (e) {
|
|
27
|
-
throw new Error(`Invalid SSE server URL: ${server.installation.url}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Validate server mode
|
|
31
|
-
if (server.mode !== 'sse') {
|
|
32
|
-
throw new Error(`Invalid server mode for SSE validator: ${server.mode}`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Additional SSE-specific validation will be implemented later
|
|
36
|
-
return true;
|
|
37
|
-
} catch (error) {
|
|
38
|
-
const errorMsg = `Server validation failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
39
|
-
Logger.error(errorMsg);
|
|
40
|
-
throw new Error(errorMsg);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { McpConfig } from "../metadatas/types.js";
|
|
2
|
-
import { IServerValidator, ValidatorType } from "./IServerValidator.js";
|
|
3
|
-
import { StdioServerValidator } from "./StdioServerValidator.js";
|
|
4
|
-
import { SSEServerValidator } from "./SSEServerValidator.js";
|
|
5
|
-
import { Logger } from "../../utils/logger.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Factory class for managing server validator instances
|
|
9
|
-
* Maintains a singleton map of validators by type
|
|
10
|
-
*/
|
|
11
|
-
export class ServerValidatorFactory {
|
|
12
|
-
private static validators = new Map<ValidatorType, IServerValidator>();
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
// Initialize validators if not already done
|
|
16
|
-
if (ServerValidatorFactory.validators.size === 0) {
|
|
17
|
-
Logger.debug('Initializing server validators');
|
|
18
|
-
ServerValidatorFactory.validators.set('stdio', new StdioServerValidator());
|
|
19
|
-
ServerValidatorFactory.validators.set('sse', new SSEServerValidator());
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Gets the appropriate validator for the given server mode
|
|
25
|
-
* @param mode The server mode to get validator for
|
|
26
|
-
* @returns IServerValidator instance for the specified mode
|
|
27
|
-
* @throws Error if server mode is not supported
|
|
28
|
-
*/
|
|
29
|
-
public getValidator(mode: ValidatorType): IServerValidator {
|
|
30
|
-
const validator = ServerValidatorFactory.validators.get(mode);
|
|
31
|
-
if (!validator) {
|
|
32
|
-
const error = `Unsupported MCP server mode: ${mode}`;
|
|
33
|
-
Logger.error(error);
|
|
34
|
-
throw new Error(error);
|
|
35
|
-
}
|
|
36
|
-
Logger.debug(`Retrieved ${mode} validator`);
|
|
37
|
-
return validator;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Gets the appropriate validator for the given server config
|
|
42
|
-
* @param serverConfig MCP server configuration
|
|
43
|
-
* @returns IServerValidator instance appropriate for the server mode
|
|
44
|
-
*/
|
|
45
|
-
public getValidatorForServer(serverConfig: McpConfig): IServerValidator {
|
|
46
|
-
return this.getValidator(serverConfig.mode);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Export singleton instance
|
|
51
|
-
export const serverValidatorFactory = new ServerValidatorFactory();
|