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.
Files changed (183) hide show
  1. package/.roo/rules-code/rules.md +88 -0
  2. package/dist/cli/index.js +1 -45
  3. package/dist/core/installers/clients/BaseClientInstaller.d.ts +1 -5
  4. package/dist/core/installers/clients/BaseClientInstaller.js +40 -38
  5. package/dist/core/installers/clients/ClientInstaller.d.ts +9 -9
  6. package/dist/core/installers/clients/ClientInstaller.js +105 -99
  7. package/dist/core/installers/requirements/BaseInstaller.d.ts +9 -1
  8. package/dist/core/installers/requirements/CommandInstaller.d.ts +9 -1
  9. package/dist/core/installers/requirements/CommandInstaller.js +46 -12
  10. package/dist/core/installers/requirements/GeneralInstaller.d.ts +11 -1
  11. package/dist/core/installers/requirements/GeneralInstaller.js +46 -10
  12. package/dist/core/installers/requirements/InstallerFactory.d.ts +3 -1
  13. package/dist/core/installers/requirements/InstallerFactory.js +3 -2
  14. package/dist/core/installers/requirements/NpmInstaller.d.ts +4 -2
  15. package/dist/core/installers/requirements/NpmInstaller.js +38 -22
  16. package/dist/core/installers/requirements/PipInstaller.d.ts +3 -1
  17. package/dist/core/installers/requirements/PipInstaller.js +58 -36
  18. package/dist/core/installers/requirements/RequirementInstaller.d.ts +4 -1
  19. package/dist/core/loaders/InstallOperationManager.d.ts +115 -0
  20. package/dist/core/loaders/InstallOperationManager.js +311 -0
  21. package/dist/core/loaders/SystemSettingsManager.d.ts +54 -0
  22. package/dist/core/loaders/SystemSettingsManager.js +257 -0
  23. package/dist/core/metadatas/constants.d.ts +7 -0
  24. package/dist/core/metadatas/constants.js +7 -0
  25. package/dist/core/metadatas/recordingConstants.d.ts +44 -0
  26. package/dist/core/metadatas/recordingConstants.js +45 -0
  27. package/dist/core/metadatas/types.d.ts +21 -0
  28. package/dist/core/onboard/FeedOnboardService.d.ts +7 -3
  29. package/dist/core/onboard/FeedOnboardService.js +52 -5
  30. package/dist/core/onboard/InstallOperationManager.d.ts +23 -0
  31. package/dist/core/onboard/InstallOperationManager.js +144 -0
  32. package/dist/core/onboard/OnboardStatusManager.js +2 -1
  33. package/dist/core/validators/StdioServerValidator.js +4 -3
  34. package/dist/services/InstallationService.d.ts +2 -37
  35. package/dist/services/InstallationService.js +45 -313
  36. package/dist/services/MCPManager.d.ts +1 -1
  37. package/dist/services/MCPManager.js +53 -47
  38. package/dist/services/RequirementService.d.ts +85 -12
  39. package/dist/services/RequirementService.js +488 -49
  40. package/dist/services/ServerService.d.ts +0 -6
  41. package/dist/services/ServerService.js +0 -74
  42. package/dist/services/TelemetryService.d.ts +15 -0
  43. package/dist/services/TelemetryService.js +54 -0
  44. package/dist/utils/adoUtils.js +6 -3
  45. package/dist/utils/githubAuth.js +65 -0
  46. package/dist/utils/logger.d.ts +16 -0
  47. package/dist/utils/logger.js +78 -1
  48. package/dist/utils/macroExpressionUtils.js +3 -25
  49. package/dist/utils/osUtils.d.ts +22 -1
  50. package/dist/utils/osUtils.js +92 -1
  51. package/dist/utils/versionUtils.d.ts +20 -0
  52. package/dist/utils/versionUtils.js +76 -0
  53. package/dist/web/public/css/modal.css +292 -1
  54. package/dist/web/public/css/serverCategoryList.css +120 -0
  55. package/dist/web/public/css/serverDetails.css +14 -1
  56. package/dist/web/public/index.html +126 -21
  57. package/dist/web/public/js/flights/flights.js +1 -1
  58. package/dist/web/public/js/modal/index.js +8 -14
  59. package/dist/web/public/js/modal/installModal.js +3 -4
  60. package/dist/web/public/js/modal/installation.js +122 -137
  61. package/dist/web/public/js/modal/loadingModal.js +155 -25
  62. package/dist/web/public/js/modal/messageQueue.js +45 -101
  63. package/dist/web/public/js/modal/modalSetup.js +125 -43
  64. package/dist/web/public/js/modal/modalUtils.js +0 -12
  65. package/dist/web/public/js/modal.js +23 -10
  66. package/dist/web/public/js/onboard/formProcessor.js +18 -11
  67. package/dist/web/public/js/onboard/publishHandler.js +35 -3
  68. package/dist/web/public/js/onboard/templates.js +5 -1
  69. package/dist/web/public/js/onboard/uiHandlers.js +266 -39
  70. package/dist/web/public/js/onboard/validationHandlers.js +71 -39
  71. package/dist/web/public/js/serverCategoryDetails.js +60 -11
  72. package/dist/web/public/js/serverCategoryList.js +93 -9
  73. package/dist/web/public/js/settings.js +314 -0
  74. package/dist/web/public/onboard.html +2 -2
  75. package/dist/web/public/settings.html +135 -0
  76. package/dist/web/public/styles.css +32 -0
  77. package/dist/web/server.js +93 -1
  78. package/{src/web/public/js/onboard → docs}/ONBOARDING_PAGE_DESIGN.md +15 -125
  79. package/docs/Telemetry.md +136 -0
  80. package/memory-bank/activeContext.md +26 -0
  81. package/memory-bank/decisionLog.md +91 -0
  82. package/memory-bank/productContext.md +41 -0
  83. package/memory-bank/progress.md +35 -0
  84. package/memory-bank/systemPatterns.md +10 -0
  85. package/package.json +2 -1
  86. package/src/cli/index.ts +1 -48
  87. package/src/core/installers/clients/BaseClientInstaller.ts +64 -50
  88. package/src/core/installers/clients/ClientInstaller.ts +130 -130
  89. package/src/core/installers/requirements/BaseInstaller.ts +9 -1
  90. package/src/core/installers/requirements/CommandInstaller.ts +47 -13
  91. package/src/core/installers/requirements/GeneralInstaller.ts +48 -10
  92. package/src/core/installers/requirements/InstallerFactory.ts +4 -3
  93. package/src/core/installers/requirements/NpmInstaller.ts +90 -68
  94. package/src/core/installers/requirements/PipInstaller.ts +81 -55
  95. package/src/core/installers/requirements/RequirementInstaller.ts +4 -3
  96. package/src/core/loaders/InstallOperationManager.ts +367 -0
  97. package/src/core/loaders/SystemSettingsManager.ts +278 -0
  98. package/src/core/metadatas/constants.ts +9 -0
  99. package/src/core/metadatas/recordingConstants.ts +62 -0
  100. package/src/core/metadatas/types.ts +23 -0
  101. package/src/core/onboard/FeedOnboardService.ts +59 -5
  102. package/src/core/onboard/OnboardStatusManager.ts +2 -1
  103. package/src/core/validators/StdioServerValidator.ts +4 -3
  104. package/src/services/InstallationService.ts +54 -399
  105. package/src/services/MCPManager.ts +61 -64
  106. package/src/services/RequirementService.ts +564 -67
  107. package/src/services/ServerService.ts +0 -90
  108. package/src/services/TelemetryService.ts +59 -0
  109. package/src/utils/adoUtils.ts +6 -4
  110. package/src/utils/githubAuth.ts +84 -1
  111. package/src/utils/logger.ts +83 -1
  112. package/src/utils/macroExpressionUtils.ts +4 -21
  113. package/src/utils/osUtils.ts +92 -1
  114. package/src/utils/versionUtils.ts +98 -13
  115. package/src/web/public/css/modal.css +292 -1
  116. package/src/web/public/css/serverCategoryList.css +120 -0
  117. package/src/web/public/css/serverDetails.css +14 -1
  118. package/src/web/public/index.html +126 -21
  119. package/src/web/public/js/flights/flights.js +1 -1
  120. package/src/web/public/js/modal/index.js +8 -14
  121. package/src/web/public/js/modal/installModal.js +3 -4
  122. package/src/web/public/js/modal/installation.js +122 -137
  123. package/src/web/public/js/modal/loadingModal.js +155 -25
  124. package/src/web/public/js/modal/modalSetup.js +125 -43
  125. package/src/web/public/js/modal/modalUtils.js +0 -12
  126. package/src/web/public/js/modal.js +23 -10
  127. package/src/web/public/js/onboard/formProcessor.js +18 -11
  128. package/src/web/public/js/onboard/publishHandler.js +35 -3
  129. package/src/web/public/js/onboard/templates.js +5 -1
  130. package/src/web/public/js/onboard/uiHandlers.js +266 -39
  131. package/src/web/public/js/onboard/validationHandlers.js +71 -39
  132. package/src/web/public/js/serverCategoryDetails.js +60 -11
  133. package/src/web/public/js/serverCategoryList.js +93 -9
  134. package/src/web/public/js/settings.js +314 -0
  135. package/src/web/public/onboard.html +2 -2
  136. package/src/web/public/settings.html +135 -0
  137. package/src/web/public/styles.css +32 -0
  138. package/src/web/server.ts +96 -1
  139. package/dist/cli/commands/start.d.ts +0 -2
  140. package/dist/cli/commands/start.js +0 -32
  141. package/dist/cli/commands/sync.d.ts +0 -2
  142. package/dist/cli/commands/sync.js +0 -17
  143. package/dist/core/ConfigurationLoader.d.ts +0 -32
  144. package/dist/core/ConfigurationLoader.js +0 -236
  145. package/dist/core/ConfigurationProvider.d.ts +0 -35
  146. package/dist/core/ConfigurationProvider.js +0 -375
  147. package/dist/core/InstallationService.d.ts +0 -50
  148. package/dist/core/InstallationService.js +0 -350
  149. package/dist/core/MCPManager.d.ts +0 -28
  150. package/dist/core/MCPManager.js +0 -188
  151. package/dist/core/RequirementService.d.ts +0 -40
  152. package/dist/core/RequirementService.js +0 -110
  153. package/dist/core/ServerSchemaLoader.d.ts +0 -11
  154. package/dist/core/ServerSchemaLoader.js +0 -43
  155. package/dist/core/ServerSchemaProvider.d.ts +0 -17
  156. package/dist/core/ServerSchemaProvider.js +0 -120
  157. package/dist/core/constants.d.ts +0 -47
  158. package/dist/core/constants.js +0 -94
  159. package/dist/core/installers/BaseInstaller.d.ts +0 -74
  160. package/dist/core/installers/BaseInstaller.js +0 -253
  161. package/dist/core/installers/ClientInstaller.d.ts +0 -23
  162. package/dist/core/installers/ClientInstaller.js +0 -564
  163. package/dist/core/installers/CommandInstaller.d.ts +0 -37
  164. package/dist/core/installers/CommandInstaller.js +0 -173
  165. package/dist/core/installers/GeneralInstaller.d.ts +0 -33
  166. package/dist/core/installers/GeneralInstaller.js +0 -85
  167. package/dist/core/installers/InstallerFactory.d.ts +0 -54
  168. package/dist/core/installers/InstallerFactory.js +0 -97
  169. package/dist/core/installers/NpmInstaller.d.ts +0 -26
  170. package/dist/core/installers/NpmInstaller.js +0 -127
  171. package/dist/core/installers/PipInstaller.d.ts +0 -28
  172. package/dist/core/installers/PipInstaller.js +0 -127
  173. package/dist/core/installers/RequirementInstaller.d.ts +0 -33
  174. package/dist/core/installers/RequirementInstaller.js +0 -3
  175. package/dist/core/types.d.ts +0 -166
  176. package/dist/core/types.js +0 -16
  177. package/dist/services/InstallRequestValidator.d.ts +0 -21
  178. package/dist/services/InstallRequestValidator.js +0 -99
  179. package/dist/web/public/js/modal/installHandler.js +0 -227
  180. package/dist/web/public/js/modal/loadingUI.js +0 -74
  181. package/dist/web/public/js/modal/modalUI.js +0 -214
  182. package/dist/web/public/js/modal/version.js +0 -20
  183. package/src/web/public/js/modal/messageQueue.js +0 -112
