imcp 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +21 -4
  2. package/dist/cli/commands/install.js.map +1 -0
  3. package/dist/cli/commands/list.js.map +1 -0
  4. package/dist/cli/commands/pull.js.map +1 -0
  5. package/dist/cli/commands/serve.js.map +1 -0
  6. package/dist/cli/commands/start.d.ts +2 -0
  7. package/dist/cli/commands/start.js +32 -0
  8. package/dist/cli/commands/start.js.map +1 -0
  9. package/dist/cli/commands/sync.d.ts +2 -0
  10. package/dist/cli/commands/sync.js +17 -0
  11. package/dist/cli/commands/sync.js.map +1 -0
  12. package/dist/cli/commands/uninstall.js.map +1 -0
  13. package/dist/cli/index.js +0 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/core/ConfigurationLoader.d.ts +32 -0
  16. package/{src/core/loaders/ConfigurationLoader.ts → dist/core/ConfigurationLoader.js} +236 -298
  17. package/dist/core/ConfigurationLoader.js.map +1 -0
  18. package/dist/core/ConfigurationProvider.d.ts +35 -0
  19. package/{src/core/loaders/ConfigurationProvider.ts → dist/core/ConfigurationProvider.js} +375 -462
  20. package/dist/core/ConfigurationProvider.js.map +1 -0
  21. package/dist/core/InstallationService.d.ts +50 -0
  22. package/dist/core/InstallationService.js +350 -0
  23. package/dist/core/InstallationService.js.map +1 -0
  24. package/dist/core/MCPManager.d.ts +28 -0
  25. package/dist/core/MCPManager.js +188 -0
  26. package/dist/core/MCPManager.js.map +1 -0
  27. package/dist/core/RequirementService.d.ts +40 -0
  28. package/dist/core/RequirementService.js +110 -0
  29. package/dist/core/RequirementService.js.map +1 -0
  30. package/dist/core/ServerSchemaLoader.d.ts +11 -0
  31. package/dist/core/ServerSchemaLoader.js +43 -0
  32. package/dist/core/ServerSchemaLoader.js.map +1 -0
  33. package/dist/core/ServerSchemaProvider.d.ts +17 -0
  34. package/dist/core/ServerSchemaProvider.js +120 -0
  35. package/dist/core/ServerSchemaProvider.js.map +1 -0
  36. package/dist/core/constants.d.ts +47 -0
  37. package/dist/core/constants.js +94 -0
  38. package/dist/core/constants.js.map +1 -0
  39. package/dist/core/installers/BaseInstaller.d.ts +74 -0
  40. package/dist/core/installers/BaseInstaller.js +253 -0
  41. package/dist/core/installers/BaseInstaller.js.map +1 -0
  42. package/dist/core/installers/ClientInstaller.d.ts +23 -0
  43. package/dist/core/installers/ClientInstaller.js +564 -0
  44. package/dist/core/installers/ClientInstaller.js.map +1 -0
  45. package/dist/core/installers/CommandInstaller.d.ts +37 -0
  46. package/{src/core/installers/requirements/CommandInstaller.ts → dist/core/installers/CommandInstaller.js} +173 -231
  47. package/dist/core/installers/CommandInstaller.js.map +1 -0
  48. package/dist/core/installers/GeneralInstaller.d.ts +33 -0
  49. package/dist/core/installers/GeneralInstaller.js +85 -0
  50. package/dist/core/installers/GeneralInstaller.js.map +1 -0
  51. package/dist/core/installers/InstallerFactory.d.ts +54 -0
  52. package/{src/core/installers/requirements/InstallerFactory.ts → dist/core/installers/InstallerFactory.js} +97 -112
  53. package/dist/core/installers/InstallerFactory.js.map +1 -0
  54. package/dist/core/installers/NpmInstaller.d.ts +26 -0
  55. package/dist/core/installers/NpmInstaller.js +127 -0
  56. package/dist/core/installers/NpmInstaller.js.map +1 -0
  57. package/dist/core/installers/PipInstaller.d.ts +28 -0
  58. package/dist/core/installers/PipInstaller.js +127 -0
  59. package/dist/core/installers/PipInstaller.js.map +1 -0
  60. package/{src/core/installers/requirements/RequirementInstaller.ts → dist/core/installers/RequirementInstaller.d.ts} +33 -42
  61. package/dist/core/installers/RequirementInstaller.js +3 -0
  62. package/dist/core/installers/RequirementInstaller.js.map +1 -0
  63. package/dist/core/installers/clients/BaseClientInstaller.js.map +1 -0
  64. package/dist/core/installers/clients/ClientInstaller.js.map +1 -0
  65. package/dist/core/installers/clients/ClientInstallerFactory.js.map +1 -0
  66. package/dist/core/installers/clients/ClineInstaller.js.map +1 -0
  67. package/dist/core/installers/clients/ExtensionInstaller.js.map +1 -0
  68. package/dist/core/installers/clients/GithubCopilotInstaller.js.map +1 -0
  69. package/dist/core/installers/clients/MSRooCodeInstaller.js.map +1 -0
  70. package/dist/core/installers/index.js.map +1 -0
  71. package/dist/core/installers/requirements/BaseInstaller.js.map +1 -0
  72. package/dist/core/installers/requirements/CommandInstaller.js.map +1 -0
  73. package/dist/core/installers/requirements/GeneralInstaller.js.map +1 -0
  74. package/dist/core/installers/requirements/InstallerFactory.js +2 -0
  75. package/dist/core/installers/requirements/InstallerFactory.js.map +1 -0
  76. package/dist/core/installers/requirements/NpmInstaller.js.map +1 -0
  77. package/dist/core/installers/requirements/NugetInstaller.d.ts +37 -0
  78. package/dist/core/installers/requirements/NugetInstaller.js +189 -0
  79. package/dist/core/installers/requirements/NugetInstaller.js.map +1 -0
  80. package/dist/core/installers/requirements/PipInstaller.js.map +1 -0
  81. package/dist/core/installers/requirements/RequirementInstaller.js.map +1 -0
  82. package/dist/core/loaders/ConfigurationLoader.js.map +1 -0
  83. package/dist/core/loaders/ConfigurationProvider.js.map +1 -0
  84. package/dist/core/loaders/InstallOperationManager.js.map +1 -0
  85. package/dist/core/loaders/ServerSchemaLoader.js.map +1 -0
  86. package/dist/core/loaders/ServerSchemaProvider.js.map +1 -0
  87. package/dist/core/loaders/SystemSettingsManager.js.map +1 -0
  88. package/dist/core/metadatas/constants.js.map +1 -0
  89. package/dist/core/metadatas/recordingConstants.d.ts +2 -0
  90. package/dist/core/metadatas/recordingConstants.js +2 -0
  91. package/dist/core/metadatas/recordingConstants.js.map +1 -0
  92. package/dist/core/metadatas/types.d.ts +1 -1
  93. package/dist/core/metadatas/types.js.map +1 -0
  94. package/dist/core/onboard/FeedOnboardService.js +1 -22
  95. package/dist/core/onboard/FeedOnboardService.js.map +1 -0
  96. package/dist/core/onboard/OnboardProcessor.js.map +1 -0
  97. package/dist/core/onboard/OnboardStatus.js.map +1 -0
  98. package/dist/core/onboard/OnboardStatusManager.js.map +1 -0
  99. package/dist/core/types.d.ts +166 -0
  100. package/dist/core/types.js +16 -0
  101. package/dist/core/types.js.map +1 -0
  102. package/dist/core/validators/FeedValidator.js.map +1 -0
  103. package/dist/core/validators/IServerValidator.js.map +1 -0
  104. package/dist/core/validators/SSEServerValidator.js.map +1 -0
  105. package/dist/core/validators/ServerValidatorFactory.js.map +1 -0
  106. package/dist/core/validators/StdioServerValidator.js +5 -5
  107. package/dist/core/validators/StdioServerValidator.js.map +1 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/services/InstallRequestValidator.d.ts +21 -0
  110. package/dist/services/InstallRequestValidator.js +99 -0
  111. package/dist/services/InstallRequestValidator.js.map +1 -0
  112. package/dist/services/InstallationService.js.map +1 -0
  113. package/dist/services/MCPManager.js.map +1 -0
  114. package/dist/services/RequirementService.js.map +1 -0
  115. package/dist/services/ServerService.js.map +1 -0
  116. package/dist/services/TelemetryService.js.map +1 -0
  117. package/dist/utils/UpdateCheckTracker.js.map +1 -0
  118. package/dist/utils/adoUtils.js.map +1 -0
  119. package/dist/utils/clientUtils.js.map +1 -0
  120. package/dist/utils/feedUtils.js.map +1 -0
  121. package/dist/utils/githubAuth.js.map +1 -0
  122. package/dist/utils/githubUtils.js.map +1 -0
  123. package/dist/utils/logger.js.map +1 -0
  124. package/dist/utils/macroExpressionUtils.js.map +1 -0
  125. package/dist/utils/osUtils.d.ts +11 -0
  126. package/dist/utils/osUtils.js +100 -0
  127. package/dist/utils/osUtils.js.map +1 -0
  128. package/dist/utils/versionUtils.js.map +1 -0
  129. package/dist/web/contract/serverContract.js.map +1 -0
  130. package/dist/web/public/index.html +1 -1
  131. package/dist/web/public/js/modal/installHandler.js +227 -0
  132. package/dist/web/public/js/modal/loadingUI.js +74 -0
  133. package/dist/web/public/js/modal/messageQueue.js +101 -45
  134. package/dist/web/public/js/modal/modalUI.js +214 -0
  135. package/{src/web/public/js/modal/versionUtils.js → dist/web/public/js/modal/version.js} +1 -1
  136. package/dist/web/public/js/onboard/templates.js +1 -0
  137. package/dist/web/public/js/serverCategoryList.js +3 -3
  138. package/dist/web/public/onboard.html +4 -4
  139. package/dist/web/server.js.map +1 -0
  140. package/package.json +5 -1
  141. package/.github/ISSUE_TEMPLATE/JitAccess.yml +0 -28
  142. package/.github/acl/access.yml +0 -20
  143. package/.github/compliance/inventory.yml +0 -5
  144. package/.github/policies/jit.yml +0 -19
  145. package/.roo/rules-code/rules.md +0 -88
  146. package/dist/core/onboard/InstallOperationManager.d.ts +0 -23
  147. package/dist/core/onboard/InstallOperationManager.js +0 -144
  148. package/docs/ONBOARDING_PAGE_DESIGN.md +0 -260
  149. package/docs/Telemetry.md +0 -136
  150. package/memory-bank/activeContext.md +0 -26
  151. package/memory-bank/decisionLog.md +0 -91
  152. package/memory-bank/productContext.md +0 -41
  153. package/memory-bank/progress.md +0 -35
  154. package/memory-bank/systemPatterns.md +0 -10
  155. package/src/cli/commands/install.ts +0 -139
  156. package/src/cli/commands/list.ts +0 -113
  157. package/src/cli/commands/pull.ts +0 -16
  158. package/src/cli/commands/serve.ts +0 -39
  159. package/src/cli/commands/uninstall.ts +0 -64
  160. package/src/cli/index.ts +0 -82
  161. package/src/core/installers/clients/BaseClientInstaller.ts +0 -341
  162. package/src/core/installers/clients/ClientInstaller.ts +0 -222
  163. package/src/core/installers/clients/ClientInstallerFactory.ts +0 -43
  164. package/src/core/installers/clients/ClineInstaller.ts +0 -35
  165. package/src/core/installers/clients/ExtensionInstaller.ts +0 -165
  166. package/src/core/installers/clients/GithubCopilotInstaller.ts +0 -79
  167. package/src/core/installers/clients/MSRooCodeInstaller.ts +0 -32
  168. package/src/core/installers/index.ts +0 -11
  169. package/src/core/installers/requirements/BaseInstaller.ts +0 -85
  170. package/src/core/installers/requirements/GeneralInstaller.ts +0 -133
  171. package/src/core/installers/requirements/NpmInstaller.ts +0 -271
  172. package/src/core/installers/requirements/PipInstaller.ts +0 -207
  173. package/src/core/loaders/InstallOperationManager.ts +0 -367
  174. package/src/core/loaders/ServerSchemaLoader.ts +0 -117
  175. package/src/core/loaders/ServerSchemaProvider.ts +0 -99
  176. package/src/core/loaders/SystemSettingsManager.ts +0 -278
  177. package/src/core/metadatas/constants.ts +0 -122
  178. package/src/core/metadatas/recordingConstants.ts +0 -62
  179. package/src/core/metadatas/types.ts +0 -202
  180. package/src/core/onboard/FeedOnboardService.ts +0 -524
  181. package/src/core/onboard/OnboardProcessor.ts +0 -356
  182. package/src/core/onboard/OnboardStatus.ts +0 -60
  183. package/src/core/onboard/OnboardStatusManager.ts +0 -416
  184. package/src/core/validators/FeedValidator.ts +0 -135
  185. package/src/core/validators/IServerValidator.ts +0 -21
  186. package/src/core/validators/SSEServerValidator.ts +0 -43
  187. package/src/core/validators/ServerValidatorFactory.ts +0 -51
  188. package/src/core/validators/StdioServerValidator.ts +0 -312
  189. package/src/index.ts +0 -44
  190. package/src/services/InstallationService.ts +0 -102
  191. package/src/services/MCPManager.ts +0 -249
  192. package/src/services/RequirementService.ts +0 -627
  193. package/src/services/ServerService.ts +0 -161
  194. package/src/services/TelemetryService.ts +0 -59
  195. package/src/utils/UpdateCheckTracker.ts +0 -86
  196. package/src/utils/adoUtils.ts +0 -293
  197. package/src/utils/clientUtils.ts +0 -72
  198. package/src/utils/feedUtils.ts +0 -31
  199. package/src/utils/githubAuth.ts +0 -212
  200. package/src/utils/githubUtils.ts +0 -164
  201. package/src/utils/logger.ts +0 -195
  202. package/src/utils/macroExpressionUtils.ts +0 -104
  203. package/src/utils/osUtils.ts +0 -597
  204. package/src/utils/versionUtils.ts +0 -114
  205. package/src/web/contract/serverContract.ts +0 -74
  206. package/src/web/public/css/detailsWidget.css +0 -235
  207. package/src/web/public/css/modal.css +0 -757
  208. package/src/web/public/css/notifications.css +0 -101
  209. package/src/web/public/css/onboard.css +0 -107
  210. package/src/web/public/css/serverCategoryList.css +0 -120
  211. package/src/web/public/css/serverDetails.css +0 -139
  212. package/src/web/public/index.html +0 -359
  213. package/src/web/public/js/api.js +0 -132
  214. package/src/web/public/js/detailsWidget.js +0 -264
  215. package/src/web/public/js/flights/flights.js +0 -127
  216. package/src/web/public/js/modal/index.js +0 -52
  217. package/src/web/public/js/modal/installModal.js +0 -162
  218. package/src/web/public/js/modal/installation.js +0 -266
  219. package/src/web/public/js/modal/loadingModal.js +0 -182
  220. package/src/web/public/js/modal/modalSetup.js +0 -595
  221. package/src/web/public/js/modal/modalUtils.js +0 -37
  222. package/src/web/public/js/modal.js +0 -42
  223. package/src/web/public/js/notifications.js +0 -137
  224. package/src/web/public/js/onboard/formProcessor.js +0 -1037
  225. package/src/web/public/js/onboard/index.js +0 -374
  226. package/src/web/public/js/onboard/publishHandler.js +0 -172
  227. package/src/web/public/js/onboard/state.js +0 -76
  228. package/src/web/public/js/onboard/templates.js +0 -341
  229. package/src/web/public/js/onboard/uiHandlers.js +0 -1076
  230. package/src/web/public/js/onboard/validationHandlers.js +0 -493
  231. package/src/web/public/js/serverCategoryDetails.js +0 -364
  232. package/src/web/public/js/serverCategoryList.js +0 -241
  233. package/src/web/public/js/settings.js +0 -314
  234. package/src/web/public/modal.html +0 -84
  235. package/src/web/public/onboard.html +0 -296
  236. package/src/web/public/settings.html +0 -135
  237. package/src/web/public/styles.css +0 -277
  238. package/src/web/server.ts +0 -478
  239. package/tsconfig.json +0 -18
