imcp 0.0.13 → 0.0.15
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/core/ConfigurationProvider.d.ts +1 -0
- package/dist/core/ConfigurationProvider.js +15 -0
- package/dist/core/InstallationService.js +2 -7
- package/dist/core/MCPManager.d.ts +11 -2
- package/dist/core/MCPManager.js +24 -1
- package/dist/core/RequirementService.js +2 -8
- package/dist/core/installers/clients/BaseClientInstaller.d.ts +51 -0
- package/dist/core/installers/clients/BaseClientInstaller.js +160 -0
- package/dist/core/installers/clients/ClientInstaller.d.ts +16 -8
- package/dist/core/installers/clients/ClientInstaller.js +77 -504
- package/dist/core/installers/clients/ClientInstallerFactory.d.ts +19 -0
- package/dist/core/installers/clients/ClientInstallerFactory.js +41 -0
- package/dist/core/installers/clients/ClineInstaller.d.ts +18 -0
- package/dist/core/installers/clients/ClineInstaller.js +124 -0
- package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +34 -0
- package/dist/core/installers/clients/GithubCopilotInstaller.js +162 -0
- package/dist/core/installers/clients/MSRooCodeInstaller.d.ts +15 -0
- package/dist/core/installers/clients/MSRooCodeInstaller.js +122 -0
- package/dist/core/installers/requirements/BaseInstaller.d.ts +11 -34
- package/dist/core/installers/requirements/BaseInstaller.js +5 -116
- package/dist/core/installers/requirements/CommandInstaller.d.ts +6 -1
- package/dist/core/installers/requirements/CommandInstaller.js +7 -0
- package/dist/core/installers/requirements/GeneralInstaller.d.ts +6 -1
- package/dist/core/installers/requirements/GeneralInstaller.js +9 -4
- package/dist/core/installers/requirements/NpmInstaller.d.ts +46 -7
- package/dist/core/installers/requirements/NpmInstaller.js +150 -58
- package/dist/core/installers/requirements/PipInstaller.d.ts +9 -0
- package/dist/core/installers/requirements/PipInstaller.js +66 -28
- package/dist/core/onboard/FeedOnboardService.d.ts +72 -0
- package/dist/core/onboard/FeedOnboardService.js +312 -0
- package/dist/core/onboard/OnboardProcessor.d.ts +79 -0
- package/dist/core/onboard/OnboardProcessor.js +290 -0
- package/dist/core/onboard/OnboardStatus.d.ts +49 -0
- package/dist/core/onboard/OnboardStatus.js +10 -0
- package/dist/core/onboard/OnboardStatusManager.d.ts +57 -0
- package/dist/core/onboard/OnboardStatusManager.js +176 -0
- package/dist/core/types.d.ts +6 -6
- package/dist/core/validators/FeedValidator.d.ts +20 -0
- package/dist/core/validators/FeedValidator.js +80 -0
- package/dist/core/validators/IServerValidator.d.ts +19 -0
- package/dist/core/validators/IServerValidator.js +2 -0
- package/dist/core/validators/SSEServerValidator.d.ts +15 -0
- package/dist/core/validators/SSEServerValidator.js +39 -0
- package/dist/core/validators/ServerValidatorFactory.d.ts +24 -0
- package/dist/core/validators/ServerValidatorFactory.js +45 -0
- package/dist/core/validators/StdioServerValidator.d.ts +46 -0
- package/dist/core/validators/StdioServerValidator.js +229 -0
- package/dist/services/InstallRequestValidator.d.ts +1 -1
- package/dist/services/ServerService.d.ts +9 -6
- package/dist/services/ServerService.js +18 -7
- package/dist/utils/adoUtils.d.ts +29 -0
- package/dist/utils/adoUtils.js +252 -0
- package/dist/utils/clientUtils.d.ts +0 -7
- package/dist/utils/clientUtils.js +0 -42
- package/dist/utils/githubUtils.d.ts +10 -0
- package/dist/utils/githubUtils.js +22 -0
- package/dist/utils/macroExpressionUtils.d.ts +38 -0
- package/dist/utils/macroExpressionUtils.js +116 -0
- package/dist/utils/osUtils.d.ts +4 -20
- package/dist/utils/osUtils.js +78 -23
- package/dist/web/contract/serverContract.d.ts +66 -0
- package/dist/web/contract/serverContract.js +2 -0
- package/dist/web/public/css/notifications.css +48 -17
- package/dist/web/public/css/onboard.css +107 -0
- package/dist/web/public/index.html +90 -18
- package/dist/web/public/js/api.js +3 -6
- package/dist/web/public/js/flights/flights.js +127 -0
- package/dist/web/public/js/modal/index.js +58 -0
- package/dist/web/public/js/modal/installHandler.js +227 -0
- package/dist/web/public/js/modal/installModal.js +163 -0
- package/dist/web/public/js/modal/installation.js +281 -0
- package/dist/web/public/js/modal/loadingModal.js +52 -0
- package/dist/web/public/js/modal/loadingUI.js +74 -0
- package/dist/web/public/js/modal/messageQueue.js +112 -0
- package/dist/web/public/js/modal/modalSetup.js +513 -0
- package/dist/web/public/js/modal/modalUI.js +214 -0
- package/dist/web/public/js/modal/modalUtils.js +49 -0
- package/dist/web/public/js/modal/version.js +20 -0
- package/dist/web/public/js/modal/versionUtils.js +20 -0
- package/dist/web/public/js/modal.js +25 -1041
- package/dist/web/public/js/notifications.js +66 -27
- package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +338 -0
- package/dist/web/public/js/onboard/formProcessor.js +864 -0
- package/dist/web/public/js/onboard/index.js +374 -0
- package/dist/web/public/js/onboard/publishHandler.js +132 -0
- package/dist/web/public/js/onboard/state.js +76 -0
- package/dist/web/public/js/onboard/templates.js +343 -0
- package/dist/web/public/js/onboard/uiHandlers.js +758 -0
- package/dist/web/public/js/onboard/validationHandlers.js +378 -0
- package/dist/web/public/js/serverCategoryDetails.js +43 -17
- package/dist/web/public/js/serverCategoryList.js +15 -2
- package/dist/web/public/onboard.html +296 -0
- package/dist/web/public/styles.css +91 -1
- package/dist/web/server.d.ts +0 -10
- package/dist/web/server.js +131 -22
- package/package.json +2 -2
- package/src/core/ConfigurationProvider.ts +15 -0
- package/src/core/InstallationService.ts +2 -7
- package/src/core/MCPManager.ts +26 -1
- package/src/core/RequirementService.ts +2 -9
- package/src/core/installers/clients/BaseClientInstaller.ts +196 -0
- package/src/core/installers/clients/ClientInstaller.ts +97 -589
- package/src/core/installers/clients/ClientInstallerFactory.ts +46 -0
- package/src/core/installers/clients/ClineInstaller.ts +135 -0
- package/src/core/installers/clients/GithubCopilotInstaller.ts +179 -0
- package/src/core/installers/clients/MSRooCodeInstaller.ts +133 -0
- package/src/core/installers/requirements/BaseInstaller.ts +13 -136
- package/src/core/installers/requirements/CommandInstaller.ts +9 -1
- package/src/core/installers/requirements/GeneralInstaller.ts +11 -4
- package/src/core/installers/requirements/NpmInstaller.ts +178 -61
- package/src/core/installers/requirements/PipInstaller.ts +68 -29
- package/src/core/onboard/FeedOnboardService.ts +346 -0
- package/src/core/onboard/OnboardProcessor.ts +305 -0
- package/src/core/onboard/OnboardStatus.ts +55 -0
- package/src/core/onboard/OnboardStatusManager.ts +188 -0
- package/src/core/types.ts +6 -6
- package/src/core/validators/FeedValidator.ts +79 -0
- package/src/core/validators/IServerValidator.ts +21 -0
- package/src/core/validators/SSEServerValidator.ts +43 -0
- package/src/core/validators/ServerValidatorFactory.ts +51 -0
- package/src/core/validators/StdioServerValidator.ts +259 -0
- package/src/services/InstallRequestValidator.ts +1 -1
- package/src/services/ServerService.ts +22 -7
- package/src/utils/adoUtils.ts +291 -0
- package/src/utils/clientUtils.ts +0 -44
- package/src/utils/githubUtils.ts +24 -0
- package/src/utils/macroExpressionUtils.ts +121 -0
- package/src/utils/osUtils.ts +89 -24
- package/src/web/contract/serverContract.ts +74 -0
- package/src/web/public/css/notifications.css +48 -17
- package/src/web/public/css/onboard.css +107 -0
- package/src/web/public/index.html +90 -18
- package/src/web/public/js/api.js +3 -6
- package/src/web/public/js/flights/flights.js +127 -0
- package/src/web/public/js/modal/index.js +58 -0
- package/src/web/public/js/modal/installModal.js +163 -0
- package/src/web/public/js/modal/installation.js +281 -0
- package/src/web/public/js/modal/loadingModal.js +52 -0
- package/src/web/public/js/modal/messageQueue.js +112 -0
- package/src/web/public/js/modal/modalSetup.js +513 -0
- package/src/web/public/js/modal/modalUtils.js +49 -0
- package/src/web/public/js/modal/versionUtils.js +20 -0
- package/src/web/public/js/modal.js +25 -1041
- package/src/web/public/js/notifications.js +66 -27
- package/src/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +338 -0
- package/src/web/public/js/onboard/formProcessor.js +864 -0
- package/src/web/public/js/onboard/index.js +374 -0
- package/src/web/public/js/onboard/publishHandler.js +132 -0
- package/src/web/public/js/onboard/state.js +76 -0
- package/src/web/public/js/onboard/templates.js +343 -0
- package/src/web/public/js/onboard/uiHandlers.js +758 -0
- package/src/web/public/js/onboard/validationHandlers.js +378 -0
- package/src/web/public/js/serverCategoryDetails.js +43 -17
- package/src/web/public/js/serverCategoryList.js +15 -2
- package/src/web/public/onboard.html +296 -0
- package/src/web/public/styles.css +91 -1
- package/src/web/server.ts +167 -58
package/src/utils/githubUtils.ts
CHANGED
|
@@ -9,6 +9,30 @@ import { SETTINGS_DIR } from '../core/constants.js';
|
|
|
9
9
|
|
|
10
10
|
const execAsync = util.promisify(exec);
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Get the latest version available for a GitHub repository
|
|
14
|
+
* @param execPromise The promise-based exec function
|
|
15
|
+
* @param repository The GitHub repository in format 'owner/repo'
|
|
16
|
+
* @returns The latest version or tag
|
|
17
|
+
*/
|
|
18
|
+
export async function getGitHubLatestVersion(execPromise: (command: string) => Promise<{ stdout: string; stderr: string }>, repository: string): Promise<string> {
|
|
19
|
+
try {
|
|
20
|
+
// Use GitHub CLI to get the latest release
|
|
21
|
+
const { stdout } = await execPromise(`gh release view --repo ${repository} --json tagName --jq .tagName`);
|
|
22
|
+
const latestTag = stdout.trim();
|
|
23
|
+
|
|
24
|
+
// Remove 'v' prefix if present
|
|
25
|
+
return latestTag.startsWith('v') ? latestTag.substring(1) : latestTag;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
// If gh command fails, try to get the latest tag
|
|
28
|
+
const { stdout } = await execPromise(`git ls-remote --tags --refs https://github.com/${repository}.git | sort -t '/' -k 3 -V | tail -n 1 | awk -F/ '{print $3}'`);
|
|
29
|
+
let latestTag = stdout.trim();
|
|
30
|
+
|
|
31
|
+
// Remove 'v' prefix if present
|
|
32
|
+
return latestTag.startsWith('v') ? latestTag.substring(1) : latestTag;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
12
36
|
interface DownloadGithubReleaseResult {
|
|
13
37
|
version: string;
|
|
14
38
|
downloadPath: string;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Logger } from './logger.js';
|
|
2
|
+
import { getPythonPackagePath, getSystemPythonPackageDirectory, GetBrowserPath } from './osUtils.js';
|
|
3
|
+
import { ServerInstallOptions } from '../core/types.js'; // Adjusted path
|
|
4
|
+
import * as fsSync from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
export const MACRO_EXPRESSIONS = {
|
|
9
|
+
PYTHON_PACKAGE: '${PYTHON_PACKAGE}',
|
|
10
|
+
NPMPATH: '${NPMPATH}',
|
|
11
|
+
BROWSER_PATH: '${BROWSER_PATH}',
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
// Define a map for macro keys to their resolver functions
|
|
15
|
+
export const MacroResolverFunctions: {
|
|
16
|
+
[key: string]: (finalConfig: any, options: ServerInstallOptions) => Promise<string | undefined>;
|
|
17
|
+
} = {
|
|
18
|
+
[MACRO_EXPRESSIONS.PYTHON_PACKAGE]: resolvePythonPackageMacro,
|
|
19
|
+
[MACRO_EXPRESSIONS.NPMPATH]: resolveNpmPathMacro,
|
|
20
|
+
[MACRO_EXPRESSIONS.BROWSER_PATH]: resolveBrowserPathMacro,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Resolves the path for the ${PYTHON_PACKAGE} macro.
|
|
25
|
+
* It considers the pythonEnv setting and falls back to system Python.
|
|
26
|
+
* Also updates finalConfig.command if it's 'python' and pythonEnv is used.
|
|
27
|
+
* @param finalConfig The configuration object (mutated for command).
|
|
28
|
+
* @param options Server installation options.
|
|
29
|
+
* @returns The resolved Python package path or undefined.
|
|
30
|
+
*/
|
|
31
|
+
export async function resolvePythonPackageMacro(finalConfig: any, options: ServerInstallOptions): Promise<string | undefined> {
|
|
32
|
+
const pythonEnv = options.settings?.pythonEnv;
|
|
33
|
+
if (pythonEnv) {
|
|
34
|
+
Logger.debug(`Python environment specified for ${MACRO_EXPRESSIONS.PYTHON_PACKAGE}: ${pythonEnv}`);
|
|
35
|
+
const pythonDir = getPythonPackagePath(pythonEnv);
|
|
36
|
+
if (pythonDir) {
|
|
37
|
+
if (finalConfig.command === 'python') {
|
|
38
|
+
Logger.debug(`Replacing command 'python' with specified pythonEnv: ${pythonEnv} due to ${MACRO_EXPRESSIONS.PYTHON_PACKAGE} resolution`);
|
|
39
|
+
finalConfig.command = pythonEnv;
|
|
40
|
+
}
|
|
41
|
+
return pythonDir;
|
|
42
|
+
}
|
|
43
|
+
Logger.debug(`Could not determine directory for pythonEnv: ${pythonEnv}. ${MACRO_EXPRESSIONS.PYTHON_PACKAGE} will not be replaced using this path.`);
|
|
44
|
+
return undefined;
|
|
45
|
+
} else {
|
|
46
|
+
Logger.debug(`No Python environment specified. Attempting to find system Python for ${MACRO_EXPRESSIONS.PYTHON_PACKAGE}.`);
|
|
47
|
+
const pythonDir = await getSystemPythonPackageDirectory();
|
|
48
|
+
if (pythonDir) {
|
|
49
|
+
return pythonDir;
|
|
50
|
+
}
|
|
51
|
+
Logger.debug(`Could not find system Python directory for ${MACRO_EXPRESSIONS.PYTHON_PACKAGE}.`);
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Resolves the actual NPM module path.
|
|
58
|
+
* It checks a provided path, then NVM, then global npm.
|
|
59
|
+
* @param providedNpmPath An optional, pre-configured NPM path.
|
|
60
|
+
* @returns The resolved NPM module path or undefined if an error occurs.
|
|
61
|
+
*/
|
|
62
|
+
export function resolveNpmModulePath(providedNpmPath: string | undefined): string {
|
|
63
|
+
if (providedNpmPath) {
|
|
64
|
+
return `${providedNpmPath}/node_modules`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const nvmHome = process.env.NVM_HOME;
|
|
68
|
+
if (nvmHome) {
|
|
69
|
+
try {
|
|
70
|
+
const nodeVersion = execSync('node -v').toString().trim();
|
|
71
|
+
const nvmNodePath = path.join(nvmHome, nodeVersion);
|
|
72
|
+
// Check if this path exists
|
|
73
|
+
try {
|
|
74
|
+
fsSync.accessSync(nvmNodePath);
|
|
75
|
+
Logger.debug(`Resolved ${MACRO_EXPRESSIONS.NPMPATH} via NVM to: ${nvmNodePath}`);
|
|
76
|
+
return nvmNodePath;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
Logger.debug(`NVM controlled path doesn't exist: ${nvmNodePath}, will try global npm`);
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
Logger.debug(`Error determining Node version for NVM: ${error}, will use global npm`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const globalNpmPath = execSync('npm root -g').toString().trim();
|
|
86
|
+
Logger.debug(`Resolved ${MACRO_EXPRESSIONS.NPMPATH} via global npm to: ${globalNpmPath}`);
|
|
87
|
+
return globalNpmPath;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolves the path to an NPM module for the ${NPMPATH} macro.
|
|
92
|
+
* Uses the resolveNpmModulePath function.
|
|
93
|
+
* @param _finalConfig Not used by this resolver.
|
|
94
|
+
* @param options Server installation options, may contain npmPath.
|
|
95
|
+
* @returns The resolved NPM path or undefined if an error occurs.
|
|
96
|
+
*/
|
|
97
|
+
export async function resolveNpmPathMacro(_finalConfig: any, options: ServerInstallOptions): Promise<string | undefined> {
|
|
98
|
+
Logger.debug(`Resolving ${MACRO_EXPRESSIONS.NPMPATH}. Provided npmPath from settings: ${options.settings?.npmPath}`);
|
|
99
|
+
try {
|
|
100
|
+
return resolveNpmModulePath(options.settings?.npmPath);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
Logger.error(`Failed to resolve ${MACRO_EXPRESSIONS.NPMPATH}:`, error);
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Resolves the path for the ${BROWSER_PATH} macro.
|
|
109
|
+
* @returns The system's browser path or undefined.
|
|
110
|
+
*/
|
|
111
|
+
export async function resolveBrowserPathMacro(): Promise<string | undefined> {
|
|
112
|
+
Logger.debug(`Resolving ${MACRO_EXPRESSIONS.BROWSER_PATH}`);
|
|
113
|
+
try {
|
|
114
|
+
const browserPath = await GetBrowserPath();
|
|
115
|
+
Logger.debug(`Resolved ${MACRO_EXPRESSIONS.BROWSER_PATH} to: ${browserPath}`);
|
|
116
|
+
return browserPath;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
Logger.error(`Failed to get system browser path for ${MACRO_EXPRESSIONS.BROWSER_PATH}:`, error);
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
package/src/utils/osUtils.ts
CHANGED
|
@@ -95,10 +95,7 @@ export async function installCLI(tool: 'gh' | 'git'): Promise<void> {
|
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* Refreshes the PATH environment variable for the current Node.js process
|
|
98
|
-
* This is necessary because when tools are installed using package managers,
|
|
99
|
-
* they update the system PATH but the current Node process doesn't see those changes.
|
|
100
98
|
*/
|
|
101
|
-
|
|
102
99
|
export async function refreshPathEnv(): Promise<void> {
|
|
103
100
|
const osType = getOSType();
|
|
104
101
|
Logger.debug({
|
|
@@ -151,6 +148,62 @@ export async function refreshPathEnv(): Promise<void> {
|
|
|
151
148
|
}
|
|
152
149
|
}
|
|
153
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Check if a command is available on the system
|
|
153
|
+
* Handles special cases for VS Code on different platforms
|
|
154
|
+
*/
|
|
155
|
+
export async function isCommandAvailable(command: string): Promise<boolean> {
|
|
156
|
+
try {
|
|
157
|
+
// For VS Code on macOS, check both command-line tool and app bundle
|
|
158
|
+
if (process.platform === 'darwin' && (command === 'code' || command === 'code-insiders')) {
|
|
159
|
+
try {
|
|
160
|
+
// Try which command first
|
|
161
|
+
await execAsync(`which ${command}`);
|
|
162
|
+
return true;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
// If which fails, check application bundles
|
|
165
|
+
const systemVSCodePath = command === 'code' ?
|
|
166
|
+
'/Applications/Visual Studio Code.app' :
|
|
167
|
+
'/Applications/Visual Studio Code - Insiders.app';
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// Check system Applications first
|
|
171
|
+
await execAsync(`test -d "${systemVSCodePath}"`);
|
|
172
|
+
return true;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
// If system Applications check fails, try user Applications
|
|
175
|
+
const homedir = process.env.HOME;
|
|
176
|
+
if (homedir) {
|
|
177
|
+
const userVSCodePath = command === 'code' ?
|
|
178
|
+
`${homedir}/Applications/Visual Studio Code.app` :
|
|
179
|
+
`${homedir}/Applications/Visual Studio Code - Insiders.app`;
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
await execAsync(`test -d "${userVSCodePath}"`);
|
|
183
|
+
return true;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// For Windows, use where command
|
|
194
|
+
if (process.platform === 'win32') {
|
|
195
|
+
await execAsync(`where ${command}`);
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// For all other cases (Unix-like systems), use which command
|
|
200
|
+
await execAsync(`which ${command}`);
|
|
201
|
+
return true;
|
|
202
|
+
} catch (error) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
154
207
|
export async function isToolInstalled(tool: 'gh' | 'git', retries = 3): Promise<boolean> {
|
|
155
208
|
try {
|
|
156
209
|
Logger.debug({
|
|
@@ -197,11 +250,6 @@ export async function isToolInstalled(tool: 'gh' | 'git', retries = 3): Promise<
|
|
|
197
250
|
}
|
|
198
251
|
}
|
|
199
252
|
|
|
200
|
-
/**
|
|
201
|
-
* Opens a URL in the default browser
|
|
202
|
-
* @param url The URL to open
|
|
203
|
-
* @returns A promise that resolves when the browser is launched
|
|
204
|
-
*/
|
|
205
253
|
export async function openBrowser(url: string): Promise<void> {
|
|
206
254
|
const osType = getOSType();
|
|
207
255
|
Logger.debug({
|
|
@@ -250,12 +298,6 @@ export async function openBrowser(url: string): Promise<void> {
|
|
|
250
298
|
}
|
|
251
299
|
}
|
|
252
300
|
|
|
253
|
-
/**
|
|
254
|
-
* Gets the directory containing Python packages (site-packages) based on Python executable path.
|
|
255
|
-
* Handles different Python installations (system, venv, conda) across different OS platforms.
|
|
256
|
-
* @param pythonExecutablePath The full path to the Python executable
|
|
257
|
-
* @returns The site-packages directory path
|
|
258
|
-
*/
|
|
259
301
|
export function getPythonPackagePath(pythonExecutablePath: string): string {
|
|
260
302
|
Logger.debug({
|
|
261
303
|
action: 'get_python_package_path',
|
|
@@ -268,8 +310,39 @@ export function getPythonPackagePath(pythonExecutablePath: string): string {
|
|
|
268
310
|
|
|
269
311
|
// Handle common Python installation patterns
|
|
270
312
|
if (isWindows) {
|
|
271
|
-
// Windows:
|
|
272
|
-
if (dir.endsWith('
|
|
313
|
+
// Windows: Handle different Python installations
|
|
314
|
+
if (dir.endsWith('WindowsApps')) {
|
|
315
|
+
// For Windows Store Python, find the actual Python installation directory
|
|
316
|
+
const entries = fs.readdirSync(dir);
|
|
317
|
+
const pythonDir = entries.find(e => e.startsWith('PythonSoftwareFoundation.Python'));
|
|
318
|
+
if (pythonDir && pythonDir.includes('.')) {
|
|
319
|
+
// Extract version from format like "PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0"
|
|
320
|
+
const parts = pythonDir.split('.');
|
|
321
|
+
const majorVer = parts[2];
|
|
322
|
+
const minorVer = parts[3].split('_')[0];
|
|
323
|
+
const version = majorVer + minorVer; // Combines "3" and "13" to "313"
|
|
324
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
325
|
+
|
|
326
|
+
if (localAppData) {
|
|
327
|
+
const sitePkgsPath = path.join(
|
|
328
|
+
localAppData,
|
|
329
|
+
'Packages',
|
|
330
|
+
pythonDir,
|
|
331
|
+
'LocalCache',
|
|
332
|
+
'local-packages',
|
|
333
|
+
'Python' + version,
|
|
334
|
+
'site-packages'
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
Logger.debug(`Resolved Windows Store Python site-packages path: ${sitePkgsPath}`);
|
|
338
|
+
return sitePkgsPath;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
Logger.debug('Could not resolve Windows Store Python site-packages path');
|
|
343
|
+
// Fallback to user's site-packages
|
|
344
|
+
return path.join(process.env.APPDATA || '', 'Python', 'Python3', 'site-packages');
|
|
345
|
+
} else if (dir.endsWith('Scripts')) {
|
|
273
346
|
// Virtual environment structure on Windows: <venv>/Scripts/python.exe
|
|
274
347
|
const venvRoot = path.dirname(dir);
|
|
275
348
|
return path.join(venvRoot, 'Lib', 'site-packages');
|
|
@@ -320,10 +393,6 @@ export function getPythonPackagePath(pythonExecutablePath: string): string {
|
|
|
320
393
|
}
|
|
321
394
|
}
|
|
322
395
|
|
|
323
|
-
/**
|
|
324
|
-
* Finds the directory of the system's default Python installation.
|
|
325
|
-
* @returns The directory path or null if not found.
|
|
326
|
-
*/
|
|
327
396
|
export async function getSystemPythonPackageDirectory(): Promise<string | null> {
|
|
328
397
|
const command = process.platform === 'win32' ? 'where python' : 'which python';
|
|
329
398
|
|
|
@@ -353,10 +422,6 @@ export async function getSystemPythonPackageDirectory(): Promise<string | null>
|
|
|
353
422
|
}
|
|
354
423
|
}
|
|
355
424
|
|
|
356
|
-
/**
|
|
357
|
-
* Gets the path of the system's default browser.
|
|
358
|
-
* @returns The path to the default browser executable.
|
|
359
|
-
*/
|
|
360
425
|
export async function GetBrowserPath(): Promise<string> {
|
|
361
426
|
const osType = getOSType();
|
|
362
427
|
Logger.debug({
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { DependencyConfig, RegistryConfig, ServerInstallOptions, EnvVariableConfig } from '../../core/types.js';
|
|
2
|
+
import { ServerSchema } from '../../core/ServerSchemaProvider.js';
|
|
3
|
+
|
|
4
|
+
export interface OnboardServerConfig {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
mode: 'stdio' | 'sse';
|
|
8
|
+
schemas?: string;
|
|
9
|
+
dependencies?: DependencyConfig;
|
|
10
|
+
repository?: string;
|
|
11
|
+
installation: {
|
|
12
|
+
command: string;
|
|
13
|
+
args?: string[];
|
|
14
|
+
env?: Record<string, {
|
|
15
|
+
name: string;
|
|
16
|
+
default?: string;
|
|
17
|
+
required: boolean;
|
|
18
|
+
description?: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type RequirementType = 'npm' | 'pip' | 'command' | 'extension' | 'other';
|
|
24
|
+
|
|
25
|
+
export interface OnboardRequirementConfig {
|
|
26
|
+
type: RequirementType;
|
|
27
|
+
name: string;
|
|
28
|
+
version: string;
|
|
29
|
+
alias?: string;
|
|
30
|
+
registry?: RegistryConfig;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface OnboardRequestBody {
|
|
34
|
+
categoryData: {
|
|
35
|
+
name: string;
|
|
36
|
+
displayName: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
repository?: string;
|
|
39
|
+
requirements?: OnboardRequirementConfig[];
|
|
40
|
+
mcpServers?: OnboardServerConfig[];
|
|
41
|
+
};
|
|
42
|
+
isUpdate: boolean;
|
|
43
|
+
forExistingCategory?: boolean;
|
|
44
|
+
serverName?: string; // Optional server name for server-specific operations
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ListQueryParams {
|
|
48
|
+
local?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface UpdateRequirementsRequestBody {
|
|
52
|
+
requirements: {
|
|
53
|
+
name: string;
|
|
54
|
+
updateVersion: string;
|
|
55
|
+
}[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface InstallServersRequestBody {
|
|
59
|
+
serverList: Record<string, ServerInstallOptions>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface UninstallServersRequestBody {
|
|
63
|
+
serverList: Record<string, { removeData?: boolean }>;
|
|
64
|
+
options: {
|
|
65
|
+
targets: string[];
|
|
66
|
+
removeData?: boolean;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ApiResponse<T> {
|
|
71
|
+
success: boolean;
|
|
72
|
+
data?: T;
|
|
73
|
+
error?: string;
|
|
74
|
+
}
|
|
@@ -2,53 +2,84 @@
|
|
|
2
2
|
.alert-container {
|
|
3
3
|
z-index: 999999; /* Extremely high to appear above modals */
|
|
4
4
|
position: fixed;
|
|
5
|
-
top:
|
|
6
|
-
|
|
7
|
-
right: 0 !important;
|
|
5
|
+
top: 20px; /* Adjusted for top-right positioning */
|
|
6
|
+
right: 20px; /* Adjusted for top-right positioning */
|
|
8
7
|
display: flex;
|
|
9
8
|
flex-direction: column;
|
|
10
|
-
align-items:
|
|
9
|
+
align-items: flex-end; /* Align items to the right */
|
|
11
10
|
gap: 10px;
|
|
12
11
|
pointer-events: none; /* Allow clicking through the container */
|
|
12
|
+
max-width: 350px; /* Max width for the container */
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.alert {
|
|
16
|
-
min-width:
|
|
17
|
-
max-width:
|
|
18
|
-
box-shadow: 0
|
|
16
|
+
min-width: 300px; /* Adjusted min-width */
|
|
17
|
+
max-width: 100%; /* Alert can take full width of container */
|
|
18
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); /* Softer shadow */
|
|
19
19
|
backdrop-filter: blur(8px);
|
|
20
|
-
border-width:
|
|
20
|
+
border-width: 1px; /* Thinner border */
|
|
21
|
+
border-radius: 8px; /* Rounded corners */
|
|
21
22
|
pointer-events: auto; /* Re-enable pointer events for alerts */
|
|
22
|
-
padding:
|
|
23
|
-
font-size:
|
|
23
|
+
padding: 12px 20px; /* Adjusted padding */
|
|
24
|
+
font-size: 0.95rem; /* Slightly smaller font size */
|
|
24
25
|
font-weight: 500;
|
|
25
|
-
|
|
26
|
+
display: flex; /* For icon and text alignment */
|
|
27
|
+
align-items: center; /* Vertically center icon and text */
|
|
28
|
+
opacity: 0; /* Start hidden for animation */
|
|
29
|
+
transform: translateX(100%); /* Start off-screen for slide-in */
|
|
30
|
+
transition: opacity 0.3s ease-out, transform 0.3s ease-out; /* Smooth animation */
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.alert.show {
|
|
34
|
+
opacity: 1;
|
|
35
|
+
transform: translateX(0);
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.alert:first-child {
|
|
29
39
|
margin-top: 0;
|
|
30
40
|
}
|
|
31
41
|
|
|
42
|
+
.alert-icon {
|
|
43
|
+
margin-right: 10px; /* Space between icon and text */
|
|
44
|
+
font-size: 1.2rem; /* Icon size */
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
.alert.alert-success {
|
|
33
|
-
background-color: rgba(
|
|
34
|
-
border-color: #
|
|
48
|
+
background-color: rgba(30, 136, 229, 0.9); /* Blue for success */
|
|
49
|
+
border-color: #1e88e5;
|
|
35
50
|
color: white;
|
|
36
|
-
font-weight: 500;
|
|
37
51
|
}
|
|
38
52
|
|
|
39
53
|
.alert.alert-error {
|
|
40
|
-
background-color: rgba(
|
|
41
|
-
border-color: #
|
|
54
|
+
background-color: rgba(229, 57, 53, 0.9); /* Red for error */
|
|
55
|
+
border-color: #e53935;
|
|
42
56
|
color: white;
|
|
43
|
-
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.alert.alert-info {
|
|
60
|
+
background-color: rgba(2, 136, 209, 0.9); /* Light blue for info */
|
|
61
|
+
border-color: #0288d1;
|
|
62
|
+
color: white;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.alert.alert-warning {
|
|
66
|
+
background-color: rgba(251, 192, 45, 0.9); /* Yellow for warning */
|
|
67
|
+
border-color: #fbc02d;
|
|
68
|
+
color: #333; /* Darker text for better contrast on yellow */
|
|
44
69
|
}
|
|
45
70
|
|
|
46
71
|
.alert .btn-close {
|
|
47
72
|
filter: brightness(0) invert(1);
|
|
48
73
|
opacity: 0.8;
|
|
49
74
|
padding: 0.75rem;
|
|
75
|
+
margin-left: auto; /* Push close button to the right */
|
|
50
76
|
}
|
|
51
77
|
|
|
78
|
+
.alert.alert-warning .btn-close {
|
|
79
|
+
filter: none; /* No filter for warning close button for better visibility */
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
52
83
|
/* When modal is open, add backdrop to alerts */
|
|
53
84
|
.modal.show ~ .alert-container .alert {
|
|
54
85
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* Onboarding form styles */
|
|
2
|
+
.requirement-item,
|
|
3
|
+
.server-item {
|
|
4
|
+
background-color: #ffffff;
|
|
5
|
+
transition: all 0.2s ease;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.requirement-item:hover,
|
|
9
|
+
.server-item:hover {
|
|
10
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.registry-config,
|
|
14
|
+
.installation-config,
|
|
15
|
+
.env-variables {
|
|
16
|
+
background-color: #f9fafb;
|
|
17
|
+
border-radius: 0.5rem;
|
|
18
|
+
padding: 0.75rem; /* Reduced padding */
|
|
19
|
+
margin-top: 0.75rem; /* Reduced margin-top */
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.registry-github,
|
|
23
|
+
.registry-artifacts {
|
|
24
|
+
background-color: #ffffff;
|
|
25
|
+
border-radius: 0.5rem;
|
|
26
|
+
padding: 0.75rem; /* Reduced padding */
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Order field styling */
|
|
30
|
+
input[type="number"][name$=".order"] {
|
|
31
|
+
-moz-appearance: textfield;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
input[type="number"][name$=".order"]::-webkit-outer-spin-button,
|
|
35
|
+
input[type="number"][name$=".order"]::-webkit-inner-spin-button {
|
|
36
|
+
-webkit-appearance: none;
|
|
37
|
+
margin: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
input[type="number"][name$=".order"]:focus {
|
|
41
|
+
border-color: #3b82f6;
|
|
42
|
+
outline: none;
|
|
43
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Collapsible sections */
|
|
47
|
+
.collapsible-content {
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
transition: max-height 0.3s ease-out, opacity 0.3s ease-out, padding 0.3s ease-out, margin 0.3s ease-out;
|
|
50
|
+
opacity: 1;
|
|
51
|
+
max-height: 1000px; /* Adjust as needed, should be larger than the content */
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.collapsible-content.hidden {
|
|
55
|
+
max-height: 0;
|
|
56
|
+
opacity: 0;
|
|
57
|
+
padding-top: 0 !important; /* Use important to override potential inline styles or more specific selectors */
|
|
58
|
+
padding-bottom: 0 !important;
|
|
59
|
+
margin-top: 0 !important;
|
|
60
|
+
margin-bottom: 0 !important; /* Ensure bottom margin also collapses */
|
|
61
|
+
border-top-width: 0;
|
|
62
|
+
border-bottom-width: 0;
|
|
63
|
+
overflow: hidden; /* Ensure content is clipped during transition */
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Styling for the clickable header of collapsible sections */
|
|
67
|
+
.collapsible-header {
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
display: flex;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
align-items: center;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.collapsible-header i {
|
|
75
|
+
transition: transform 0.3s ease;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.collapsible-content.hidden + .collapsible-header i {
|
|
79
|
+
transform: rotate(-90deg);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Specific styling for scrollable server content */
|
|
83
|
+
.server-content-scrollable {
|
|
84
|
+
/* This max-height is for when the section is *expanded*.
|
|
85
|
+
The .collapsible-content.hidden will still set max-height to 0 for collapse.
|
|
86
|
+
The general .collapsible-content max-height is a fallback for other sections.
|
|
87
|
+
*/
|
|
88
|
+
max-height: 60vh; /* Reduced max-height for compactness */
|
|
89
|
+
overflow-y: auto; /* Add vertical scrollbar when content exceeds max-height */
|
|
90
|
+
padding-right: 0.5rem; /* Add a little padding so scrollbar doesn't overlap content too much */
|
|
91
|
+
/* Ensure it inherits or has its own transitions for smooth animation */
|
|
92
|
+
transition: max-height 0.3s ease-out, opacity 0.3s ease-out, padding 0.3s ease-out, margin 0.3s ease-out;
|
|
93
|
+
opacity: 1; /* Explicitly set opacity for visible state */
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Ensure that when server-content-scrollable is hidden, its specific max-height is overridden */
|
|
97
|
+
.server-content-scrollable.hidden {
|
|
98
|
+
max-height: 0 !important; /* Override the 60vh for hidden state */
|
|
99
|
+
opacity: 0 !important; /* Ensure opacity transition for hidden state */
|
|
100
|
+
overflow-y: hidden; /* Hide scrollbar when collapsed */
|
|
101
|
+
padding-top: 0 !important;
|
|
102
|
+
padding-bottom: 0 !important;
|
|
103
|
+
padding-left: 0 !important; /* Ensure all paddings are zeroed */
|
|
104
|
+
padding-right: 0 !important;
|
|
105
|
+
margin-top: 0 !important;
|
|
106
|
+
margin-bottom: 0 !important;
|
|
107
|
+
}
|