@@ -3,8 +3,6 @@ import { fileURLToPath } from 'url';
3
3
  import { Logger } from '../utils/logger.js';
4
4
  import { ServerSchemaProvider } from '../core/loaders/ServerSchemaProvider.js';
5
5
  import { mcpManager } from './MCPManager.js';
6
- import { UPDATE_CHECK_INTERVAL_MS } from '../core/metadatas/constants.js';
7
- import { updateCheckTracker } from '../utils/UpdateCheckTracker.js';
8
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
7
  /**
10
8
  * ServerService provides a unified interface for server management operations.
@@ -23,80 +21,8 @@ export class ServerService {
23
21
  async getServerCategory(categoryName) {
24
22
  const serverCategories = await this.listServerCategories();
25
23
  const serverCategory = serverCategories.find(s => s.name === categoryName);
26
- // Start async check for requirement updates if one isn't already in progress
27
- if (serverCategory && serverCategory.feedConfiguration && serverCategory.name) {
28
- // Check if update is already in progress using the tracker
29
- const shouldCheckForUpdates = await updateCheckTracker.startOperation(serverCategory.name);
30
- if (shouldCheckForUpdates) {
31
- this.checkRequirementsForUpdate(serverCategory).catch(error => {
32
- // Ensure we mark the operation as complete on error
33
- if (serverCategory.name) {
34
- updateCheckTracker.endOperation(serverCategory.name)
35
- .catch(lockError => console.error(`Failed to mark update check as complete: ${lockError.message}`));
36
- }
37
- Logger.error(`Error checking requirements for updates: ${error.message}`);
38
- });
39
- }
40
- else {
41
- Logger.debug(`Update check already in progress for ${serverCategory.name}, skipping`);
42
- }
43
- }
44
24
  return serverCategory;
45
25
  }
46
- /**
47
- * Check for updates to requirements for a server category
48
- * @param serverCategory The server category to check
49
- * @private
50
- */
51
- async checkRequirementsForUpdate(serverCategory) {
52
- if (!serverCategory.name || !serverCategory.feedConfiguration?.requirements?.length) {
53
- return;
54
- }
55
- try {
56
- const { requirementService } = await import('./RequirementService.js');
57
- const { configProvider } = await import('../core/loaders/ConfigurationProvider.js');
58
- for (const requirement of serverCategory.feedConfiguration.requirements) {
59
- if (requirement.version.includes('latest')) {
60
- // Get current status if available
61
- const currentStatus = serverCategory.installationStatus?.requirementsStatus[requirement.name];
62
- if (!currentStatus)
63
- continue;
64
- // Skip update check if last check was less than UPDATE_CHECK_INTERVAL_MS ago
65
- if (currentStatus.lastCheckTime) {
66
- const lastCheckTime = new Date(currentStatus.lastCheckTime);
67
- const currentTime = new Date();
68
- const timeSinceLastCheck = currentTime.getTime() - lastCheckTime.getTime();
69
- if (timeSinceLastCheck < UPDATE_CHECK_INTERVAL_MS) {
70
- Logger.debug(`Skipping update check for ${requirement.name}, last check was ${Math.round(timeSinceLastCheck / 1000)} seconds ago`);
71
- continue;
72
- }
73
- }
74
- // Check for updates
75
- const updatedStatus = await requirementService.checkRequirementForUpdates(requirement, currentStatus);
76
- // If update information is found, update the configuration
77
- if (updatedStatus.availableUpdate && serverCategory.name) {
78
- await configProvider.updateRequirementStatus(serverCategory.name, requirement.name, updatedStatus);
79
- // Also update the in-memory status for immediate use
80
- if (serverCategory.installationStatus?.requirementsStatus) {
81
- serverCategory.installationStatus.requirementsStatus[requirement.name] = updatedStatus;
82
- }
83
- }
84
- currentStatus.lastCheckTime = new Date().toISOString();
85
- await configProvider.updateRequirementStatus(serverCategory.name, requirement.name, currentStatus);
86
- if (serverCategory.installationStatus?.requirementsStatus) {
87
- serverCategory.installationStatus.requirementsStatus[requirement.name] = updatedStatus;
88
- }
89
- }
90
- }
91
- }
92
- finally {
93
- // Always mark the operation as complete when done, even if there was an error
94
- if (serverCategory.name) {
95
- await updateCheckTracker.endOperation(serverCategory.name)
96
- .catch(error => console.error(`Failed to mark update check as complete: ${error.message}`));
97
- }
98
- }
99
- }
100
26
  /**
101
27
  * Gets the schema for a specific server in a category
102
28
  */