@@ -1,104 +0,0 @@
1
- import { Logger } from './logger.js';
2
- import { getPythonPackagePath, getSystemPythonPackageDirectory, getBrowserPath, getGlobalNPMPackagePath } from './osUtils.js';
3
- import { ServerInstallOptions } from '../core/metadatas/types.js'; // Adjusted path
4
- import { SystemSettingsManager } from '../core/loaders/SystemSettingsManager.js';
5
- import * as fsSync from 'fs';
6
- import * as path from 'path';
7
- import { execSync } from 'child_process';
8
-
9
- export const MACRO_EXPRESSIONS = {
10
- PYTHON_PACKAGE: '${PYTHON_PACKAGE}',
11
- NPMPATH: '${NPMPATH}',
12
- BROWSER_PATH: '${BROWSER_PATH}',
13
- } as const;
14
-
15
- // Define a map for macro keys to their resolver functions
16
- export const MacroResolverFunctions: {
17
- [key: string]: (finalConfig: any, options: ServerInstallOptions) => Promise<string | undefined>;
18
- } = {
19
- [MACRO_EXPRESSIONS.PYTHON_PACKAGE]: resolvePythonPackageMacro,
20
- [MACRO_EXPRESSIONS.NPMPATH]: resolveNpmPathMacro,
21
- [MACRO_EXPRESSIONS.BROWSER_PATH]: resolveBrowserPathMacro,
22
- };
23
-
24
- /**
25
- * Resolves the path for the ${PYTHON_PACKAGE} macro.
26
- * It considers the pythonEnv setting and falls back to system Python.
27
- * Also updates finalConfig.command if it's 'python' and pythonEnv is used.
28
- * @param finalConfig The configuration object (mutated for command).
29
- * @param options Server installation options.
30
- * @returns The resolved Python package path or undefined.
31
- */
32
- export async function resolvePythonPackageMacro(finalConfig: any, options: ServerInstallOptions): Promise<string | undefined> {
33
- const pythonEnv = options.settings?.pythonEnv;
34
- if (pythonEnv) {
35
- Logger.debug(`Python environment specified for ${MACRO_EXPRESSIONS.PYTHON_PACKAGE}: ${pythonEnv}`);
36
- const pythonDir = getPythonPackagePath(pythonEnv);
37
- if (pythonDir) {
38
- if (finalConfig.command === 'python') {
39
- Logger.debug(`Replacing command 'python' with specified pythonEnv: ${pythonEnv} due to ${MACRO_EXPRESSIONS.PYTHON_PACKAGE} resolution`);
40
- finalConfig.command = pythonEnv;
41
- }
42
- return pythonDir;
43
- }
44
- Logger.debug(`Could not determine directory for pythonEnv: ${pythonEnv}. ${MACRO_EXPRESSIONS.PYTHON_PACKAGE} will not be replaced using this path.`);
45
- return undefined;
46
- } else {
47
- Logger.debug(`No Python environment specified. Attempting to find system Python for ${MACRO_EXPRESSIONS.PYTHON_PACKAGE}.`);
48
- const pythonDir = await getSystemPythonPackageDirectory();
49
- if (pythonDir) {
50
- return pythonDir;
51
- }
52
- Logger.debug(`Could not find system Python directory for ${MACRO_EXPRESSIONS.PYTHON_PACKAGE}.`);
53
- return undefined;
54
- }
55
- }
56
-
57
- /**
58
- * Resolves the actual NPM module path.
59
- * It checks a provided path, then NVM, then global npm.
60
- * @param providedNpmPath An optional, pre-configured NPM path.
61
- * @returns The resolved NPM module path or undefined if an error occurs.
62
- */
63
- export function resolveNpmModulePath(providedNpmPath: string | undefined): string {
64
- if (providedNpmPath) {
65
- return `${providedNpmPath}/node_modules`;
66
- }
67
-
68
- const globalNpmPath = getGlobalNPMPackagePath();
69
- Logger.debug(`Resolved ${MACRO_EXPRESSIONS.NPMPATH} via global npm to: ${globalNpmPath}`);
70
- return globalNpmPath;
71
- }
72
-
73
- /**
74
- * Resolves the path to an NPM module for the ${NPMPATH} macro.
75
- * Uses the resolveNpmModulePath function.
76
- * @param _finalConfig Not used by this resolver.
77
- * @param options Server installation options, may contain npmPath.
78
- * @returns The resolved NPM path or undefined if an error occurs.
79
- */
80
- export async function resolveNpmPathMacro(_finalConfig: any, options: ServerInstallOptions): Promise<string | undefined> {
81
- Logger.debug(`Resolving ${MACRO_EXPRESSIONS.NPMPATH}. Provided npmPath from settings: ${options.settings?.npmPath}`);
82
- try {
83
- return resolveNpmModulePath(options.settings?.npmPath);
84
- } catch (error) {
85
- Logger.error(`Failed to resolve ${MACRO_EXPRESSIONS.NPMPATH}:`, error);
86
- return undefined;
87
- }
88
- }
89
-
90
- /**
91
- * Resolves the path for the ${BROWSER_PATH} macro.
92
- * @returns The system's browser path or undefined.
93
- */
94
- export async function resolveBrowserPathMacro(): Promise<string | undefined> {
95
- Logger.debug(`Resolving ${MACRO_EXPRESSIONS.BROWSER_PATH}`);
96
- try {
97
- const browserPath = await getBrowserPath();
98
- Logger.debug(`Resolved ${MACRO_EXPRESSIONS.BROWSER_PATH} to: ${browserPath}`);
99
- return browserPath;
100
- } catch (error) {
101
- Logger.error(`Failed to get system browser path for ${MACRO_EXPRESSIONS.BROWSER_PATH}:`, error);
102
- return undefined;
103
- }
104
- }
@@ -1,597 +0,0 @@
1
- import { OSType } from '../core/metadatas/types.js';
2
- import os from 'os';
3
- import { exec } from 'child_process';
4
- import util from 'util';
5
- import { Logger } from './logger.js';
6
- import fs from 'fs';
7
- import path from 'path';
8
- import { execSync } from 'child_process';
9
- import * as fsSync from 'fs';
10
-
11
- const execAsync = util.promisify(exec);
12
-
13
- export function getOSType(): OSType {
14
- const platform = os.platform();
15
- Logger.debug({
16
- action: 'get_os_type',
17
- platform
18
- });
19
-
20
- switch (platform) {
21
- case 'win32':
22
- return OSType.Windows;
23
- case 'darwin':
24
- return OSType.MacOS;
25
- case 'linux':
26
- return OSType.Linux;
27
- default:
28
- const error = `Unsupported operating system: ${platform}`;
29
- Logger.error(error);
30
- throw new Error(error);
31
- }
32
- }
33
-
34
- export async function installCLI(tool: 'gh' | 'git'): Promise<void> {
35
- const osType = getOSType();
36
- Logger.debug({
37
- action: 'install_cli',
38
- tool,
39
- osType
40
- });
41
-
42
- try {
43
- switch (osType) {
44
- case OSType.Windows:
45
- if (tool === 'git') {
46
- await execAsync('winget install --id Git.Git -e --source winget --silent');
47
- } else {
48
- await execAsync('winget install --id GitHub.cli --silent');
49
- }
50
- // Refresh PATH environment variable after installation
51
- await refreshPathEnv();
52
- break;
53
-
54
- case OSType.MacOS:
55
- if (tool === 'git') {
56
- await execAsync('brew install git');
57
- } else {
58
- await execAsync('brew install gh');
59
- }
60
- // On macOS, we may need to source profile files
61
- if (tool === 'git') {
62
- await execAsync('source ~/.zshrc || source ~/.bash_profile || source ~/.bashrc || true');
63
- }
64
- break;
65
-
66
- case OSType.Linux:
67
- if (tool === 'git') {
68
- await execAsync('sudo apt-get update && sudo apt-get install -y git');
69
- } else {
70
- await execAsync('curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install -y gh');
71
- }
72
- // Source bash profile to refresh PATH
73
- await execAsync('source ~/.bashrc || source ~/.profile || true');
74
- break;
75
-
76
- default:
77
- throw new Error(`Unsupported operating system for installing ${tool}`);
78
- }
79
-
80
- // Wait a moment for system to register the new binaries
81
- await new Promise(resolve => setTimeout(resolve, 1000));
82
-
83
- Logger.debug({
84
- action: 'install_cli_success',
85
- tool,
86
- osType
87
- });
88
- } catch (error) {
89
- Logger.error('Failed to install CLI tool', {
90
- tool,
91
- osType,
92
- error
93
- });
94
- throw error;
95
- }
96
- }
97
-
98
- /**
99
- * Refreshes the PATH environment variable for the current Node.js process
100
- */
101
- export async function refreshPathEnv(): Promise<void> {
102
- const osType = getOSType();
103
- Logger.debug({
104
- action: 'refresh_path_env',
105
- osType
106
- });
107
-
108
- try {
109
- switch (osType) {
110
- case OSType.Windows:
111
- // On Windows, get the PATH from registry
112
- const { stdout: winPath } = await execAsync('powershell -command "[Environment]::GetEnvironmentVariable(\'Path\', \'Machine\') + \';\' + [Environment]::GetEnvironmentVariable(\'Path\', \'User\')"');
113
- if (winPath) {
114
- process.env.PATH = winPath.trim();
115
- Logger.debug('Refreshed PATH from Windows registry');
116
- }
117
- break;
118
-
119
- case OSType.MacOS:
120
- case OSType.Linux:
121
- // On Unix systems, typical installation locations if PATH isn't updated
122
- const commonPaths = [
123
- '/usr/local/bin',
124
- '/usr/bin',
125
- '/bin',
126
- '/usr/sbin',
127
- '/sbin',
128
- '/usr/local/git/bin',
129
- '/opt/homebrew/bin', // For M1 Macs
130
- `${os.homedir()}/.local/bin`
131
- ];
132
-
133
- // Ensure these paths are in process.env.PATH
134
- if (process.env.PATH) {
135
- const currentPaths = process.env.PATH.split(':');
136
- const newPaths = [...new Set([...currentPaths, ...commonPaths])];
137
- process.env.PATH = newPaths.join(':');
138
- Logger.debug('Expanded PATH with common Unix binary locations');
139
- }
140
- break;
141
- }
142
-
143
- Logger.debug({
144
- action: 'refresh_path_env_success',
145
- path: process.env.PATH
146
- });
147
- } catch (error) {
148
- Logger.error('Failed to refresh PATH environment variable', error);
149
- // Continue execution even if PATH refresh fails
150
- }
151
- }
152
-
153
- /**
154
- * Check if a command is available on the system
155
- * Handles special cases for VS Code on different platforms
156
- */
157
- export async function isCommandAvailable(command: string): Promise<boolean> {
158
- try {
159
- // For VS Code on macOS, check both command-line tool and app bundle
160
- if (process.platform === 'darwin' && (command === 'code' || command === 'code-insiders')) {
161
- try {
162
- // Try which command first
163
- await execAsync(`which ${command}`);
164
- return true;
165
- } catch (error) {
166
- // If which fails, check application bundles
167
- const systemVSCodePath = command === 'code' ?
168
- '/Applications/Visual Studio Code.app' :
169
- '/Applications/Visual Studio Code - Insiders.app';
170
-
171
- try {
172
- // Check system Applications first
173
- await execAsync(`test -d "${systemVSCodePath}"`);
174
- return true;
175
- } catch (error) {
176
- // If system Applications check fails, try user Applications
177
- const homedir = process.env.HOME;
178
- if (homedir) {
179
- const userVSCodePath = command === 'code' ?
180
- `${homedir}/Applications/Visual Studio Code.app` :
181
- `${homedir}/Applications/Visual Studio Code - Insiders.app`;
182
-
183
- try {
184
- await execAsync(`test -d "${userVSCodePath}"`);
185
- return true;
186
- } catch (error) {
187
- return false;
188
- }
189
- }
190
- return false;
191
- }
192
- }
193
- }
194
-
195
- // For Windows, use where command
196
- if (process.platform === 'win32') {
197
- await execAsync(`where ${command}`);
198
- return true;
199
- }
200
-
201
- // For all other cases (Unix-like systems), use which command
202
- await execAsync(`which ${command}`);
203
- return true;
204
- } catch (error) {
205
- return false;
206
- }
207
- }
208
-
209
- export async function isToolInstalled(tool: 'gh' | 'git', retries = 3): Promise<boolean> {
210
- try {
211
- Logger.debug({
212
- action: 'check_tool_installed',
213
- tool,
214
- retries
215
- });
216
-
217
- // Try to execute tool command
218
- try {
219
- await execAsync(`${tool} --version`);
220
- Logger.debug({
221
- action: 'check_tool_installed_success',
222
- tool,
223
- installed: true
224
- });
225
- return true;
226
- } catch (error) {
227
- // If we have retries left, refresh PATH and try again
228
- if (retries > 0) {
229
- Logger.debug(`${tool} not found, refreshing PATH and retrying...`);
230
-
231
- // Refresh environment PATH variable
232
- await refreshPathEnv();
233
-
234
- // Wait a moment before retrying
235
- await new Promise(resolve => setTimeout(resolve, 500));
236
-
237
- // Recursive retry with decremented counter
238
- return isToolInstalled(tool, retries - 1);
239
- }
240
-
241
- // No retries left, tool is not installed
242
- Logger.debug({
243
- action: 'check_tool_installed_success',
244
- tool,
245
- installed: false
246
- });
247
- return false;
248
- }
249
- } catch (error) {
250
- Logger.error(`Error checking if ${tool} is installed`, error);
251
- return false;
252
- }
253
- }
254
-
255
- export async function openBrowser(url: string): Promise<void> {
256
- const osType = getOSType();
257
- Logger.debug({
258
- action: 'open_browser',
259
- url,
260
- osType
261
- });
262
-
263
- try {
264
- switch (osType) {
265
- case OSType.Windows:
266
- await execAsync(`start ${url}`);
267
- break;
268
- case OSType.MacOS:
269
- await execAsync(`open ${url}`);
270
- break;
271
- case OSType.Linux:
272
- // Try different commands that might be available
273
- try {
274
- await execAsync(`xdg-open ${url}`);
275
- } catch (error) {
276
- // Try alternative commands
277
- try {
278
- await execAsync(`sensible-browser ${url}`);
279
- } catch (error) {
280
- await execAsync(`gnome-open ${url}`);
281
- }
282
- }
283
- break;
284
- default:
285
- throw new Error(`Unsupported operating system for opening browser`);
286
- }
287
-
288
- Logger.debug({
289
- action: 'open_browser_success',
290
- url,
291
- osType
292
- });
293
- } catch (error) {
294
- Logger.error('Failed to open browser', {
295
- url,
296
- osType,
297
- error
298
- });
299
- // Don't throw the error - just log it and continue
300
- }
301
- }
302
-
303
- export function getPythonPackagePath(pythonExecutablePath: string): string {
304
- Logger.debug({
305
- action: 'get_python_package_path',
306
- pythonExecutablePath
307
- });
308
-
309
- try {
310
- const dir = path.dirname(pythonExecutablePath);
311
- const isWindows = process.platform === 'win32';
312
-
313
- // Handle common Python installation patterns
314
- if (isWindows) {
315
- // Windows: Handle different Python installations
316
- if (dir.endsWith('WindowsApps')) {
317
- // For Windows Store Python, find the actual Python installation directory
318
- const entries = fs.readdirSync(dir);
319
- const pythonDir = entries.find(e => e.startsWith('PythonSoftwareFoundation.Python'));
320
- if (pythonDir && pythonDir.includes('.')) {
321
- // Extract version from format like "PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0"
322
- const parts = pythonDir.split('.');
323
- const majorVer = parts[2];
324
- const minorVer = parts[3].split('_')[0];
325
- const version = majorVer + minorVer; // Combines "3" and "13" to "313"
326
- const localAppData = process.env.LOCALAPPDATA;
327
-
328
- if (localAppData) {
329
- const sitePkgsPath = path.join(
330
- localAppData,
331
- 'Packages',
332
- pythonDir,
333
- 'LocalCache',
334
- 'local-packages',
335
- 'Python' + version,
336
- 'site-packages'
337
- );
338
-
339
- Logger.debug(`Resolved Windows Store Python site-packages path: ${sitePkgsPath}`);
340
- return sitePkgsPath;
341
- }
342
- }
343
-
344
- Logger.debug('Could not resolve Windows Store Python site-packages path');
345
- // Fallback to user's site-packages
346
- return path.join(process.env.APPDATA || '', 'Python', 'Python3', 'site-packages');
347
- } else if (dir.endsWith('Scripts')) {
348
- // Virtual environment structure on Windows: <venv>/Scripts/python.exe
349
- const venvRoot = path.dirname(dir);
350
- return path.join(venvRoot, 'Lib', 'site-packages');
351
- } else {
352
- // System Python or Conda on Windows
353
- return path.join(dir, 'Lib', 'site-packages');
354
- }
355
- } else {
356
- // Unix systems (MacOS/Linux)
357
- if (dir.endsWith('bin')) {
358
- // Virtual environment structure on Unix: <venv>/bin/python
359
- const venvRoot = path.dirname(dir);
360
- // Try to find python version-specific site-packages
361
- const libDir = path.join(venvRoot, 'lib');
362
- if (fs.existsSync(libDir)) {
363
- const pythonDirs = fs.readdirSync(libDir).filter(d => d.startsWith('python'));
364
- if (pythonDirs.length > 0) {
365
- // Use the first python directory found
366
- return path.join(libDir, pythonDirs[0], 'site-packages');
367
- }
368
- }
369
- // Fallback to a generic lib/python3/site-packages if version-specific not found
370
- return path.join(venvRoot, 'lib', 'python3', 'site-packages');
371
- } else if (dir.toLowerCase().includes('python')) {
372
- // System Python or Conda on Unix
373
- const libDir = path.join(dir, 'lib');
374
- if (fs.existsSync(libDir)) {
375
- const pythonDirs = fs.readdirSync(libDir).filter(d => d.startsWith('python'));
376
- if (pythonDirs.length > 0) {
377
- // Use the first python directory found
378
- return path.join(libDir, pythonDirs[0], 'site-packages');
379
- }
380
- }
381
- // Fallback to a generic lib/python3/site-packages
382
- return path.join(dir, 'lib', 'python3', 'site-packages');
383
- }
384
- }
385
-
386
- // Default fallback: return the original directory
387
- Logger.debug('No standard Python directory structure found, using original directory');
388
- return dir;
389
- } catch (error) {
390
- Logger.error('Error getting Python package path', {
391
- pythonExecutablePath,
392
- error
393
- });
394
- return path.dirname(pythonExecutablePath);
395
- }
396
- }
397
-
398
- export async function getSystemPythonPackageDirectory(): Promise<string | null> {
399
- const command = process.platform === 'win32' ? 'where python' : 'which python';
400
-
401
- Logger.debug({
402
- action: 'get_system_python_package_directory',
403
- command
404
- });
405
-
406
- try {
407
- const { stdout } = await execAsync(command);
408
- // Use the first path found, trim whitespace
409
- const pythonPath = stdout.split('\n')[0].trim();
410
- if (pythonPath) {
411
- const packagePath = getPythonPackagePath(pythonPath);
412
- Logger.debug({
413
- action: 'get_system_python_package_directory_success',
414
- pythonPath,
415
- packagePath
416
- });
417
- return packagePath;
418
- }
419
- Logger.debug('No Python executable found');
420
- return null;
421
- } catch (error) {
422
- Logger.debug(`Could not find system python using "${command}": ${error}`);
423
- return null;
424
- }
425
- }
426
- /**
427
- * Get the system Python executable path.
428
- * This function returns the absolute path to the system Python executable (e.g., /Users/penwa/miniconda3/envs/browser-use-temp/bin/python).
429
- * It uses 'which python' (Unix) or 'where python' (Windows) to locate the executable.
430
- * @returns {Promise<string | null>} The path to the Python executable, or null if not found.
431
- */
432
- export async function getSystemPythonExecutablePath(): Promise<string | null> {
433
- const command = process.platform === 'win32' ? 'where python' : 'which python';
434
-
435
- Logger.debug({
436
- action: 'get_system_python_executable_path',
437
- command
438
- });
439
-
440
- try {
441
- const { stdout } = await execAsync(command);
442
- // Use the first path found, trim whitespace
443
- const pythonPath = stdout.split('\n')[0].trim();
444
- if (pythonPath) {
445
- Logger.debug({
446
- action: 'get_system_python_executable_path_success',
447
- pythonPath
448
- });
449
- return pythonPath;
450
- }
451
- Logger.debug('No Python executable found');
452
- return null;
453
- } catch (error) {
454
- Logger.debug(`Could not find system python using "${command}": ${error}`);
455
- return null;
456
- }
457
- }
458
-
459
- export async function getBrowserPath(): Promise<string> {
460
- const osType = getOSType();
461
- Logger.debug({
462
- action: 'get_system_browser_path',
463
- osType
464
- });
465
-
466
- try {
467
- switch (osType) {
468
- case OSType.Windows: {
469
- // Check for Edge first
470
- const edgePaths = [
471
- `${process.env['PROGRAMFILES(X86)']}\\Microsoft\\Edge\\Application\\msedge.exe`,
472
- `${process.env['PROGRAMFILES']}\\Microsoft\\Edge\\Application\\msedge.exe`
473
- ];
474
- for (const path of edgePaths) {
475
- if (fs.existsSync(path)) {
476
- return path;
477
- }
478
- }
479
-
480
- // Then check for Chrome
481
- const chromePaths = [
482
- `${process.env['PROGRAMFILES(X86)']}\\Google\\Chrome\\Application\\chrome.exe`,
483
- `${process.env['PROGRAMFILES']}\\Google\\Chrome\\Application\\chrome.exe`
484
- ];
485
- for (const path of chromePaths) {
486
- if (fs.existsSync(path)) {
487
- return path;
488
- }
489
- }
490
- break;
491
- }
492
-
493
- case OSType.MacOS: {
494
- // Check for Edge first
495
- const edgePath = '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge';
496
- if (fs.existsSync(edgePath)) {
497
- return edgePath;
498
- }
499
-
500
- // Then check for Chrome
501
- const chromePath = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
502
- if (fs.existsSync(chromePath)) {
503
- return chromePath;
504
- }
505
-
506
- // Finally check for Safari
507
- const safariPath = '/Applications/Safari.app/Contents/MacOS/Safari';
508
- if (fs.existsSync(safariPath)) {
509
- return safariPath;
510
- }
511
- break;
512
- }
513
-
514
- case OSType.Linux: {
515
- // Try Edge first
516
- try {
517
- const { stdout: edgePath } = await execAsync('which microsoft-edge');
518
- if (edgePath.trim()) {
519
- return edgePath.trim();
520
- }
521
- } catch { }
522
-
523
- // Then try Chrome or Chromium
524
- try {
525
- const { stdout: chromePath } = await execAsync('which google-chrome chromium');
526
- if (chromePath.trim()) {
527
- return chromePath.trim();
528
- }
529
- } catch { }
530
- break;
531
- }
532
- }
533
-
534
- // If no browser found, throw error
535
- throw new Error('No supported browser found on the system');
536
- } catch (error) {
537
- Logger.error('Failed to get browser path', error);
538
- throw error;
539
- }
540
- }
541
-
542
- /**
543
- * Get the global NPM path
544
- * This function checks if NVM is installed and retrieves the global NPM path accordingly.
545
- * If NVM is not installed, it falls back to the global NPM path.
546
- * @returns The global NPM path as a string.
547
- * @throws Error if the NPM path cannot be determined.
548
- * */
549
- export function getGlobalNPMPackagePath(): string {
550
- const nvmHome = process.env.NVM_HOME;
551
- if (nvmHome) {
552
- try {
553
- const nodeVersion = execSync('node -v').toString().trim();
554
- const nvmNodePath = path.join(nvmHome, nodeVersion);
555
- // Check if this path exists
556
- try {
557
- fsSync.accessSync(nvmNodePath);
558
- return nvmNodePath;
559
- } catch (error) {
560
- Logger.debug(`NVM controlled path doesn't exist: ${nvmNodePath}, will try global npm`);
561
- }
562
- } catch (error) {
563
- Logger.debug(`Error determining Node version for NVM: ${error}, will use global npm`);
564
- }
565
- }
566
-
567
- const globalNpmPath = execSync('npm root -g').toString().trim();
568
- return globalNpmPath;
569
- }
570
-
571
-
572
- /**
573
- * Get the NPM executable path on the current platform (Windows, macOS, Linux).
574
- * On Windows, uses PowerShell to locate npm. On macOS/Linux, uses 'which' to locate npm.
575
- * Returns the directory containing the npm executable, or a platform-appropriate default if not found.
576
- */
577
- export async function getNpmExecutablePath(): Promise<string> {
578
- try {
579
- if (process.platform === 'win32') {
580
- const { stdout } = await execAsync('powershell -Command "get-command npm | Select-Object -ExpandProperty Source"');
581
- return stdout.trim().replace(/\\npm\.cmd$/, '');
582
- } else {
583
- // macOS or Linux
584
- const { stdout } = await execAsync('which npm');
585
- // Remove the trailing '/npm' to get the directory
586
- return stdout.trim().replace(/\/npm$/, '');
587
- }
588
- } catch (error) {
589
- Logger.error('Error getting npm path:', error);
590
- if (process.platform === 'win32') {
591
- return 'C:\\Program Files\\nodejs';
592
- } else {
593
- // Common default for Unix systems
594
- return '/usr/local/bin';
595
- }
596
- }
597
- }