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
@@ -0,0 +1,257 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { SETTINGS_DIR } from '../metadatas/constants.js';
4
+ import { Logger } from '../../utils/logger.js';
5
+ import { getSystemPythonExecutablePath, getNpmExecutablePath, getBrowserPath } from '../../utils/osUtils.js';
6
+ const SETTINGS_FILE_NAME = 'system_settings.json';
7
+ const SETTINGS_FILE_PATH = path.join(SETTINGS_DIR, 'settings', SETTINGS_FILE_NAME);
8
+ export class SystemSettingsManager {
9
+ static instance;
10
+ settings;
11
+ settingsFilePath;
12
+ settingsLock = Promise.resolve();
13
+ constructor() {
14
+ this.settingsFilePath = SETTINGS_FILE_PATH;
15
+ this.settings = {};
16
+ // No await here, initialization is best-effort. Lock will protect subsequent calls.
17
+ this.loadSettings().catch(error => {
18
+ Logger.error('Failed to initialize SystemSettingsManager during construction:', error);
19
+ // Initialize with empty settings if load fails, defaults will be applied on first access
20
+ this.settings = {};
21
+ });
22
+ }
23
+ static getInstance() {
24
+ if (!SystemSettingsManager.instance) {
25
+ SystemSettingsManager.instance = new SystemSettingsManager();
26
+ }
27
+ return SystemSettingsManager.instance;
28
+ }
29
+ async withLock(operation) {
30
+ const currentLock = this.settingsLock;
31
+ let releaseLock;
32
+ this.settingsLock = new Promise(resolve => releaseLock = resolve);
33
+ try {
34
+ await currentLock;
35
+ return await operation();
36
+ }
37
+ finally {
38
+ releaseLock();
39
+ }
40
+ }
41
+ // Internal method without lock
42
+ async _loadSettingsInternal() {
43
+ try {
44
+ await fs.mkdir(path.dirname(this.settingsFilePath), { recursive: true });
45
+ const data = await fs.readFile(this.settingsFilePath, 'utf-8');
46
+ this.settings = JSON.parse(data);
47
+ await this._applyDefaultsIfNeededInternal(); // Call internal version
48
+ }
49
+ catch (error) {
50
+ if (error.code === 'ENOENT') {
51
+ Logger.info(`Settings file not found at ${this.settingsFilePath}. Initializing with defaults.`);
52
+ this.settings = {};
53
+ await this._applyDefaultsIfNeededInternal(); // Call internal version
54
+ }
55
+ else {
56
+ Logger.error(`Error loading settings from ${this.settingsFilePath}:`, error);
57
+ this.settings = {};
58
+ await this._applyDefaultsIfNeededInternal(); // Call internal version
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * Loads settings from the file. This operation is atomic.
64
+ * If the settings file doesn't exist, it initializes with defaults and creates the file.
65
+ * @returns A promise that resolves when settings are loaded.
66
+ */
67
+ async loadSettings() {
68
+ return this.withLock(() => this._loadSettingsInternal());
69
+ }
70
+ // Internal method without lock
71
+ async _applyDefaultsIfNeededInternal() {
72
+ let updated = false;
73
+ const normalizePath = (p) => p ? p.replace(/\\/g, '/') : undefined;
74
+ if (!this.settings.pythonEnvs) {
75
+ this.settings.pythonEnvs = {};
76
+ updated = true;
77
+ }
78
+ if (!this.settings.pythonEnvs["system"]) {
79
+ try {
80
+ const pythonPath = normalizePath(await getSystemPythonExecutablePath() || undefined);
81
+ if (pythonPath) {
82
+ this.settings.pythonEnvs["system"] = pythonPath;
83
+ updated = true;
84
+ }
85
+ }
86
+ catch (e) {
87
+ Logger.warn(`Could not get default pythonEnv: ${e}`);
88
+ }
89
+ }
90
+ if (!this.settings.nodePath) {
91
+ try {
92
+ const npmExecDir = await getNpmExecutablePath();
93
+ let nodeExecutable = process.platform === 'win32' ? 'node.exe' : 'node';
94
+ const platformNodePath = process.platform === 'win32'
95
+ ? path.join(npmExecDir || '', nodeExecutable)
96
+ : path.join(npmExecDir || '', 'bin', nodeExecutable);
97
+ this.settings.nodePath = npmExecDir ? normalizePath(platformNodePath) : undefined;
98
+ if (this.settings.nodePath)
99
+ updated = true;
100
+ }
101
+ catch (e) {
102
+ Logger.warn(`Could not get default nodePath: ${e}`);
103
+ }
104
+ }
105
+ else {
106
+ this.settings.nodePath = normalizePath(this.settings.nodePath);
107
+ }
108
+ if (!this.settings.browserPath) {
109
+ try {
110
+ this.settings.browserPath = normalizePath(await getBrowserPath() || undefined);
111
+ if (this.settings.browserPath)
112
+ updated = true;
113
+ }
114
+ catch (e) {
115
+ Logger.warn(`Could not get default browserPath: ${e}`);
116
+ }
117
+ }
118
+ else {
119
+ this.settings.browserPath = normalizePath(this.settings.browserPath);
120
+ }
121
+ if (!this.settings.systemEnvironments) {
122
+ this.settings.systemEnvironments = { ...process.env };
123
+ updated = true;
124
+ }
125
+ if (this.settings.userConfigurations === undefined) {
126
+ this.settings.userConfigurations = {};
127
+ updated = true;
128
+ }
129
+ if (updated) {
130
+ await this._saveSettingsInternal();
131
+ }
132
+ }
133
+ /**
134
+ * Applies default values to settings if they are not already set.
135
+ * This operation is atomic and saves settings if defaults are applied.
136
+ * @returns A promise that resolves when defaults are applied and saved if necessary.
137
+ */
138
+ async applyDefaultsIfNeeded() {
139
+ return this.withLock(() => this._applyDefaultsIfNeededInternal());
140
+ }
141
+ /**
142
+ * Retrieves the current system settings.
143
+ * If settings haven't been loaded or are empty, it attempts to load them.
144
+ * Paths within the settings are normalized (e.g., backslashes to forward slashes).
145
+ * @returns A promise that resolves to the `SystemSettings` object.
146
+ */
147
+ async getSystemSettings() {
148
+ // Ensure settings are loaded if they are empty.
149
+ if (Object.keys(this.settings).length === 0) {
150
+ // Use the public, locked version of loadSettings here
151
+ await this.loadSettings();
152
+ }
153
+ // Return a deep copy to prevent external modification of the internal state.
154
+ // Ensure this.settings is used, not a potentially stale local copy.
155
+ const settingsToReturn = JSON.parse(JSON.stringify(this.settings));
156
+ // Ensure paths are normalized when retrieved
157
+ const normalizedSettings = { ...settingsToReturn };
158
+ // Normalize paths in pythonEnvs
159
+ if (normalizedSettings.pythonEnvs) {
160
+ const normalizedPythonEnvs = {};
161
+ Object.keys(normalizedSettings.pythonEnvs).forEach(key => {
162
+ normalizedPythonEnvs[key] = normalizedSettings.pythonEnvs?.[key]?.replace(/\\/g, '/') || '';
163
+ });
164
+ normalizedSettings.pythonEnvs = normalizedPythonEnvs;
165
+ }
166
+ normalizedSettings.nodePath = normalizedSettings.nodePath?.replace(/\\/g, '/');
167
+ normalizedSettings.browserPath = normalizedSettings.browserPath?.replace(/\\/g, '/');
168
+ return normalizedSettings;
169
+ }
170
+ /**
171
+ * Creates or updates system settings with the provided partial settings.
172
+ * This operation is atomic and protected by a lock.
173
+ * It loads existing settings if not already loaded, merges the new settings,
174
+ * applies any necessary defaults, and then saves the updated settings.
175
+ * @param newSettings A `Partial<SystemSettings>` object containing the settings to update.
176
+ * @returns A promise that resolves to the fully updated and normalized `SystemSettings`.
177
+ */
178
+ async createOrUpdateSystemSettings(newSettings) {
179
+ return this.withLock(async () => {
180
+ // Ensure current settings are loaded before modification by calling the internal, non-locking version
181
+ if (Object.keys(this.settings).length === 0) {
182
+ await this._loadSettingsInternal();
183
+ }
184
+ const normalizePath = (p) => p ? p.replace(/\\/g, '/') : undefined;
185
+ // Initialize pythonEnvs if it doesn't exist on the current settings
186
+ if (!this.settings.pythonEnvs) {
187
+ this.settings.pythonEnvs = {};
188
+ }
189
+ // Create a new settings object by merging current and new settings.
190
+ const updatedSettings = {
191
+ ...this.settings, // Start with current settings
192
+ ...newSettings, // Override with new settings
193
+ // Explicitly handle potentially undefined paths from newSettings
194
+ nodePath: normalizePath(newSettings.nodePath !== undefined ? newSettings.nodePath : this.settings.nodePath),
195
+ browserPath: normalizePath(newSettings.browserPath !== undefined ? newSettings.browserPath : this.settings.browserPath),
196
+ // Ensure systemEnvironments and userConfigurations are properly merged or taken from newSettings
197
+ systemEnvironments: newSettings.systemEnvironments !== undefined
198
+ ? newSettings.systemEnvironments
199
+ : this.settings.systemEnvironments, // Keep existing if not in newSettings
200
+ userConfigurations: newSettings.userConfigurations !== undefined
201
+ ? newSettings.userConfigurations
202
+ : this.settings.userConfigurations || {}, // Keep existing or default to empty
203
+ };
204
+ this.settings = updatedSettings;
205
+ // Call the internal, non-locking version of applyDefaultsIfNeeded
206
+ await this._applyDefaultsIfNeededInternal();
207
+ // _applyDefaultsIfNeededInternal will call _saveSettingsInternal if it makes changes.
208
+ // However, if newSettings were provided that didn't trigger a change in _applyDefaultsIfNeededInternal
209
+ // (e.g., just updating an existing path), we still need to save.
210
+ // So, always call _saveSettingsInternal to persist all merged changes.
211
+ await this._saveSettingsInternal();
212
+ Logger.info('System settings updated.');
213
+ // getSystemSettings will handle its own locking if it needs to load.
214
+ return this.getSystemSettings();
215
+ });
216
+ }
217
+ /**
218
+ * Internal method to save settings to the file without acquiring a lock.
219
+ * Assumes the lock is already held by the calling public method.
220
+ * Normalizes paths before saving.
221
+ * @returns A promise that resolves when settings are written to disk.
222
+ */
223
+ async _saveSettingsInternal() {
224
+ try {
225
+ // Normalize paths before saving
226
+ const settingsToSave = { ...this.settings };
227
+ settingsToSave.nodePath = settingsToSave.nodePath?.replace(/\\/g, '/');
228
+ settingsToSave.browserPath = settingsToSave.browserPath?.replace(/\\/g, '/');
229
+ if (settingsToSave.pythonEnvs) {
230
+ const normalizedPythonEnvs = {};
231
+ Object.keys(settingsToSave.pythonEnvs).forEach(key => {
232
+ normalizedPythonEnvs[key] = settingsToSave.pythonEnvs?.[key]?.replace(/\\/g, '/') || '';
233
+ });
234
+ settingsToSave.pythonEnvs = normalizedPythonEnvs;
235
+ }
236
+ await fs.mkdir(path.dirname(this.settingsFilePath), { recursive: true });
237
+ await fs.writeFile(this.settingsFilePath, JSON.stringify(settingsToSave, null, 2));
238
+ Logger.info(`System settings saved to ${this.settingsFilePath}`);
239
+ }
240
+ catch (error) {
241
+ Logger.error(`Error saving settings to ${this.settingsFilePath}:`, error);
242
+ throw error; // Re-throw to indicate failure
243
+ }
244
+ }
245
+ /**
246
+ * Saves the current settings to the file. This operation is atomic and protected by a lock.
247
+ * Paths are normalized before saving.
248
+ * @returns A promise that resolves when the settings are saved.
249
+ */
250
+ async saveSettings() {
251
+ await this.withLock(async () => {
252
+ await this._saveSettingsInternal();
253
+ });
254
+ }
255
+ }
256
+ export const systemSettingsManager = SystemSettingsManager.getInstance();
257
+ //# sourceMappingURL=SystemSettingsManager.js.map
@@ -18,6 +18,13 @@ export declare const SETTINGS_DIR: string;
18
18
  * Local feeds directory path
19
19
  */
20
20
  export declare const LOCAL_FEEDS_DIR: string;
21
+ /**
22
+ * Path to the user information file
23
+ */
24
+ export declare const USER_INFO_PATH: string;
25
+ /**
26
+ * Path to the local feeds schema directory
27
+ */
21
28
  export declare const LOCAL_FEEDS_SCHEMA_DIR: string;
22
29
  /**
23
30
  * Supported client configurations.
@@ -27,6 +27,13 @@ export const SETTINGS_DIR = (() => {
27
27
  * Local feeds directory path
28
28
  */
29
29
  export const LOCAL_FEEDS_DIR = path.join(SETTINGS_DIR, 'feeds');
30
+ /**
31
+ * Path to the user information file
32
+ */
33
+ export const USER_INFO_PATH = path.join(SETTINGS_DIR, 'settings', 'user_info.json');
34
+ /**
35
+ * Path to the local feeds schema directory
36
+ */
30
37
  export const LOCAL_FEEDS_SCHEMA_DIR = path.join(LOCAL_FEEDS_DIR, 'schemas');
31
38
  const CODE_STRORAGE_DIR = (() => {
32
39
  switch (process.platform) {
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Step name constants for InstallOperationManager and step recording.
3
+ *
4
+ * This file defines all static step names and documents dynamic step name patterns
5
+ * used throughout the installation and onboarding process.
6
+ *
7
+ * Dynamic step names are documented as template string patterns.
8
+ */
9
+ /** Step for processing all requirement updates in a batch operation. */
10
+ export declare const STEP_PROCESS_REQUIREMENT_UPDATES = "Processing all requirement updates";
11
+ /** Step for checking the status of a specific requirement. */
12
+ export declare const STEP_CHECKING_REQUIREMENT_STATUS = "Checking the status of requirement";
13
+ /** Step for installing requirements in the background process. */
14
+ export declare const STEP_INSTALLING_REQUIREMENTS_IN_BACKGROUND = "Installing requirements in the background";
15
+ /** Step for checking and installing all requirements as needed. */
16
+ export declare const STEP_CHECK_AND_INSTALL_REQUIREMENTS = "Checking and installing all requirements";
17
+ /** Step for running the install logic in the CommandInstaller. */
18
+ export declare const STEP_COMMAND_INSTALLER_INSTALL = "Running install in CommandInstaller";
19
+ /** Step for running the install logic in the GeneralInstaller. */
20
+ export declare const STEP_GENERAL_INSTALLER_INSTALL = "Running install in GeneralInstaller";
21
+ /** Step for executing the actual installation command (npm, pip, etc.). */
22
+ export declare const STEP_INSTALLATION_COMMAND_EXECUTION = "Executing installation command for requirement";
23
+ /** Step for running the install logic in the PipInstaller. */
24
+ export declare const STEP_PIP_INSTALLER_INSTALL = "Running install in PipInstaller";
25
+ /** Step for processing requirement updates in the RequirementService. */
26
+ export declare const STEP_PROCESS_REQUIREMENT_UPDATES_SERVICE = "Processing requirement updates in RequirementService";
27
+ /** Step for checking if the server is ready after installation. */
28
+ export declare const STEP_CHECK_SERVER_READINESS = "Checking server readiness after installation";
29
+ /** Step for running the install logic in the NpmInstaller. */
30
+ export declare const STEP_NPM_INSTALLER_INSTALL = "Running install in NpmInstaller";
31
+ /** Prefix for steps that update a specific requirement. */
32
+ export declare const STEP_INSTALL_REQUIREMENT_PREFIX = "Updating requirement:";
33
+ /** Prefix for steps that execute an installation command for a requirement. */
34
+ export declare const STEP_INSTALL_COMMAND_PREFIX = "Executing installation command for:";
35
+ /** Step for checking and installing the VS Code extension for the client. */
36
+ export declare const STEP_CHECK_VSCODE_AND_INSTALL_EXTENSION = "Checking and installing VS Code extension for client";
37
+ /** Step for setting up the installation configuration (env, args, etc.). */
38
+ export declare const STEP_SETUP_INSTALLATION_CONFIG = "Setting up installation configuration";
39
+ /** Step for updating VS Code settings for the client/server. */
40
+ export declare const STEP_UPDATE_VSCODE_SETTINGS = "Updating VS Code settings for client/server";
41
+ /** Step for the overall installation process of a client or server. */
42
+ export declare const STEP_INSTALLATION = "Running overall installation process";
43
+ /** Step for marking the initiation of an onboarding or installation process. */
44
+ export declare const STEP_INITIATED = "Initiating onboarding or installation process";
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Step name constants for InstallOperationManager and step recording.
3
+ *
4
+ * This file defines all static step names and documents dynamic step name patterns
5
+ * used throughout the installation and onboarding process.
6
+ *
7
+ * Dynamic step names are documented as template string patterns.
8
+ */
9
+ /** Step for processing all requirement updates in a batch operation. */
10
+ export const STEP_PROCESS_REQUIREMENT_UPDATES = 'Processing all requirement updates';
11
+ /** Step for checking the status of a specific requirement. */
12
+ export const STEP_CHECKING_REQUIREMENT_STATUS = 'Checking the status of requirement';
13
+ /** Step for installing requirements in the background process. */
14
+ export const STEP_INSTALLING_REQUIREMENTS_IN_BACKGROUND = 'Installing requirements in the background';
15
+ /** Step for checking and installing all requirements as needed. */
16
+ export const STEP_CHECK_AND_INSTALL_REQUIREMENTS = 'Checking and installing all requirements';
17
+ /** Step for running the install logic in the CommandInstaller. */
18
+ export const STEP_COMMAND_INSTALLER_INSTALL = 'Running install in CommandInstaller';
19
+ /** Step for running the install logic in the GeneralInstaller. */
20
+ export const STEP_GENERAL_INSTALLER_INSTALL = 'Running install in GeneralInstaller';
21
+ /** Step for executing the actual installation command (npm, pip, etc.). */
22
+ export const STEP_INSTALLATION_COMMAND_EXECUTION = 'Executing installation command for requirement';
23
+ /** Step for running the install logic in the PipInstaller. */
24
+ export const STEP_PIP_INSTALLER_INSTALL = 'Running install in PipInstaller';
25
+ /** Step for processing requirement updates in the RequirementService. */
26
+ export const STEP_PROCESS_REQUIREMENT_UPDATES_SERVICE = 'Processing requirement updates in RequirementService';
27
+ /** Step for checking if the server is ready after installation. */
28
+ export const STEP_CHECK_SERVER_READINESS = 'Checking server readiness after installation';
29
+ /** Step for running the install logic in the NpmInstaller. */
30
+ export const STEP_NPM_INSTALLER_INSTALL = 'Running install in NpmInstaller';
31
+ /** Prefix for steps that update a specific requirement. */
32
+ export const STEP_INSTALL_REQUIREMENT_PREFIX = 'Updating requirement:';
33
+ /** Prefix for steps that execute an installation command for a requirement. */
34
+ export const STEP_INSTALL_COMMAND_PREFIX = 'Executing installation command for:';
35
+ /** Step for checking and installing the VS Code extension for the client. */
36
+ export const STEP_CHECK_VSCODE_AND_INSTALL_EXTENSION = 'Checking and installing VS Code extension for client';
37
+ /** Step for setting up the installation configuration (env, args, etc.). */
38
+ export const STEP_SETUP_INSTALLATION_CONFIG = 'Setting up installation configuration';
39
+ /** Step for updating VS Code settings for the client/server. */
40
+ export const STEP_UPDATE_VSCODE_SETTINGS = 'Updating VS Code settings for client/server';
41
+ /** Step for the overall installation process of a client or server. */
42
+ export const STEP_INSTALLATION = 'Running overall installation process';
43
+ /** Step for marking the initiation of an onboarding or installation process. */
44
+ export const STEP_INITIATED = 'Initiating onboarding or installation process';
45
+ //# sourceMappingURL=recordingConstants.js.map
@@ -165,3 +165,24 @@ export interface MCPEventData {
165
165
  configuration: MCPConfiguration;
166
166
  };
167
167
  }
168
+ export interface InstallOperationStep {
169
+ name: string;
170
+ status: 'pending' | 'in-progress' | 'completed' | 'failed' | 'canceled';
171
+ message?: string;
172
+ isCritical?: boolean;
173
+ timestamp: string;
174
+ }
175
+ export interface InstallOperationDetails {
176
+ currentStep: string;
177
+ steps: InstallOperationStep[];
178
+ lastUpdated: string;
179
+ error?: string;
180
+ overallStatus: 'pending' | 'in-progress' | 'completed' | 'failed';
181
+ }
182
+ export interface SystemSettings {
183
+ pythonEnvs?: Record<string, string>;
184
+ nodePath?: string;
185
+ browserPath?: string;
186
+ systemEnvironments?: Record<string, string>;
187
+ userConfigurations?: Record<string, string>;
188
+ }
@@ -13,16 +13,20 @@ export declare class FeedOnboardService {
13
13
  */
14
14
  private createOperationId;
15
15
  /**
16
- * Onboard a new feed configuration
16
+ * Onboard a new feed configuration. This method performs validation and initiates the onboarding process.
17
17
  * @param config Feed configuration to onboard
18
+ * @param forExistingCategory Whether this onboarding is for an existing category
19
+ * @returns Promise resolving to operation status with optional feed configuration
18
20
  */
19
21
  onboardFeed(config: FeedConfiguration, forExistingCategory?: boolean): Promise<OperationStatus & {
20
22
  feedConfiguration?: FeedConfiguration;
21
23
  }>;
22
24
  /**
23
- * Validate a feed configuration without performing full onboarding
25
+ * Validate a feed configuration without performing full onboarding.
26
+ * This method performs static validation and initiates the validation process.
24
27
  * @param config Feed configuration to validate
25
- * @returns Operation status indicating the result of the validation initiation
28
+ * @param forExistingCategory Whether this validation is for an existing category
29
+ * @returns Promise resolving to operation status with optional feed configuration
26
30
  */
27
31
  validateFeed(config: FeedConfiguration, forExistingCategory?: boolean): Promise<OperationStatus & {
28
32
  feedConfiguration?: FeedConfiguration;
@@ -1,7 +1,7 @@
1
1
  import { configProvider } from '../loaders/ConfigurationProvider.js';
2
2
  import { ServerSchemaProvider } from '../loaders/ServerSchemaProvider.js';
3
3
  import { feedValidator } from '../validators/FeedValidator.js';
4
- import { Logger } from '../../utils/logger.js';
4
+ import { Logger, EventType, EventStatus } from '../../utils/logger.js';
5
5
  import { OnboardingProcessStatus } from './OnboardStatus.js';
6
6
  import { onboardStatusManager } from './OnboardStatusManager.js';
7
7
  import { onboardProcessor } from './OnboardProcessor.js';
@@ -23,8 +23,10 @@ export class FeedOnboardService {
23
23
  return `${feedName}_${operationType}`;
24
24
  }
25
25
  /**
26
- * Onboard a new feed configuration
26
+ * Onboard a new feed configuration. This method performs validation and initiates the onboarding process.
27
27
  * @param config Feed configuration to onboard
28
+ * @param forExistingCategory Whether this onboarding is for an existing category
29
+ * @returns Promise resolving to operation status with optional feed configuration
28
30
  */
29
31
  async onboardFeed(config, forExistingCategory) {
30
32
  // Perform static validation first
@@ -40,10 +42,19 @@ export class FeedOnboardService {
40
42
  // For now, let's return a FAILED status for the attempted FULL_ONBOARDING initiation.
41
43
  // A more robust solution might involve a different return type or error code.
42
44
  const onboardingId = this.createOperationId(config.name, 'FULL_ONBOARDING'); // Hypothetical ID
45
+ const errorMessage = `No prior successful validation found for feed: ${config.name}. Please validate the configuration before publishing.`;
46
+ // Track failed event
47
+ Logger.trackEvent(EventType.FEED_ONBOARD, {
48
+ status: EventStatus.FAILED,
49
+ feedName: config.name,
50
+ errorMessage,
51
+ onboardingId: onboardingId,
52
+ feedConfiguration: config
53
+ });
43
54
  return {
44
55
  onboardingId: onboardingId,
45
56
  status: OnboardingProcessStatus.FAILED, // Or a new status like 'VALIDATION_REQUIRED'
46
- message: 'The feed configuration has not been validated or has changed. Please validate the configuration before publishing.',
57
+ message: errorMessage,
47
58
  lastQueried: new Date().toISOString(),
48
59
  feedConfiguration: config
49
60
  };
@@ -58,9 +69,11 @@ export class FeedOnboardService {
58
69
  };
59
70
  }
60
71
  /**
61
- * Validate a feed configuration without performing full onboarding
72
+ * Validate a feed configuration without performing full onboarding.
73
+ * This method performs static validation and initiates the validation process.
62
74
  * @param config Feed configuration to validate
63
- * @returns Operation status indicating the result of the validation initiation
75
+ * @param forExistingCategory Whether this validation is for an existing category
76
+ * @returns Promise resolving to operation status with optional feed configuration
64
77
  */
65
78
  async validateFeed(config, forExistingCategory) {
66
79
  // Perform static validation first
@@ -307,10 +320,28 @@ export class FeedOnboardService {
307
320
  validationStatus: result.validationStatus // Ensure validationStatus is also updated on success
308
321
  });
309
322
  Logger.log(`[${onboardingId}] Successfully validated feed: ${config.name}`);
323
+ // Track successful validation
324
+ Logger.trackEvent(EventType.FEED_VALIDATE, {
325
+ status: EventStatus.SUCCESS,
326
+ feedName: config.name,
327
+ operationType: 'VALIDATION_ONLY',
328
+ onboardingId: onboardingId,
329
+ feedConfiguration: config
330
+ });
310
331
  }
311
332
  catch (error) {
333
+ const errorMessage = error instanceof Error ? error.message : String(error);
312
334
  // Error is already logged and status updated by _validateFeedConfiguration or its callers
313
335
  Logger.error(`[${onboardingId}] Feed validation process failed for ${config.name} (already handled):`, error);
336
+ // Track validation failure
337
+ Logger.trackEvent(EventType.FEED_VALIDATE, {
338
+ status: EventStatus.FAILED,
339
+ feedName: config.name,
340
+ operationType: 'VALIDATION_ONLY',
341
+ errorMessage: errorMessage,
342
+ onboardingId: onboardingId,
343
+ feedConfiguration: config
344
+ });
314
345
  }
315
346
  }
316
347
  /**
@@ -359,6 +390,14 @@ export class FeedOnboardService {
359
390
  await configProvider.initialize(feedFilePath, { prLink: prInfo.url, adhocServers: serverList }); // configProvider is already an instance
360
391
  Logger.log(`[${onboardingId}] ConfigurationProvider re-initialized.`);
361
392
  Logger.log(`[${onboardingId}] Successfully completed full onboarding for feed: ${config.name}`);
393
+ // Track successful onboarding
394
+ Logger.trackEvent(EventType.FEED_ONBOARD, {
395
+ status: EventStatus.SUCCESS,
396
+ feedName: config.name,
397
+ onboardingId: onboardingId,
398
+ prUrl: prInfo.url,
399
+ feedConfiguration: config
400
+ });
362
401
  }
363
402
  catch (reinitError) {
364
403
  Logger.warn(`[${onboardingId}] Failed to re-initialize providers after PR creation for feed ${config.name}:`);
@@ -368,6 +407,14 @@ export class FeedOnboardService {
368
407
  catch (error) {
369
408
  Logger.error(`[${onboardingId}] Full feed onboarding process failed:`, error);
370
409
  const errorMessage = error instanceof Error ? error.message : String(error);
410
+ // Track onboarding failure
411
+ Logger.trackEvent(EventType.FEED_ONBOARD, {
412
+ status: EventStatus.FAILED,
413
+ feedName: config.name,
414
+ onboardingId: onboardingId,
415
+ errorMessage,
416
+ feedConfiguration: config
417
+ });
371
418
  // Check if status is already FAILED (e.g., by _validateFeedConfiguration)
372
419
  // to avoid overwriting a more specific error message or step from validation.
373
420
  const currentStatus = await onboardStatusManager.getStatus(config.name, operationType);
@@ -0,0 +1,23 @@
1
+ import { InstallOperationDetails } from '../metadatas/types.js';
2
+ export declare class InstallOperationManager {
3
+ private static instance;
4
+ private installOperationStatus;
5
+ private statusLock;
6
+ private constructor();
7
+ static getInstance(): InstallOperationManager;
8
+ private withLock;
9
+ private loadStatuses;
10
+ private saveStatuses;
11
+ private createOperationKey;
12
+ recordStep(categoryName: string, serverName: string, stepName: string, isSucceeded: boolean, message?: string): Promise<InstallOperationDetails>;
13
+ /**
14
+ * Resets (deletes) the operation status for a given category and server.
15
+ * This is useful to call before starting a new installation attempt.
16
+ * @param categoryName The name of the category.
17
+ * @param serverName The name of the server.
18
+ */
19
+ resetOperation(categoryName: string, serverName: string): Promise<void>;
20
+ getDetails(categoryName: string, serverName: string): Promise<InstallOperationDetails | undefined>;
21
+ getAllDetails(): Promise<Record<string, InstallOperationDetails>>;
22
+ }
23
+ export declare const installOperationManager: InstallOperationManager;