@@ -0,0 +1,15 @@
1
+ export declare class TelemetryService {
2
+ private static client;
3
+ private static readonly instrumentationKey;
4
+ static trackEvent(name: string, properties?: {
5
+ [key: string]: string;
6
+ }): void;
7
+ static trackException(error: Error, properties?: {
8
+ [key: string]: string;
9
+ }): void;
10
+ static trackTrace(message: string, properties?: {
11
+ [key: string]: string;
12
+ }): void;
13
+ static trackMetric(name: string, value: number): void;
14
+ static flush(): Promise<void>;
15
+ }
@@ -0,0 +1,54 @@
1
+ import * as appInsights from 'applicationinsights';
2
+ export class TelemetryService {
3
+ static client = null;
4
+ static instrumentationKey = 'InstrumentationKey=c5fc06c7-a96c-4d80-9aff-bc9c933db0d1';
5
+ static {
6
+ // Initialize Application Insights
7
+ try {
8
+ const client = new appInsights.TelemetryClient(TelemetryService.instrumentationKey);
9
+ client.config.disableAppInsights = false;
10
+ client.config.maxBatchSize = 250;
11
+ client.context.tags[client.context.keys.cloudRole] = 'imcp';
12
+ TelemetryService.client = client;
13
+ console.log('Application Insights initialized');
14
+ }
15
+ catch (error) {
16
+ console.error('Failed to initialize Application Insights:', error);
17
+ }
18
+ }
19
+ static trackEvent(name, properties) {
20
+ if (!this.client) {
21
+ return;
22
+ }
23
+ this.client.trackEvent({ name, properties });
24
+ }
25
+ static trackException(error, properties) {
26
+ if (!this.client) {
27
+ return;
28
+ }
29
+ this.client.trackException({ exception: error, properties });
30
+ }
31
+ static trackTrace(message, properties) {
32
+ if (!this.client) {
33
+ return;
34
+ }
35
+ this.client.trackTrace({ message, properties });
36
+ }
37
+ static trackMetric(name, value) {
38
+ if (!this.client) {
39
+ return;
40
+ }
41
+ this.client.trackMetric({ name, value });
42
+ }
43
+ static flush() {
44
+ return new Promise((resolve) => {
45
+ if (!this.client) {
46
+ resolve();
47
+ return;
48
+ }
49
+ this.client.flush();
50
+ resolve();
51
+ });
52
+ }
53
+ }
54
+ //# sourceMappingURL=TelemetryService.js.map
@@ -104,11 +104,11 @@ targetDir // Optional target directory for npm
104
104
  if (!registry) {
105
105
  throw new Error('Azure DevOps artifacts registry configuration is required.');
106
106
  }
