imcp 0.0.19 → 0.1.2
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/.roo/rules-code/rules.md +88 -0
- package/dist/cli/index.js +1 -45
- package/dist/core/installers/clients/BaseClientInstaller.d.ts +1 -5
- package/dist/core/installers/clients/BaseClientInstaller.js +40 -38
- package/dist/core/installers/clients/ClientInstaller.d.ts +9 -9
- package/dist/core/installers/clients/ClientInstaller.js +105 -99
- package/dist/core/installers/requirements/BaseInstaller.d.ts +9 -1
- package/dist/core/installers/requirements/CommandInstaller.d.ts +9 -1
- package/dist/core/installers/requirements/CommandInstaller.js +46 -12
- package/dist/core/installers/requirements/GeneralInstaller.d.ts +11 -1
- package/dist/core/installers/requirements/GeneralInstaller.js +46 -10
- package/dist/core/installers/requirements/InstallerFactory.d.ts +3 -1
- package/dist/core/installers/requirements/InstallerFactory.js +3 -2
- package/dist/core/installers/requirements/NpmInstaller.d.ts +4 -2
- package/dist/core/installers/requirements/NpmInstaller.js +38 -22
- package/dist/core/installers/requirements/PipInstaller.d.ts +3 -1
- package/dist/core/installers/requirements/PipInstaller.js +58 -36
- package/dist/core/installers/requirements/RequirementInstaller.d.ts +4 -1
- package/dist/core/loaders/InstallOperationManager.d.ts +115 -0
- package/dist/core/loaders/InstallOperationManager.js +311 -0
- package/dist/core/loaders/SystemSettingsManager.d.ts +54 -0
- package/dist/core/loaders/SystemSettingsManager.js +257 -0
- package/dist/core/metadatas/constants.d.ts +7 -0
- package/dist/core/metadatas/constants.js +7 -0
- package/dist/core/metadatas/recordingConstants.d.ts +44 -0
- package/dist/core/metadatas/recordingConstants.js +45 -0
- package/dist/core/metadatas/types.d.ts +21 -0
- package/dist/core/onboard/FeedOnboardService.d.ts +7 -3
- package/dist/core/onboard/FeedOnboardService.js +52 -5
- package/dist/core/onboard/InstallOperationManager.d.ts +23 -0
- package/dist/core/onboard/InstallOperationManager.js +144 -0
- package/dist/core/onboard/OnboardStatusManager.js +2 -1
- package/dist/core/validators/StdioServerValidator.js +4 -3
- package/dist/services/InstallationService.d.ts +2 -37
- package/dist/services/InstallationService.js +45 -313
- package/dist/services/MCPManager.d.ts +1 -1
- package/dist/services/MCPManager.js +53 -47
- package/dist/services/RequirementService.d.ts +85 -12
- package/dist/services/RequirementService.js +488 -49
- package/dist/services/ServerService.d.ts +0 -6
- package/dist/services/ServerService.js +0 -74
- package/dist/services/TelemetryService.d.ts +15 -0
- package/dist/services/TelemetryService.js +54 -0
- package/dist/utils/adoUtils.js +6 -3
- package/dist/utils/githubAuth.js +65 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.js +78 -1
- package/dist/utils/macroExpressionUtils.js +3 -25
- package/dist/utils/osUtils.d.ts +22 -1
- package/dist/utils/osUtils.js +92 -1
- package/dist/utils/versionUtils.d.ts +20 -0
- package/dist/utils/versionUtils.js +76 -0
- package/dist/web/public/css/modal.css +292 -1
- package/dist/web/public/css/serverCategoryList.css +120 -0
- package/dist/web/public/css/serverDetails.css +14 -1
- package/dist/web/public/index.html +126 -21
- package/dist/web/public/js/flights/flights.js +1 -1
- package/dist/web/public/js/modal/index.js +8 -14
- package/dist/web/public/js/modal/installModal.js +3 -4
- package/dist/web/public/js/modal/installation.js +122 -137
- package/dist/web/public/js/modal/loadingModal.js +155 -25
- package/dist/web/public/js/modal/messageQueue.js +45 -101
- package/dist/web/public/js/modal/modalSetup.js +125 -43
- package/dist/web/public/js/modal/modalUtils.js +0 -12
- package/dist/web/public/js/modal.js +23 -10
- package/dist/web/public/js/onboard/formProcessor.js +18 -11
- package/dist/web/public/js/onboard/publishHandler.js +35 -3
- package/dist/web/public/js/onboard/templates.js +5 -1
- package/dist/web/public/js/onboard/uiHandlers.js +266 -39
- package/dist/web/public/js/onboard/validationHandlers.js +71 -39
- package/dist/web/public/js/serverCategoryDetails.js +60 -11
- package/dist/web/public/js/serverCategoryList.js +93 -9
- package/dist/web/public/js/settings.js +314 -0
- package/dist/web/public/onboard.html +2 -2
- package/dist/web/public/settings.html +135 -0
- package/dist/web/public/styles.css +32 -0
- package/dist/web/server.js +93 -1
- package/{src/web/public/js/onboard → docs}/ONBOARDING_PAGE_DESIGN.md +15 -125
- package/docs/Telemetry.md +136 -0
- package/memory-bank/activeContext.md +26 -0
- package/memory-bank/decisionLog.md +91 -0
- package/memory-bank/productContext.md +41 -0
- package/memory-bank/progress.md +35 -0
- package/memory-bank/systemPatterns.md +10 -0
- package/package.json +2 -1
- package/src/cli/index.ts +1 -48
- package/src/core/installers/clients/BaseClientInstaller.ts +64 -50
- package/src/core/installers/clients/ClientInstaller.ts +130 -130
- package/src/core/installers/requirements/BaseInstaller.ts +9 -1
- package/src/core/installers/requirements/CommandInstaller.ts +47 -13
- package/src/core/installers/requirements/GeneralInstaller.ts +48 -10
- package/src/core/installers/requirements/InstallerFactory.ts +4 -3
- package/src/core/installers/requirements/NpmInstaller.ts +90 -68
- package/src/core/installers/requirements/PipInstaller.ts +81 -55
- package/src/core/installers/requirements/RequirementInstaller.ts +4 -3
- package/src/core/loaders/InstallOperationManager.ts +367 -0
- package/src/core/loaders/SystemSettingsManager.ts +278 -0
- package/src/core/metadatas/constants.ts +9 -0
- package/src/core/metadatas/recordingConstants.ts +62 -0
- package/src/core/metadatas/types.ts +23 -0
- package/src/core/onboard/FeedOnboardService.ts +59 -5
- package/src/core/onboard/OnboardStatusManager.ts +2 -1
- package/src/core/validators/StdioServerValidator.ts +4 -3
- package/src/services/InstallationService.ts +54 -399
- package/src/services/MCPManager.ts +61 -64
- package/src/services/RequirementService.ts +564 -67
- package/src/services/ServerService.ts +0 -90
- package/src/services/TelemetryService.ts +59 -0
- package/src/utils/adoUtils.ts +6 -4
- package/src/utils/githubAuth.ts +84 -1
- package/src/utils/logger.ts +83 -1
- package/src/utils/macroExpressionUtils.ts +4 -21
- package/src/utils/osUtils.ts +92 -1
- package/src/utils/versionUtils.ts +98 -13
- package/src/web/public/css/modal.css +292 -1
- package/src/web/public/css/serverCategoryList.css +120 -0
- package/src/web/public/css/serverDetails.css +14 -1
- package/src/web/public/index.html +126 -21
- package/src/web/public/js/flights/flights.js +1 -1
- package/src/web/public/js/modal/index.js +8 -14
- package/src/web/public/js/modal/installModal.js +3 -4
- package/src/web/public/js/modal/installation.js +122 -137
- package/src/web/public/js/modal/loadingModal.js +155 -25
- package/src/web/public/js/modal/modalSetup.js +125 -43
- package/src/web/public/js/modal/modalUtils.js +0 -12
- package/src/web/public/js/modal.js +23 -10
- package/src/web/public/js/onboard/formProcessor.js +18 -11
- package/src/web/public/js/onboard/publishHandler.js +35 -3
- package/src/web/public/js/onboard/templates.js +5 -1
- package/src/web/public/js/onboard/uiHandlers.js +266 -39
- package/src/web/public/js/onboard/validationHandlers.js +71 -39
- package/src/web/public/js/serverCategoryDetails.js +60 -11
- package/src/web/public/js/serverCategoryList.js +93 -9
- package/src/web/public/js/settings.js +314 -0
- package/src/web/public/onboard.html +2 -2
- package/src/web/public/settings.html +135 -0
- package/src/web/public/styles.css +32 -0
- package/src/web/server.ts +96 -1
- 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/modalUI.js +0 -214
- package/dist/web/public/js/modal/version.js +0 -20
- package/src/web/public/js/modal/messageQueue.js +0 -112
|
@@ -2,6 +2,7 @@ import { OSType } 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';
|
|
5
|
+
import * as RecordingConstants from '../../metadatas/recordingConstants.js';
|
|
5
6
|
/**
|
|
6
7
|
* Installer implementation for command-line tools
|
|
7
8
|
*/
|
|
@@ -122,8 +123,15 @@ export class CommandInstaller extends BaseInstaller {
|
|
|
122
123
|
* @param requirement The requirement to install
|
|
123
124
|
* @returns The status of the installation
|
|
124
125
|
*/
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Install the command
|
|
128
|
+
* @param requirement The requirement to install
|
|
129
|
+
* @param options Optional install options
|
|
130
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
131
|
+
* @returns The status of the installation
|
|
132
|
+
*/
|
|
133
|
+
async install(requirement, recorder, options) {
|
|
134
|
+
const doInstall = async () => {
|
|
127
135
|
const status = await this.checkInstallation(requirement);
|
|
128
136
|
if (status.installed) {
|
|
129
137
|
return status;
|
|
@@ -132,20 +140,20 @@ export class CommandInstaller extends BaseInstaller {
|
|
|
132
140
|
const osType = getOSType();
|
|
133
141
|
let installCommand;
|
|
134
142
|
if (osType === OSType.Windows) {
|
|
135
|
-
// Windows installation using winget
|
|
136
143
|
installCommand = `winget install --id ${packageId}`;
|
|
137
144
|
if (requirement.version && requirement.version !== 'latest') {
|
|
138
145
|
installCommand += ` --version ${requirement.version}`;
|
|
139
146
|
}
|
|
140
147
|
}
|
|
141
148
|
else if (osType === OSType.MacOS) {
|
|
142
|
-
// macOS installation using Homebrew
|
|
143
149
|
installCommand = `brew install ${packageId}`;
|
|
144
150
|
if (requirement.version && requirement.version !== 'latest') {
|
|
145
151
|
installCommand += `@${requirement.version}`;
|
|
146
152
|
}
|
|
147
153
|
}
|
|
148
154
|
else {
|
|
155
|
+
if (recorder)
|
|
156
|
+
await recorder.recordStep('CommandInstaller:UnsupportedOS', 'failed', `Unsupported OS for ${requirement.name}`);
|
|
149
157
|
throw new Error(`Unsupported operating system for installing ${requirement.name}`);
|
|
150
158
|
}
|
|
151
159
|
// Execute the installation command
|
|
@@ -165,15 +173,41 @@ export class CommandInstaller extends BaseInstaller {
|
|
|
165
173
|
version: updatedStatus.version || requirement.version,
|
|
166
174
|
inProgress: false
|
|
167
175
|
};
|
|
176
|
+
};
|
|
177
|
+
if (recorder) {
|
|
178
|
+
return recorder.recording(doInstall, {
|
|
179
|
+
stepName: RecordingConstants.STEP_COMMAND_INSTALLER_INSTALL,
|
|
180
|
+
inProgressMessage: `Installing command: ${requirement.name}`,
|
|
181
|
+
endMessage: (result) => result.installed
|
|
182
|
+
? `Install completed for ${requirement.name}`
|
|
183
|
+
: `Install failed for ${requirement.name}`,
|
|
184
|
+
onError: (error) => {
|
|
185
|
+
return {
|
|
186
|
+
result: {
|
|
187
|
+
name: requirement.name,
|
|
188
|
+
type: 'command',
|
|
189
|
+
installed: false,
|
|
190
|
+
error: error instanceof Error ? error.message : String(error),
|
|
191
|
+
inProgress: false,
|
|
192
|
+
},
|
|
193
|
+
message: error instanceof Error ? error.message : String(error),
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
});
|
|
168
197
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
198
|
+
else {
|
|
199
|
+
try {
|
|
200
|
+
return await doInstall();
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
return {
|
|
204
|
+
name: requirement.name,
|
|
205
|
+
type: 'command',
|
|
206
|
+
installed: false,
|
|
207
|
+
error: error instanceof Error ? error.message : String(error),
|
|
208
|
+
inProgress: false,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
177
211
|
}
|
|
178
212
|
}
|
|
179
213
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
|
|
2
2
|
import { BaseInstaller } from './BaseInstaller.js';
|
|
3
|
+
import { InstallOperationManager } from '../../loaders/InstallOperationManager.js';
|
|
3
4
|
/**
|
|
4
5
|
* Installer implementation for general requirements (type 'other')
|
|
5
6
|
* This installer handles requirements that don't fit into specific package manager categories
|
|
@@ -34,5 +35,14 @@ export declare class GeneralInstaller extends BaseInstaller {
|
|
|
34
35
|
* @param requirement The requirement to install
|
|
35
36
|
* @returns The status of the installation, including the install path in updateInfo
|
|
36
37
|
*/
|
|
37
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Install the general requirement
|
|
40
|
+
* For type 'other', this doesn't actually install anything, but downloads
|
|
41
|
+
* or locates the asset and returns the path for the caller to use
|
|
42
|
+
* @param requirement The requirement to install
|
|
43
|
+
* @param options Optional install options
|
|
44
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
45
|
+
* @returns The status of the installation, including the install path in updateInfo
|
|
46
|
+
*/
|
|
47
|
+
install(requirement: RequirementConfig, recorder: InstallOperationManager, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
38
48
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BaseInstaller } from './BaseInstaller.js';
|
|
2
2
|
import { handleGitHubRelease } from '../../../utils/githubUtils.js';
|
|
3
3
|
import { handleArtifact } from '../../../utils/adoUtils.js';
|
|
4
|
+
import * as RecordingConstants from '../../metadatas/recordingConstants.js';
|
|
4
5
|
/**
|
|
5
6
|
* Installer implementation for general requirements (type 'other')
|
|
6
7
|
* This installer handles requirements that don't fit into specific package manager categories
|
|
@@ -50,8 +51,17 @@ export class GeneralInstaller extends BaseInstaller {
|
|
|
50
51
|
* @param requirement The requirement to install
|
|
51
52
|
* @returns The status of the installation, including the install path in updateInfo
|
|
52
53
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Install the general requirement
|
|
56
|
+
* For type 'other', this doesn't actually install anything, but downloads
|
|
57
|
+
* or locates the asset and returns the path for the caller to use
|
|
58
|
+
* @param requirement The requirement to install
|
|
59
|
+
* @param options Optional install options
|
|
60
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
61
|
+
* @returns The status of the installation, including the install path in updateInfo
|
|
62
|
+
*/
|
|
63
|
+
async install(requirement, recorder, options) {
|
|
64
|
+
const doInstall = async () => {
|
|
55
65
|
// For type 'other', a registry must be specified
|
|
56
66
|
if (!requirement.registry) {
|
|
57
67
|
throw new Error('Registry must be specified for requirement type "other"');
|
|
@@ -76,15 +86,41 @@ export class GeneralInstaller extends BaseInstaller {
|
|
|
76
86
|
version: requirement.version,
|
|
77
87
|
inProgress: false,
|
|
78
88
|
};
|
|
89
|
+
};
|
|
90
|
+
if (recorder) {
|
|
91
|
+
return recorder.recording(doInstall, {
|
|
92
|
+
stepName: RecordingConstants.STEP_GENERAL_INSTALLER_INSTALL,
|
|
93
|
+
inProgressMessage: `Installing general requirement: ${requirement.name}`,
|
|
94
|
+
endMessage: (result) => result.installed
|
|
95
|
+
? `Install completed for ${requirement.name}`
|
|
96
|
+
: `Install failed for ${requirement.name}`,
|
|
97
|
+
onError: (error) => {
|
|
98
|
+
return {
|
|
99
|
+
result: {
|
|
100
|
+
name: requirement.name,
|
|
101
|
+
type: 'other',
|
|
102
|
+
installed: false,
|
|
103
|
+
error: error instanceof Error ? error.message : String(error),
|
|
104
|
+
inProgress: false,
|
|
105
|
+
},
|
|
106
|
+
message: error instanceof Error ? error.message : String(error),
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
});
|
|
79
110
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
111
|
+
else {
|
|
112
|
+
try {
|
|
113
|
+
return await doInstall();
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
return {
|
|
117
|
+
name: requirement.name,
|
|
118
|
+
type: 'other',
|
|
119
|
+
installed: false,
|
|
120
|
+
error: error instanceof Error ? error.message : String(error),
|
|
121
|
+
inProgress: false,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
88
124
|
}
|
|
89
125
|
}
|
|
90
126
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
|
|
2
2
|
import { RequirementInstaller } from './RequirementInstaller.js';
|
|
3
3
|
import { exec } from 'child_process';
|
|
4
|
+
import { InstallOperationManager } from '../../loaders/InstallOperationManager.js';
|
|
4
5
|
/**
|
|
5
6
|
* Factory for creating the appropriate installer for a requirement
|
|
6
7
|
*/
|
|
@@ -34,10 +35,11 @@ export declare class InstallerFactory {
|
|
|
34
35
|
/**
|
|
35
36
|
* Install a requirement using the appropriate installer
|
|
36
37
|
* @param requirement The requirement to install
|
|
38
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
37
39
|
* @param options Installation options including python environment
|
|
38
40
|
* @returns The installation status
|
|
39
41
|
*/
|
|
40
|
-
install(requirement: RequirementConfig, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
42
|
+
install(requirement: RequirementConfig, recorder: InstallOperationManager, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
41
43
|
/**
|
|
42
44
|
* Check the installation status of a requirement
|
|
43
45
|
* @param requirement The requirement to check
|
|
@@ -50,10 +50,11 @@ export class InstallerFactory {
|
|
|
50
50
|
/**
|
|
51
51
|
* Install a requirement using the appropriate installer
|
|
52
52
|
* @param requirement The requirement to install
|
|
53
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
53
54
|
* @param options Installation options including python environment
|
|
54
55
|
* @returns The installation status
|
|
55
56
|
*/
|
|
56
|
-
async install(requirement, options) {
|
|
57
|
+
async install(requirement, recorder, options) {
|
|
57
58
|
const installer = this.getInstaller(requirement);
|
|
58
59
|
if (!installer) {
|
|
59
60
|
return {
|
|
@@ -64,7 +65,7 @@ export class InstallerFactory {
|
|
|
64
65
|
inProgress: false
|
|
65
66
|
};
|
|
66
67
|
}
|
|
67
|
-
return await installer.install(requirement, options);
|
|
68
|
+
return await installer.install(requirement, recorder, options);
|
|
68
69
|
}
|
|
69
70
|
/**
|
|
70
71
|
* Check the installation status of a requirement
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
|
|
2
2
|
import { BaseInstaller } from './BaseInstaller.js';
|
|
3
|
+
import { InstallOperationManager } from '../../loaders/InstallOperationManager.js';
|
|
3
4
|
/**
|
|
4
5
|
* Installer implementation for NPM packages
|
|
5
6
|
*/
|
|
@@ -58,8 +59,9 @@ export declare class NpmInstaller extends BaseInstaller {
|
|
|
58
59
|
/**
|
|
59
60
|
* Install the NPM package.
|
|
60
61
|
* @param requirement The requirement to install.
|
|
61
|
-
* @param
|
|
62
|
+
* @param recorder Optional InstallOperationManager for recording steps.
|
|
63
|
+
* @param options Installation options.
|
|
62
64
|
* @returns The status of the installation.
|
|
63
65
|
*/
|
|
64
|
-
install(requirement: RequirementConfig, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
66
|
+
install(requirement: RequirementConfig, recorder: InstallOperationManager, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
65
67
|
}
|
|
@@ -7,6 +7,7 @@ import path from 'path';
|
|
|
7
7
|
import fs from 'fs/promises';
|
|
8
8
|
import { SETTINGS_DIR } from '../../metadatas/constants.js'; // Corrected path
|
|
9
9
|
import { Logger } from '../../../utils/logger.js';
|
|
10
|
+
import * as RecordingConstants from '../../metadatas/recordingConstants.js';
|
|
10
11
|
/**
|
|
11
12
|
* Installer implementation for NPM packages
|
|
12
13
|
*/
|
|
@@ -136,13 +137,13 @@ export class NpmInstaller extends BaseInstaller {
|
|
|
136
137
|
* @param targetDir Target directory for installation.
|
|
137
138
|
* @returns The installed version of the package.
|
|
138
139
|
*/
|
|
139
|
-
async _installPackage(requirement, packageSource, targetDir) {
|
|
140
|
+
async _installPackage(requirement, packageSource, targetDir, recorder) {
|
|
140
141
|
Logger.debug(`Installing NPM package from "${packageSource}" into "${targetDir}"`);
|
|
141
142
|
await fs.mkdir(targetDir, { recursive: true });
|
|
142
143
|
const installCommand = `npm install ${packageSource} --prefix "${targetDir}"`;
|
|
143
144
|
Logger.debug(`Executing install command: ${installCommand}`);
|
|
144
145
|
const requirementName = this._getRequirementName(requirement);
|
|
145
|
-
|
|
146
|
+
return await recorder.recording(async () => {
|
|
146
147
|
const { stdout: installStdout, stderr: installStderr } = await this.execPromise(installCommand);
|
|
147
148
|
Logger.debug(`NPM install stdout for ${packageSource} in ${targetDir}: ${installStdout}`);
|
|
148
149
|
if (installStderr && !installStderr.toLowerCase().includes('added') && !installStderr.toLowerCase().includes('updated') && !installStderr.toLowerCase().includes('found 0 vulnerabilities')) {
|
|
@@ -155,24 +156,28 @@ export class NpmInstaller extends BaseInstaller {
|
|
|
155
156
|
return { version: installedVersion };
|
|
156
157
|
}
|
|
157
158
|
else {
|
|
158
|
-
throw new Error(`Successfully ran npm install for ${packageSource}, but ${requirement.name} version could not be determined via npm list in ${targetDir}
|
|
159
|
+
throw new Error(`Successfully ran npm install for ${packageSource}, but ${requirement.name} version could not be determined via npm list in ${targetDir}, stderr: ${installStderr}`);
|
|
159
160
|
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
}, {
|
|
162
|
+
stepName: RecordingConstants.STEP_INSTALLATION_COMMAND_EXECUTION,
|
|
163
|
+
inProgressMessage: `Running: ${installCommand}`,
|
|
164
|
+
onError: (error) => {
|
|
165
|
+
Logger.error(`Error during NPM installation: ${error instanceof Error ? error.message : String(error)}`);
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
165
169
|
}
|
|
166
170
|
/**
|
|
167
171
|
* Install the NPM package.
|
|
168
172
|
* @param requirement The requirement to install.
|
|
169
|
-
* @param
|
|
173
|
+
* @param recorder Optional InstallOperationManager for recording steps.
|
|
174
|
+
* @param options Installation options.
|
|
170
175
|
* @returns The status of the installation.
|
|
171
176
|
*/
|
|
172
|
-
async install(requirement, options) {
|
|
177
|
+
async install(requirement, recorder, options) {
|
|
173
178
|
const targetDir = options?.settings?.folderName || this._getRequirementFolderPath(requirement);
|
|
174
179
|
await fs.mkdir(targetDir, { recursive: true });
|
|
175
|
-
|
|
180
|
+
return recorder.recording(async () => {
|
|
176
181
|
const status = await this.checkInstallation(requirement, { settings: { folderName: targetDir } });
|
|
177
182
|
if (status.installed && status.version && compareVersions(status.version, requirement.version) === 0 && !requirement.version.toLowerCase().includes('latest')) {
|
|
178
183
|
Logger.log(`${requirement.name}@${status.version} already installed in ${targetDir}.`);
|
|
@@ -192,10 +197,12 @@ export class NpmInstaller extends BaseInstaller {
|
|
|
192
197
|
resolvedVersion = adoResult.version;
|
|
193
198
|
}
|
|
194
199
|
else {
|
|
200
|
+
if (recorder)
|
|
201
|
+
await recorder.recordStep('NpmInstaller:RegistryConfig', 'failed', 'Invalid registry configuration for npm.');
|
|
195
202
|
throw new Error('Invalid registry configuration for npm.');
|
|
196
203
|
}
|
|
197
204
|
}
|
|
198
|
-
const finalInstallResult = await this._installPackage(requirement, packageToInstall, targetDir);
|
|
205
|
+
const finalInstallResult = await this._installPackage(requirement, packageToInstall, targetDir, recorder);
|
|
199
206
|
resolvedVersion = finalInstallResult.version;
|
|
200
207
|
return {
|
|
201
208
|
name: requirement.name,
|
|
@@ -205,16 +212,25 @@ export class NpmInstaller extends BaseInstaller {
|
|
|
205
212
|
inProgress: false,
|
|
206
213
|
npmPath: targetDir
|
|
207
214
|
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
215
|
+
}, {
|
|
216
|
+
stepName: RecordingConstants.STEP_NPM_INSTALLER_INSTALL,
|
|
217
|
+
inProgressMessage: `Installing npm package: ${requirement.name}`,
|
|
218
|
+
endMessage: (result) => result.installed
|
|
219
|
+
? `Install completed for ${requirement.name}`
|
|
220
|
+
: `Install failed for ${requirement.name}`,
|
|
221
|
+
onError: (error) => {
|
|
222
|
+
return {
|
|
223
|
+
result: {
|
|
224
|
+
name: requirement.name,
|
|
225
|
+
type: 'npm',
|
|
226
|
+
installed: false,
|
|
227
|
+
error: error instanceof Error ? error.message : String(error),
|
|
228
|
+
inProgress: false
|
|
229
|
+
},
|
|
230
|
+
message: error instanceof Error ? error.message : String(error),
|
|
231
|
+
};
|
|
232
|
+
},
|
|
233
|
+
});
|
|
218
234
|
}
|
|
219
235
|
}
|
|
220
236
|
//# sourceMappingURL=NpmInstaller.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
|
|
2
2
|
import { BaseInstaller } from './BaseInstaller.js';
|
|
3
|
+
import { InstallOperationManager } from '../../loaders/InstallOperationManager.js';
|
|
3
4
|
/**
|
|
4
5
|
* Installer implementation for Python packages using pip
|
|
5
6
|
*/
|
|
@@ -30,8 +31,9 @@ export declare class PipInstaller extends BaseInstaller {
|
|
|
30
31
|
/**
|
|
31
32
|
* Install the Python package
|
|
32
33
|
* @param requirement The requirement to install
|
|
34
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
33
35
|
* @param options Optional server install options
|
|
34
36
|
* @returns The status of the installation
|
|
35
37
|
*/
|
|
36
|
-
install(requirement: RequirementConfig, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
38
|
+
install(requirement: RequirementConfig, recorder: InstallOperationManager, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
37
39
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseInstaller } from './BaseInstaller.js';
|
|
2
2
|
import { handleGitHubRelease, getGitHubLatestVersion } from '../../../utils/githubUtils.js';
|
|
3
|
-
// Assuming getArtifactLatestVersion will be available in adoUtils.ts
|
|
4
3
|
import { handleArtifact as handleAdoArtifact, getArtifactLatestVersion } from '../../../utils/adoUtils.js';
|
|
5
4
|
import { compareVersions } from '../../../utils/versionUtils.js';
|
|
6
5
|
import { Logger } from '../../../utils/logger.js';
|
|
6
|
+
import * as RecordingConstants from '../../metadatas/recordingConstants.js';
|
|
7
7
|
/**
|
|
8
8
|
* Installer implementation for Python packages using pip
|
|
9
9
|
*/
|
|
@@ -105,21 +105,25 @@ export class PipInstaller extends BaseInstaller {
|
|
|
105
105
|
/**
|
|
106
106
|
* Install the Python package
|
|
107
107
|
* @param requirement The requirement to install
|
|
108
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
108
109
|
* @param options Optional server install options
|
|
109
110
|
* @returns The status of the installation
|
|
110
111
|
*/
|
|
111
|
-
async install(requirement, options) {
|
|
112
|
-
|
|
112
|
+
async install(requirement, recorder, options) {
|
|
113
|
+
return await recorder.recording(async () => {
|
|
113
114
|
const status = await this.checkInstallation(requirement, options);
|
|
114
115
|
if (status.installed && status.version && compareVersions(status.version, requirement.version) === 0 && !requirement.version.toLowerCase().includes('latest')) {
|
|
115
116
|
Logger.log(`${requirement.name}==${status.version} already installed for ${this.getPythonCommand}.`);
|
|
116
117
|
return status;
|
|
117
118
|
}
|
|
118
119
|
const pipCmd = this.getPipCommand(options);
|
|
120
|
+
let command;
|
|
119
121
|
if (!requirement.registry) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
if (requirement.version && !requirement.version.includes('latest')) {
|
|
123
|
+
command = `${pipCmd} install ${requirement.name}==${requirement.version}`;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
command = `${pipCmd} install --upgrade ${requirement.name}`;
|
|
123
127
|
}
|
|
124
128
|
}
|
|
125
129
|
else {
|
|
@@ -127,45 +131,63 @@ export class PipInstaller extends BaseInstaller {
|
|
|
127
131
|
if (requirement.registry.githubRelease) {
|
|
128
132
|
const result = await handleGitHubRelease(requirement, requirement.registry.githubRelease);
|
|
129
133
|
packageSource = result.resolvedPath;
|
|
130
|
-
|
|
131
|
-
if (stderr && stderr.toLowerCase().includes('error')) {
|
|
132
|
-
throw new Error(stderr);
|
|
133
|
-
}
|
|
134
|
+
command = `${pipCmd} install "${packageSource}"`;
|
|
134
135
|
}
|
|
135
136
|
else if (requirement.registry.artifacts) {
|
|
136
137
|
const pythonCmd = this.getPythonCommand(options);
|
|
137
138
|
const adoArtifactResult = await handleAdoArtifact(requirement, requirement.registry.artifacts, pythonCmd);
|
|
138
|
-
|
|
139
|
-
if (stderr && stderr.toLowerCase().includes('error')) {
|
|
140
|
-
const checkStatus = await this.checkInstallation(requirement, options);
|
|
141
|
-
if (!checkStatus.installed) {
|
|
142
|
-
throw new Error(`Pip installation failed with: ${stderr}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
139
|
+
command = `${pipCmd} install ${adoArtifactResult.package} --extra-index-url ${adoArtifactResult.registryUrl}`;
|
|
145
140
|
}
|
|
146
141
|
else {
|
|
142
|
+
await recorder.recordStep('PipInstaller:RegistryConfig', 'failed', 'Invalid registry configuration');
|
|
147
143
|
throw new Error('Invalid registry configuration');
|
|
148
144
|
}
|
|
149
145
|
}
|
|
150
|
-
return {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
146
|
+
return await recorder.recording(async () => {
|
|
147
|
+
const { stderr } = await this.execPromise(command);
|
|
148
|
+
if (stderr && stderr.toLowerCase().includes('error')) {
|
|
149
|
+
Logger.debug(`Pip installation error: ${stderr}`);
|
|
150
|
+
// wait for 5 seconds as python pip would be little delayed
|
|
151
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
152
|
+
const checkStatus = await this.checkInstallation(requirement, options);
|
|
153
|
+
if (!checkStatus.installed) {
|
|
154
|
+
Logger.error(`Package not found after the command, ${stderr}`);
|
|
155
|
+
throw new Error(`Pip installation failed with: ${stderr}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
name: requirement.name,
|
|
160
|
+
type: 'pip',
|
|
161
|
+
installed: true,
|
|
162
|
+
version: requirement.version, // This might need to be updated to actual installed version
|
|
163
|
+
inProgress: false,
|
|
164
|
+
pythonEnv: this.getPythonCommand(options)
|
|
165
|
+
};
|
|
166
|
+
}, {
|
|
167
|
+
stepName: `${RecordingConstants.STEP_INSTALL_COMMAND_PREFIX}: ${requirement.name} : ${requirement.version}`,
|
|
168
|
+
inProgressMessage: `Running: ${command}`,
|
|
169
|
+
endMessage: (result) => result.installed ? `Succeeded: ${command}` : `Failed: ${command}`,
|
|
170
|
+
});
|
|
171
|
+
}, {
|
|
172
|
+
stepName: RecordingConstants.STEP_PIP_INSTALLER_INSTALL,
|
|
173
|
+
inProgressMessage: `Installing pip package: ${requirement.name}`,
|
|
174
|
+
endMessage: (result) => result.installed
|
|
175
|
+
? `Install completed for ${requirement.name} with version ${result.version}`
|
|
176
|
+
: `Install failed for ${requirement.name}`,
|
|
177
|
+
onError: (error) => {
|
|
178
|
+
return {
|
|
179
|
+
result: {
|
|
180
|
+
name: requirement.name,
|
|
181
|
+
type: 'pip',
|
|
182
|
+
installed: false,
|
|
183
|
+
error: error instanceof Error ? error.message : String(error),
|
|
184
|
+
inProgress: false,
|
|
185
|
+
pythonEnv: this.getPythonCommand(options)
|
|
186
|
+
},
|
|
187
|
+
message: error instanceof Error ? error.message : String(error),
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
});
|
|
169
191
|
}
|
|
170
192
|
}
|
|
171
193
|
//# sourceMappingURL=PipInstaller.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RequirementConfig, RequirementStatus, ServerInstallOptions } from '../../metadatas/types.js';
|
|
2
|
+
import { InstallOperationManager } from '../../loaders/InstallOperationManager.js';
|
|
2
3
|
/**
|
|
3
4
|
* Interface for requirement installers.
|
|
4
5
|
* Implementations should handle specific requirement types.
|
|
@@ -14,9 +15,11 @@ export interface RequirementInstaller {
|
|
|
14
15
|
/**
|
|
15
16
|
* Install the requirement
|
|
16
17
|
* @param requirement The requirement to install
|
|
18
|
+
* @param options Optional install options
|
|
19
|
+
* @param recorder Optional InstallOperationManager for recording steps
|
|
17
20
|
* @returns The status of the installation
|
|
18
21
|
*/
|
|
19
|
-
install(requirement: RequirementConfig, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
22
|
+
install(requirement: RequirementConfig, recorder: InstallOperationManager, options?: ServerInstallOptions): Promise<RequirementStatus>;
|
|
20
23
|
/**
|
|
21
24
|
* Check if the requirement is already installed
|
|
22
25
|
* @param requirement The requirement to check
|