107
- if (!registry.registryName || !registry.registryUrl) {
108
- throw new Error('Registry name and URL are required for Azure DevOps artifacts.');
109
- }
110
107
  Logger.debug(`Handling ADO artifact for requirement: ${requirement.name}, type: ${requirement.type}`);
111
108
  if (requirement.type === 'npm') {
109
+ if (!registry.registryName || !registry.registryUrl) {
110
+ throw new Error('Registry name and URL are required for NPM source in Azure DevOps artifacts.');
111
+ }
112
112
  const requirementDir = targetDir || path.join(SETTINGS_DIR, 'requirements', requirement.name, requirement.version);
113
113
  await fs.mkdir(requirementDir, { recursive: true });
114
114
  Logger.debug(`Ensured directory for npm requirement: ${requirementDir}`);
@@ -130,6 +130,9 @@ targetDir // Optional target directory for npm
130
130
  }
131
131
  }
132
132
  else if (requirement.type === 'pip') {
133
+ if (!registry.registryUrl) {
134
+ throw new Error('Registry URL are required for PIP source in Azure DevOps artifacts.');
135
+ }
133
136
  await _installPipRequirements(pythonCommand);
134
137
  const packageName = requirement.version.toLowerCase().includes('latest')
135
138
  ? `${requirement.name} --upgrade`
@@ -2,6 +2,9 @@ import { isToolInstalled, installCLI } from './osUtils.js';
2
2
  import { exec, spawn } from 'child_process';
3
3
  import util from 'util';
4
4
  import { Logger } from './logger.js';
5
+ import fs from 'fs/promises';
6
+ import path from 'path';
7
+ import { USER_INFO_PATH } from '../core/metadatas/constants.js';
5
8
  const execAsync = util.promisify(exec);
6
9
  // Create a promisified version of spawn that returns a Promise
7
10
  const spawnAsync = (command, args, options = {}) => {
@@ -63,6 +66,8 @@ export async function checkGithubAuth() {
63
66
  });
64
67
  throw new GithubAuthError(error);
65
68
  }
69
+ // After Microsoft account verification, persist user information
70
+ await persistUserInfo();
66
71
  Logger.debug('GitHub authentication verified successfully with Microsoft account');
67
72
  }
68
73
  catch (error) {
@@ -86,6 +91,8 @@ export async function checkGithubAuth() {
86
91
  if (!viewer.login.toLowerCase().endsWith('_microsoft')) {
87
92
  throw new GithubAuthError('You must be logged in with a Microsoft account (username should end with _microsoft).');
88
93
  }
94
+ // After Microsoft account verification, persist user information
95
+ await persistUserInfo();
89
96
  Logger.debug(`Successfully authenticated as ${viewer.login}`);
90
97
  return; // Auth successful, continue execution
91
98
  }
@@ -110,4 +117,62 @@ export async function checkGithubAuth() {
110
117
  }
111
118
  }
112
119
  }
120
+ /**
121
+ * Persists GitHub user information to the system-specific settings directory.
122
+ * Only performs persistence on non-Windows systems (Linux/macOS).
123
+ */
124
+ async function persistUserInfo() {
125
+ try {
126
+ Logger.debug('Starting user information persistence check');
127
+ // 1. Skip persistence on Windows systems
128
+ if (process.platform === 'win32') {
129
+ Logger.debug('Skipping user info persistence on Windows system');
130
+ return;
131
+ }
132
+ // 2. Check if file exists and has all required keys
133
+ try {
134
+ if (await fs.access(USER_INFO_PATH).then(() => true).catch(() => false)) {
135
+ const existingContent = await fs.readFile(USER_INFO_PATH, 'utf8');
136
+ const existingData = JSON.parse(existingContent);
137
+ if (existingData.alias && existingData.name && existingData.email) {
138
+ Logger.debug('User info already exists with all required fields, skipping update');
139
+ return;
140
+ }
141
+ }
142
+ }
143
+ catch (err) {
144
+ Logger.debug('No valid existing user info found, proceeding with persistence');
145
+ }
146
+ // Proceed with persistence since both checks passed
147
+ Logger.debug('Proceeding with user information persistence');
148
+ // Get user info from GitHub API
149
+ const { stdout: userDataStr } = await execAsync('gh api user');
150
+ const userData = JSON.parse(userDataStr);
151
+ const { login, name, email } = userData;
152
+ Logger.debug({ message: 'Retrieved user information from GitHub API', login, name, email });
153
+ // Check if login ends with _microsoft
154
+ if (!login.toLowerCase().endsWith('_microsoft')) {
155
+ Logger.log(`GitHub login "${login}" does not end with _microsoft, skipping user information persistence`);
156
+ return;
157
+ }
158
+ // Create directory if it doesn't exist
159
+ await fs.mkdir(path.dirname(USER_INFO_PATH), { recursive: true });
160
+ Logger.debug(`Ensuring directory exists for user info at ${USER_INFO_PATH}`);
161
+ // Extract alias from login (remove _microsoft suffix)
162
+ const alias = login.toLowerCase().replace(/_microsoft$/, '');
163
+ // Prepare user information
164
+ const userInfo = {
165
+ alias,
166
+ name,
167
+ email
168
+ };
169
+ // Write user information to file
170
+ await fs.writeFile(USER_INFO_PATH, JSON.stringify(userInfo, null, 2));
171
+ Logger.debug({ message: 'User information persisted successfully', path: USER_INFO_PATH, alias });
172
+ }
173
+ catch (error) {
174
+ Logger.error('Failed to persist user information:', error);
175
+ // Don't throw - persistence failure shouldn't block auth flow
176
+ }
177
+ }
113
178
  //# sourceMappingURL=githubAuth.js.map
@@ -1,7 +1,21 @@
1
+ export declare enum EventType {
2
+ IMCP_SERVE = "imcp_serve",
3
+ SERVER_INSTALL = "server_install",
4
+ SERVER_UNINSTALL = "server_uninstall",
5
+ REQUIREMENT_UPDATE = "requirement_update",
6
+ FEED_ONBOARD = "feed_onboard",
7
+ FEED_VALIDATE = "feed_validate"
8
+ }
9
+ export declare enum EventStatus {
10
+ SUCCESS = "success",
11
+ FAILED = "failed"
12
+ }
1
13
  export declare class Logger {
2
14
  private static verbose;
3
15
  private static fileLoggingEnabled;
4
16
  private static logsDir;
17
+ private static isTestEnvironment;
18
+ private static packageVersion;
5
19
  static setVerbose(isVerbose: boolean): void;
6
20
  static setFileLogging(enabled: boolean): void;
7
21
  private static ensureLogsDirExists;
@@ -13,4 +27,6 @@ export declare class Logger {
13
27
  static warn(message: string): Promise<void>;
14
28
  static debug(message: string | object): Promise<void>;
15
29
  static error(message: string, error?: unknown): Promise<void>;
30
+ private static getUsername;
31
+ static trackEvent(eventType: EventType, dimensions: Record<string, any>): void;
16
32
  }
@@ -1,10 +1,29 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { SETTINGS_DIR } from '../core/metadatas/constants.js';
3
+ import os from 'os';
4
+ import { SETTINGS_DIR, USER_INFO_PATH } from '../core/metadatas/constants.js';
5
+ import { TelemetryService } from '../services/TelemetryService.js';
6
+ import { getPackageVersion } from './versionUtils.js';
7
+ export var EventType;
8
+ (function (EventType) {
9
+ EventType["IMCP_SERVE"] = "imcp_serve";
10
+ EventType["SERVER_INSTALL"] = "server_install";
11
+ EventType["SERVER_UNINSTALL"] = "server_uninstall";
12
+ EventType["REQUIREMENT_UPDATE"] = "requirement_update";
13
+ EventType["FEED_ONBOARD"] = "feed_onboard";
14
+ EventType["FEED_VALIDATE"] = "feed_validate";
15
+ })(EventType || (EventType = {}));
16
+ export var EventStatus;
17
+ (function (EventStatus) {
18
+ EventStatus["SUCCESS"] = "success";
19
+ EventStatus["FAILED"] = "failed";
20
+ })(EventStatus || (EventStatus = {}));
4
21
  export class Logger {
5
22
  static verbose = false;
6
23
  static fileLoggingEnabled = true;
7
24
  static logsDir = path.join(SETTINGS_DIR, 'logs');
25
+ static isTestEnvironment = false;
26
+ static packageVersion = getPackageVersion().packageVersion;
8
27
  static setVerbose(isVerbose) {
9
28
  this.verbose = isVerbose;
10
29
  }
@@ -96,5 +115,63 @@ export class Logger {
96
115
  }
97
116
  await this.writeToLogFile('ERROR', logMessage);
98
117
  }
118
+ static getUsername() {
119
+ try {
120
+ // If on Windows, use os username directly
121
+ if (process.platform === 'win32') {
122
+ return os.userInfo().username;
123
+ }
124
+ // For Mac/Linux users
125
+ try {
126
+ const userInfoPath = USER_INFO_PATH;
127
+ if (fs.existsSync(userInfoPath)) {
128
+ const userInfo = JSON.parse(fs.readFileSync(userInfoPath, 'utf8'));
129
+ if (userInfo.alias) {
130
+ return userInfo.alias;
131
+ }
132
+ }
133
+ }
134
+ catch (error) {
135
+ this.error('Failed to get user info from file', error);
136
+ }
137
+ // Fall back to os username if all else fails
138
+ return os.userInfo().username;
139
+ }
140
+ catch (error) {
141
+ this.error('Failed to get username', error);
142
+ return 'unknown';
143
+ }
144
+ }
145
+ static trackEvent(eventType, dimensions) {
146
+ try {
147
+ const username = this.getUsername();
148
+ // Add username and package version to dimensions
149
+ const allDimensions = {
150
+ username,
151
+ packageVersion: this.packageVersion,
152
+ ...dimensions
153
+ };
154
+ // Log to file
155
+ if (this.verbose) {
156
+ this.log(`Event: ${eventType}`);
157
+ this.log(JSON.stringify(allDimensions, null, 2));
158
+ }
159
+ // Skip AppInsights in test environment
160
+ if (Logger.isTestEnvironment) {
161
+ return;
162
+ }
163
+ // Log to Application Insights
164
+ try {
165
+ TelemetryService.trackEvent(eventType, allDimensions);
166
+ TelemetryService.flush();
167
+ }
168
+ catch (insightsError) {
169
+ this.error('Failed to track event in Application Insights', insightsError);
170
+ }
171
+ }
172
+ catch (error) {
173
+ this.error('Failed to log event', error);
174
+ }
175
+ }
99
176
  }
100
177
  //# sourceMappingURL=logger.js.map
@@ -1,8 +1,5 @@
1
1
  import { Logger } from './logger.js';
2
- import { getPythonPackagePath, getSystemPythonPackageDirectory, GetBrowserPath } from './osUtils.js';
3
- import * as fsSync from 'fs';
4
- import * as path from 'path';
5
- import { execSync } from 'child_process';
2
+ import { getPythonPackagePath, getSystemPythonPackageDirectory, getBrowserPath, getGlobalNPMPackagePath } from './osUtils.js';
6
3
  export const MACRO_EXPRESSIONS = {
7
4
  PYTHON_PACKAGE: '${PYTHON_PACKAGE}',
8
5
  NPMPATH: '${NPMPATH}',
@@ -57,26 +54,7 @@ export function resolveNpmModulePath(providedNpmPath) {
57
54
  if (providedNpmPath) {
58
55
  return `${providedNpmPath}/node_modules`;
59
56
  }
60
- const nvmHome = process.env.NVM_HOME;
61
- if (nvmHome) {
62
- try {
63
- const nodeVersion = execSync('node -v').toString().trim();
64
- const nvmNodePath = path.join(nvmHome, nodeVersion);
65
- // Check if this path exists
66
- try {
67
- fsSync.accessSync(nvmNodePath);
68
- Logger.debug(`Resolved ${MACRO_EXPRESSIONS.NPMPATH} via NVM to: ${nvmNodePath}`);
69
- return nvmNodePath;
70
- }
71
- catch (error) {
72
- Logger.debug(`NVM controlled path doesn't exist: ${nvmNodePath}, will try global npm`);
73
- }
74
- }
75
- catch (error) {
76
- Logger.debug(`Error determining Node version for NVM: ${error}, will use global npm`);
77
- }
78
- }
79
- const globalNpmPath = execSync('npm root -g').toString().trim();
57
+ const globalNpmPath = getGlobalNPMPackagePath();
80
58
  Logger.debug(`Resolved ${MACRO_EXPRESSIONS.NPMPATH} via global npm to: ${globalNpmPath}`);
81
59
  return globalNpmPath;
82
60
  }
@@ -104,7 +82,7 @@ export async function resolveNpmPathMacro(_finalConfig, options) {
104
82
  export async function resolveBrowserPathMacro() {
105
83
  Logger.debug(`Resolving ${MACRO_EXPRESSIONS.BROWSER_PATH}`);
106
84
  try {
107
- const browserPath = await GetBrowserPath();
85
+ const browserPath = await getBrowserPath();
108
86
  Logger.debug(`Resolved ${MACRO_EXPRESSIONS.BROWSER_PATH} to: ${browserPath}`);
109
87
  return browserPath;
110
88
  }
@@ -14,4 +14,25 @@ export declare function isToolInstalled(tool: 'gh' | 'git', retries?: number): P
14
14
  export declare function openBrowser(url: string): Promise<void>;
15
15
  export declare function getPythonPackagePath(pythonExecutablePath: string): string;
16
16
  export declare function getSystemPythonPackageDirectory(): Promise<string | null>;
17
- export declare function GetBrowserPath(): Promise<string>;
17
+ /**
18
+ * Get the system Python executable path.
19
+ * This function returns the absolute path to the system Python executable (e.g., /Users/penwa/miniconda3/envs/browser-use-temp/bin/python).
20
+ * It uses 'which python' (Unix) or 'where python' (Windows) to locate the executable.
21
+ * @returns {Promise<string | null>} The path to the Python executable, or null if not found.
22
+ */
23
+ export declare function getSystemPythonExecutablePath(): Promise<string | null>;
24
+ export declare function getBrowserPath(): Promise<string>;
25
+ /**
26
+ * Get the global NPM path
27
+ * This function checks if NVM is installed and retrieves the global NPM path accordingly.
28
+ * If NVM is not installed, it falls back to the global NPM path.
29
+ * @returns The global NPM path as a string.
30
+ * @throws Error if the NPM path cannot be determined.
31
+ * */
32
+ export declare function getGlobalNPMPackagePath(): string;
33
+ /**
34
+ * Get the NPM executable path on the current platform (Windows, macOS, Linux).
35
+ * On Windows, uses PowerShell to locate npm. On macOS/Linux, uses 'which' to locate npm.
36
+ * Returns the directory containing the npm executable, or a platform-appropriate default if not found.
37
+ */
38
+ export declare function getNpmExecutablePath(): Promise<string>;
@@ -5,6 +5,8 @@ import util from 'util';
5
5
  import { Logger } from './logger.js';
6
6
  import fs from 'fs';
7
7
  import path from 'path';
8
+ import { execSync } from 'child_process';
9
+ import * as fsSync from 'fs';
8
10
  const execAsync = util.promisify(exec);
9
11
  export function getOSType() {
10
12
  const platform = os.platform();
@@ -394,7 +396,38 @@ export async function getSystemPythonPackageDirectory() {
394
396
  return null;
395
397
  }
396
398
  }
397
- export async function GetBrowserPath() {
399
+ /**
400
+ * Get the system Python executable path.
401
+ * This function returns the absolute path to the system Python executable (e.g., /Users/penwa/miniconda3/envs/browser-use-temp/bin/python).
402
+ * It uses 'which python' (Unix) or 'where python' (Windows) to locate the executable.
403
+ * @returns {Promise<string | null>} The path to the Python executable, or null if not found.
404
+ */
405
+ export async function getSystemPythonExecutablePath() {
406
+ const command = process.platform === 'win32' ? 'where python' : 'which python';
407
+ Logger.debug({
408
+ action: 'get_system_python_executable_path',
409
+ command
410
+ });
411
+ try {
412
+ const { stdout } = await execAsync(command);
413
+ // Use the first path found, trim whitespace
414
+ const pythonPath = stdout.split('\n')[0].trim();
415
+ if (pythonPath) {
416
+ Logger.debug({
417
+ action: 'get_system_python_executable_path_success',
418
+ pythonPath
419
+ });
420
+ return pythonPath;
421
+ }
422
+ Logger.debug('No Python executable found');
423
+ return null;
424
+ }
425
+ catch (error) {
426
+ Logger.debug(`Could not find system python using "${command}": ${error}`);
427
+ return null;
428
+ }
429
+ }
430
+ export async function getBrowserPath() {
398
431
  const osType = getOSType();
399
432
  Logger.debug({
400
433
  action: 'get_system_browser_path',
@@ -471,4 +504,62 @@ export async function GetBrowserPath() {
471
504
  throw error;
472
505
  }
473
506
  }
507
+ /**
508
+ * Get the global NPM path
509
+ * This function checks if NVM is installed and retrieves the global NPM path accordingly.
510
+ * If NVM is not installed, it falls back to the global NPM path.
511
+ * @returns The global NPM path as a string.
512
+ * @throws Error if the NPM path cannot be determined.
513
+ * */
514
+ export function getGlobalNPMPackagePath() {
515
+ const nvmHome = process.env.NVM_HOME;
516
+ if (nvmHome) {
517
+ try {
518
+ const nodeVersion = execSync('node -v').toString().trim();
519
+ const nvmNodePath = path.join(nvmHome, nodeVersion);
520
+ // Check if this path exists
521
+ try {
522
+ fsSync.accessSync(nvmNodePath);
523
+ return nvmNodePath;
524
+ }
525
+ catch (error) {
526
+ Logger.debug(`NVM controlled path doesn't exist: ${nvmNodePath}, will try global npm`);
527
+ }
528
+ }
529
+ catch (error) {
530
+ Logger.debug(`Error determining Node version for NVM: ${error}, will use global npm`);
531
+ }
532
+ }
533
+ const globalNpmPath = execSync('npm root -g').toString().trim();
534
+ return globalNpmPath;
535
+ }
536
+ /**
537
+ * Get the NPM executable path on the current platform (Windows, macOS, Linux).
538
+ * On Windows, uses PowerShell to locate npm. On macOS/Linux, uses 'which' to locate npm.
539
+ * Returns the directory containing the npm executable, or a platform-appropriate default if not found.
540
+ */
541
+ export async function getNpmExecutablePath() {
542
+ try {
543
+ if (process.platform === 'win32') {
544
+ const { stdout } = await execAsync('powershell -Command "get-command npm | Select-Object -ExpandProperty Source"');
545
+ return stdout.trim().replace(/\\npm\.cmd$/, '');
546
+ }
547
+ else {
548
+ // macOS or Linux
549
+ const { stdout } = await execAsync('which npm');
550
+ // Remove the trailing '/npm' to get the directory
551
+ return stdout.trim().replace(/\/npm$/, '');
552
+ }
553
+ }
554
+ catch (error) {
555
+ Logger.error('Error getting npm path:', error);
556
+ if (process.platform === 'win32') {
557
+ return 'C:\\Program Files\\nodejs';
558
+ }
559
+ else {
560
+ // Common default for Unix systems
561
+ return '/usr/local/bin';
562
+ }
563
+ }
564
+ }
474
565
  //# sourceMappingURL=osUtils.js.map
@@ -1,3 +1,7 @@
1
+ export declare function getPackageVersion(): {
2
+ packageName: string;
3
+ packageVersion: string;
4
+ };
1
5
  /**
2
6
  * Utility functions for version comparison and management
3
7
  */
@@ -10,3 +14,19 @@
10
14
  * a positive number if v1 > v2, 0 if equal)
11
15
  */
12
16
  export declare function compareVersions(v1: string, v2: string): number;
17
+ /**
18
+ * Check if there's a newer version of the package available
19
+ */
20
+ export declare function checkForUpdates(): Promise<void>;
21
+ /**
22
+ * Retrieves the application version and information about available updates.
23
+ * @returns A promise that resolves to an object containing the current packageVersion and any availableUpdates.
24
+ */
25
+ export declare function getAppVersion(): Promise<{
26
+ name: string;
27
+ version: string;
28
+ availableUpdate?: {
29
+ latestVersion: string;
30
+ message: string;
31
+ };
32
+ }>;