@wonderwhy-er/desktop-commander 0.2.5 → 0.2.7

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 (113) hide show
  1. package/dist/index-dxt.js +10 -47
  2. package/dist/server.js +6 -0
  3. package/dist/tools/filesystem.js +37 -4
  4. package/dist/utils/usageTracker.js +8 -5
  5. package/dist/version.d.ts +1 -1
  6. package/dist/version.js +1 -1
  7. package/package.json +2 -1
  8. package/dist/REPLSessionManager.d.ts +0 -109
  9. package/dist/REPLSessionManager.js +0 -364
  10. package/dist/REPLSessionManager.test.d.ts +0 -1
  11. package/dist/REPLSessionManager.test.js +0 -75
  12. package/dist/client/replClient.d.ts +0 -63
  13. package/dist/client/replClient.js +0 -217
  14. package/dist/client/sshClient.d.ts +0 -82
  15. package/dist/client/sshClient.js +0 -200
  16. package/dist/command-manager.js.map +0 -1
  17. package/dist/config-manager.js.map +0 -1
  18. package/dist/config.js.map +0 -1
  19. package/dist/custom-stdio.js.map +0 -1
  20. package/dist/error-handlers.js.map +0 -1
  21. package/dist/handlers/command-handlers.d.ts +0 -13
  22. package/dist/handlers/command-handlers.js +0 -43
  23. package/dist/handlers/edit-search-handlers.js.map +0 -1
  24. package/dist/handlers/filesystem-handlers.js.map +0 -1
  25. package/dist/handlers/fuzzy-search-log-handlers.d.ts +0 -13
  26. package/dist/handlers/fuzzy-search-log-handlers.js +0 -179
  27. package/dist/handlers/index.js.map +0 -1
  28. package/dist/handlers/process-handlers.js.map +0 -1
  29. package/dist/handlers/repl-handlers.d.ts +0 -21
  30. package/dist/handlers/repl-handlers.js +0 -37
  31. package/dist/handlers/replCommandHandler.d.ts +0 -125
  32. package/dist/handlers/replCommandHandler.js +0 -255
  33. package/dist/handlers/replCommandHandler.test.d.ts +0 -1
  34. package/dist/handlers/replCommandHandler.test.js +0 -103
  35. package/dist/handlers/terminal-handlers.js.map +0 -1
  36. package/dist/index-with-startup-detection.d.ts +0 -5
  37. package/dist/index-with-startup-detection.js +0 -180
  38. package/dist/index.js.map +0 -1
  39. package/dist/logging.d.ts +0 -2
  40. package/dist/logging.js +0 -28
  41. package/dist/polyform-license-src/edit/edit.d.ts +0 -15
  42. package/dist/polyform-license-src/edit/edit.js +0 -163
  43. package/dist/polyform-license-src/edit/fuzzySearch.d.ts +0 -30
  44. package/dist/polyform-license-src/edit/fuzzySearch.js +0 -121
  45. package/dist/polyform-license-src/edit/handlers.d.ts +0 -16
  46. package/dist/polyform-license-src/edit/handlers.js +0 -24
  47. package/dist/polyform-license-src/edit/index.d.ts +0 -12
  48. package/dist/polyform-license-src/edit/index.js +0 -13
  49. package/dist/polyform-license-src/edit/schemas.d.ts +0 -25
  50. package/dist/polyform-license-src/edit/schemas.js +0 -16
  51. package/dist/polyform-license-src/index.d.ts +0 -9
  52. package/dist/polyform-license-src/index.js +0 -10
  53. package/dist/repl-manager.d.ts +0 -73
  54. package/dist/repl-manager.js +0 -407
  55. package/dist/replIntegration.d.ts +0 -14
  56. package/dist/replIntegration.js +0 -27
  57. package/dist/sandbox/index.d.ts +0 -9
  58. package/dist/sandbox/index.js +0 -50
  59. package/dist/sandbox/mac-sandbox.d.ts +0 -19
  60. package/dist/sandbox/mac-sandbox.js +0 -174
  61. package/dist/server.js.map +0 -1
  62. package/dist/setup.log +0 -32
  63. package/dist/terminal-manager.js.map +0 -1
  64. package/dist/tools/client.d.ts +0 -10
  65. package/dist/tools/client.js +0 -13
  66. package/dist/tools/command-block.d.ts +0 -18
  67. package/dist/tools/command-block.js +0 -62
  68. package/dist/tools/config.js.map +0 -1
  69. package/dist/tools/debug-path.d.ts +0 -1
  70. package/dist/tools/debug-path.js +0 -44
  71. package/dist/tools/edit.js.map +0 -1
  72. package/dist/tools/enhanced-read-output.js +0 -69
  73. package/dist/tools/enhanced-send-input.js +0 -111
  74. package/dist/tools/environment.d.ts +0 -55
  75. package/dist/tools/environment.js +0 -65
  76. package/dist/tools/execute.d.ts +0 -10
  77. package/dist/tools/execute.js +0 -158
  78. package/dist/tools/execute.js.map +0 -1
  79. package/dist/tools/filesystem-fixed.d.ts +0 -22
  80. package/dist/tools/filesystem-fixed.js +0 -176
  81. package/dist/tools/filesystem.js.map +0 -1
  82. package/dist/tools/fuzzySearch.js.map +0 -1
  83. package/dist/tools/mime-types.js.map +0 -1
  84. package/dist/tools/pdf-reader.d.ts +0 -13
  85. package/dist/tools/pdf-reader.js +0 -214
  86. package/dist/tools/process.js.map +0 -1
  87. package/dist/tools/progress.d.ts +0 -20
  88. package/dist/tools/progress.js +0 -59
  89. package/dist/tools/repl.d.ts +0 -21
  90. package/dist/tools/repl.js +0 -217
  91. package/dist/tools/schemas.js.map +0 -1
  92. package/dist/tools/search.js.map +0 -1
  93. package/dist/tools/send-input.d.ts +0 -2
  94. package/dist/tools/send-input.js +0 -45
  95. package/dist/types.js.map +0 -1
  96. package/dist/utils/capture.js.map +0 -1
  97. package/dist/utils/early-logger.d.ts +0 -4
  98. package/dist/utils/early-logger.js +0 -35
  99. package/dist/utils/fuzzySearchLogger.js.map +0 -1
  100. package/dist/utils/lineEndingHandler.js.map +0 -1
  101. package/dist/utils/lineEndingHandler_optimized.d.ts +0 -21
  102. package/dist/utils/lineEndingHandler_optimized.js +0 -77
  103. package/dist/utils/mcp-logger.d.ts +0 -30
  104. package/dist/utils/mcp-logger.js +0 -59
  105. package/dist/utils/smithery-detector.d.ts +0 -94
  106. package/dist/utils/smithery-detector.js +0 -292
  107. package/dist/utils/startup-detector.d.ts +0 -65
  108. package/dist/utils/startup-detector.js +0 -390
  109. package/dist/utils/trackTools.js.map +0 -1
  110. package/dist/utils/withTimeout.js.map +0 -1
  111. package/dist/utils.d.ts +0 -26
  112. package/dist/utils.js +0 -227
  113. package/dist/version.js.map +0 -1
@@ -1,390 +0,0 @@
1
- /**
2
- * Production-Ready Startup Detection Module
3
- *
4
- * This module provides a lightweight, production-ready way to detect
5
- * how a Node.js application was started. Perfect for logging, analytics,
6
- * or conditional behavior based on startup method.
7
- */
8
- import { readFileSync } from 'fs';
9
- import { platform } from 'os';
10
- export class StartupDetector {
11
- constructor() {
12
- this._startupInfo = null;
13
- }
14
- static getInstance() {
15
- if (!StartupDetector.instance) {
16
- StartupDetector.instance = new StartupDetector();
17
- }
18
- return StartupDetector.instance;
19
- }
20
- /**
21
- * Get startup information (cached after first call)
22
- */
23
- getStartupInfo() {
24
- if (!this._startupInfo) {
25
- this._startupInfo = this.detectStartupMethod();
26
- }
27
- return this._startupInfo;
28
- }
29
- /**
30
- * Force re-detection (useful for testing)
31
- */
32
- forceRedetect() {
33
- this._startupInfo = this.detectStartupMethod();
34
- return this._startupInfo;
35
- }
36
- detectStartupMethod() {
37
- const detectors = [
38
- this.detectSmithery.bind(this),
39
- this.detectNpmRun.bind(this),
40
- this.detectNpx.bind(this),
41
- this.detectDocker.bind(this),
42
- this.detectCiCd.bind(this),
43
- this.detectDirectNode.bind(this)
44
- ];
45
- const results = detectors.map(detector => detector()).filter(result => result !== null);
46
- // Sort by confidence, highest first
47
- results.sort((a, b) => b.confidence - a.confidence);
48
- if (results.length === 0) {
49
- return {
50
- method: 'unknown',
51
- confidence: 0,
52
- details: { evidence: ['No detection method succeeded'] },
53
- environment: 'unknown'
54
- };
55
- }
56
- const topResult = results[0];
57
- topResult.environment = this.detectEnvironment(topResult);
58
- return topResult;
59
- }
60
- detectNpmRun() {
61
- const evidence = [];
62
- let confidence = 0;
63
- // Primary indicator - npm_lifecycle_event is only set during npm run
64
- if (process.env.npm_lifecycle_event) {
65
- confidence += 50;
66
- evidence.push(`npm script: ${process.env.npm_lifecycle_event}`);
67
- // Additional confidence for npm script context
68
- if (process.env.npm_lifecycle_script) {
69
- confidence += 20;
70
- }
71
- return {
72
- method: 'npm-run',
73
- confidence,
74
- details: {
75
- npmScript: process.env.npm_lifecycle_event,
76
- evidence
77
- },
78
- environment: 'unknown' // Will be set later
79
- };
80
- }
81
- return null;
82
- }
83
- detectNpx() {
84
- const evidence = [];
85
- let confidence = 0;
86
- // Check user agent for npx
87
- const userAgent = process.env.npm_config_user_agent;
88
- if (userAgent?.includes('npx')) {
89
- confidence += 40;
90
- evidence.push(`User agent indicates npx: ${userAgent}`);
91
- }
92
- // NPX specific environment variables
93
- if (process.env.NPM_CLI_JS?.includes('npx')) {
94
- confidence += 30;
95
- evidence.push('NPM_CLI_JS indicates npx execution');
96
- }
97
- if (confidence > 0) {
98
- return {
99
- method: 'npx',
100
- confidence,
101
- details: { evidence },
102
- environment: 'unknown'
103
- };
104
- }
105
- return null;
106
- }
107
- detectDocker() {
108
- const evidence = [];
109
- let confidence = 0;
110
- // Most reliable: Check for .dockerenv file
111
- try {
112
- readFileSync('/.dockerenv');
113
- confidence += 70;
114
- evidence.push('/.dockerenv file exists');
115
- }
116
- catch {
117
- // Not in Docker
118
- }
119
- // Check container environment variable
120
- if (process.env.container === 'docker' || process.env.container === 'podman') {
121
- confidence += 50;
122
- evidence.push(`Container type: ${process.env.container}`);
123
- }
124
- // Check for Docker-like hostname pattern
125
- const hostname = process.env.HOSTNAME;
126
- if (hostname && hostname.length === 12 && /^[a-f0-9]{12}$/.test(hostname)) {
127
- confidence += 25;
128
- evidence.push('Docker-style hostname detected');
129
- }
130
- // Linux-specific: Check cgroup
131
- if (platform() === 'linux') {
132
- try {
133
- const cgroup = readFileSync('/proc/1/cgroup', 'utf8');
134
- if (cgroup.includes('docker') || cgroup.includes('containerd')) {
135
- confidence += 60;
136
- evidence.push('Docker detected in cgroup');
137
- }
138
- }
139
- catch {
140
- // Ignore errors
141
- }
142
- }
143
- if (confidence > 0) {
144
- return {
145
- method: 'docker',
146
- confidence,
147
- details: {
148
- dockerContainer: true,
149
- evidence
150
- },
151
- environment: 'unknown'
152
- };
153
- }
154
- return null;
155
- }
156
- detectCiCd() {
157
- const evidence = [];
158
- let confidence = 0;
159
- let ciPlatform;
160
- const ciDetectors = {
161
- 'GitHub Actions': () => process.env.GITHUB_ACTIONS === 'true',
162
- 'GitLab CI': () => process.env.GITLAB_CI === 'true',
163
- 'Jenkins': () => !!process.env.JENKINS_URL,
164
- 'CircleCI': () => process.env.CIRCLECI === 'true',
165
- 'Travis CI': () => process.env.TRAVIS === 'true',
166
- 'Azure DevOps': () => process.env.TF_BUILD === 'True',
167
- 'Bamboo': () => !!process.env.bamboo_buildKey,
168
- 'TeamCity': () => !!process.env.TEAMCITY_VERSION
169
- };
170
- for (const [platform, detector] of Object.entries(ciDetectors)) {
171
- if (detector()) {
172
- ciPlatform = platform;
173
- confidence += 60;
174
- evidence.push(`${platform} environment detected`);
175
- break;
176
- }
177
- }
178
- // Generic CI detection
179
- if (!ciPlatform && (process.env.CI === 'true' || process.env.CI === '1')) {
180
- confidence += 40;
181
- evidence.push('Generic CI environment');
182
- ciPlatform = 'Generic CI';
183
- }
184
- if (confidence > 0) {
185
- return {
186
- method: 'ci-cd',
187
- confidence,
188
- details: {
189
- ciPlatform,
190
- evidence
191
- },
192
- environment: 'unknown'
193
- };
194
- }
195
- return null;
196
- }
197
- detectDirectNode() {
198
- const evidence = [];
199
- let confidence = 0;
200
- // If no npm/npx indicators are present, likely direct node
201
- if (!process.env.npm_lifecycle_event &&
202
- !process.env.npm_config_user_agent &&
203
- !process.env.npm_execpath) {
204
- confidence += 30;
205
- evidence.push('No package manager environment variables');
206
- }
207
- // This is more of a fallback, so lower confidence
208
- if (confidence > 0) {
209
- return {
210
- method: 'node-direct',
211
- confidence,
212
- details: { evidence },
213
- environment: 'unknown'
214
- };
215
- }
216
- return null;
217
- }
218
- detectSmithery() {
219
- const evidence = [];
220
- let confidence = 0;
221
- let smitheryClient;
222
- let smitheryConnection;
223
- let smitherySession;
224
- // Check for Smithery-specific environment variables
225
- const smitheryEnvVars = [
226
- 'SMITHERY_SESSION_ID',
227
- 'SMITHERY_CLIENT',
228
- 'SMITHERY_PROFILE',
229
- 'SMITHERY_ANALYTICS',
230
- 'SMITHERY_CONNECTION_TYPE',
231
- 'SMITHERY_QUALIFIED_NAME'
232
- ];
233
- for (const envVar of smitheryEnvVars) {
234
- if (process.env[envVar]) {
235
- confidence += 40;
236
- evidence.push(`Smithery environment variable: ${envVar}`);
237
- // Extract specific details
238
- switch (envVar) {
239
- case 'SMITHERY_SESSION_ID':
240
- smitherySession = process.env[envVar];
241
- break;
242
- case 'SMITHERY_CLIENT':
243
- smitheryClient = process.env[envVar];
244
- break;
245
- case 'SMITHERY_CONNECTION_TYPE':
246
- smitheryConnection = process.env[envVar];
247
- break;
248
- }
249
- }
250
- }
251
- // Check for Smithery endpoints
252
- if (process.env.REGISTRY_ENDPOINT?.includes('smithery')) {
253
- confidence += 30;
254
- evidence.push('Smithery registry endpoint detected');
255
- }
256
- if (process.env.ANALYTICS_ENDPOINT?.includes('smithery')) {
257
- confidence += 25;
258
- evidence.push('Smithery analytics endpoint detected');
259
- }
260
- // Check process arguments for Smithery patterns
261
- const args = process.argv.join(' ');
262
- const smitheryPatterns = [
263
- /smithery[\s\/\\]cli/i,
264
- /@smithery[\s\/\\]cli/i,
265
- /npx.*@smithery/i,
266
- /smithery.*run/i
267
- ];
268
- for (const pattern of smitheryPatterns) {
269
- if (pattern.test(args)) {
270
- confidence += 35;
271
- evidence.push('Smithery CLI pattern in arguments');
272
- break;
273
- }
274
- }
275
- // Check for UUID v7 session pattern (Smithery uses uuidv7)
276
- const envVars = Object.keys(process.env);
277
- for (const key of envVars) {
278
- const value = process.env[key] || '';
279
- if (/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {
280
- confidence += 25;
281
- evidence.push('UUID v7 session ID pattern detected');
282
- if (!smitherySession)
283
- smitherySession = value;
284
- break;
285
- }
286
- }
287
- if (confidence > 0) {
288
- return {
289
- method: 'smithery',
290
- confidence,
291
- details: {
292
- smitheryClient,
293
- smitheryConnection,
294
- smitherySession,
295
- evidence
296
- },
297
- environment: 'unknown'
298
- };
299
- }
300
- return null;
301
- }
302
- detectEnvironment(startupInfo) {
303
- // Smithery is always considered smithery environment
304
- if (startupInfo.method === 'smithery') {
305
- return 'smithery';
306
- }
307
- // Docker containers are usually production or CI
308
- if (startupInfo.method === 'docker') {
309
- // Check if it's also CI
310
- if (process.env.CI === 'true' || process.env.CI === '1') {
311
- return 'ci';
312
- }
313
- return 'container';
314
- }
315
- // Check NODE_ENV
316
- const nodeEnv = process.env.NODE_ENV?.toLowerCase();
317
- if (nodeEnv === 'production')
318
- return 'production';
319
- if (nodeEnv === 'development')
320
- return 'development';
321
- // NPM scripts often indicate development
322
- if (startupInfo.method === 'npm-run') {
323
- const script = startupInfo.details.npmScript;
324
- if (script?.includes('dev') || script?.includes('start')) {
325
- return 'development';
326
- }
327
- if (script?.includes('prod') || script?.includes('build')) {
328
- return 'production';
329
- }
330
- return 'development'; // Default for npm scripts
331
- }
332
- // NPX is often used for one-off tools in development
333
- if (startupInfo.method === 'npx') {
334
- return 'development';
335
- }
336
- return 'unknown';
337
- }
338
- /**
339
- * Get a simple string representation of how the app was started
340
- */
341
- getStartupMethodString() {
342
- const info = this.getStartupInfo();
343
- switch (info.method) {
344
- case 'npm-run':
345
- return `npm run ${info.details.npmScript || 'script'}`;
346
- case 'npx':
347
- return 'npx';
348
- case 'docker':
349
- return 'Docker container';
350
- case 'ci-cd':
351
- return info.details.ciPlatform || 'CI/CD';
352
- case 'smithery':
353
- return `Smithery CLI${info.details.smitheryClient ? ` (${info.details.smitheryClient})` : ''}`;
354
- case 'node-direct':
355
- return 'node (direct)';
356
- default:
357
- return 'unknown';
358
- }
359
- }
360
- /**
361
- * Check if running in a specific environment
362
- */
363
- isEnvironment(env) {
364
- return this.getStartupInfo().environment === env;
365
- }
366
- /**
367
- * Check if running via a specific method
368
- */
369
- isMethod(method) {
370
- return this.getStartupInfo().method === method;
371
- }
372
- }
373
- // Singleton instance
374
- export const startupDetector = StartupDetector.getInstance();
375
- // Convenience functions
376
- export const getStartupInfo = () => startupDetector.getStartupInfo();
377
- export const getStartupMethod = () => startupDetector.getStartupMethodString();
378
- export const isProduction = () => startupDetector.isEnvironment('production');
379
- export const isDevelopment = () => startupDetector.isEnvironment('development');
380
- export const isDocker = () => startupDetector.isMethod('docker');
381
- export const isCi = () => startupDetector.isEnvironment('ci');
382
- export const isSmithery = () => startupDetector.isMethod('smithery');
383
- export const getSmitheryClient = () => {
384
- const info = startupDetector.getStartupInfo();
385
- return info.method === 'smithery' ? info.details.smitheryClient : undefined;
386
- };
387
- export const getSmitheryConnection = () => {
388
- const info = startupDetector.getStartupInfo();
389
- return info.method === 'smithery' ? info.details.smitheryConnection : undefined;
390
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"trackTools.js","sourceRoot":"","sources":["../../src/utils/trackTools.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"withTimeout.js","sourceRoot":"","sources":["../../src/utils/withTimeout.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACvB,SAAqB,EACrB,SAAiB,EACjB,aAAqB,EACrB,YAAe;IAEf,kFAAkF;IAClF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,iBAAiB;QACjB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,WAAW,GAAG,IAAI,CAAC;gBACnB,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;oBACxB,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACJ,wDAAwD;oBACxD,sDAAsD;oBACtD,MAAM,CAAC,cAAc,aAAa,oBAAoB,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC;gBACtF,CAAC;YACL,CAAC;QACL,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,wBAAwB;QACxB,SAAS;aACJ,IAAI,CAAC,MAAM,CAAC,EAAE;YACX,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,WAAW,GAAG,IAAI,CAAC;gBACnB,YAAY,CAAC,SAAS,CAAC,CAAC;gBACxB,OAAO,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC;QACL,CAAC,CAAC;aACD,KAAK,CAAC,KAAK,CAAC,EAAE;YACX,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,WAAW,GAAG,IAAI,CAAC;gBACnB,YAAY,CAAC,SAAS,CAAC,CAAC;gBACxB,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;oBACxB,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACJ,oFAAoF;oBACpF,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClB,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACP,CAAC"}
package/dist/utils.d.ts DELETED
@@ -1,26 +0,0 @@
1
- /**
2
- * Sanitizes error objects to remove potentially sensitive information like file paths
3
- * @param error Error object or string to sanitize
4
- * @returns An object with sanitized message and optional error code
5
- */
6
- export declare function sanitizeError(error: any): {
7
- message: string;
8
- code?: string;
9
- };
10
- /**
11
- * Send an event to Google Analytics
12
- * @param event Event name
13
- * @param properties Optional event properties
14
- */
15
- export declare const capture: (event: string, properties?: any) => Promise<void>;
16
- /**
17
- * Executes a promise with a timeout. If the promise doesn't resolve or reject within
18
- * the specified timeout, returns the provided default value.
19
- *
20
- * @param operation The promise to execute
21
- * @param timeoutMs Timeout in milliseconds
22
- * @param operationName Name of the operation (for logs)
23
- * @param defaultValue Value to return if the operation times out
24
- * @returns Promise that resolves with the operation result or the default value on timeout
25
- */
26
- export declare function withTimeout<T>(operation: Promise<T>, timeoutMs: number, operationName: string, defaultValue: T): Promise<T>;
package/dist/utils.js DELETED
@@ -1,227 +0,0 @@
1
- import { platform } from 'os';
2
- import { randomUUID } from 'crypto';
3
- import * as https from 'https';
4
- import { configManager } from './config-manager.js';
5
- let VERSION = 'unknown';
6
- try {
7
- const versionModule = await import('./version.js');
8
- VERSION = versionModule.VERSION;
9
- }
10
- catch {
11
- // Continue without version info if not available
12
- }
13
- // Configuration
14
- const GA_MEASUREMENT_ID = 'G-NGGDNL0K4L'; // Replace with your GA4 Measurement ID
15
- const GA_API_SECRET = '5M0mC--2S_6t94m8WrI60A'; // Replace with your GA4 API Secret
16
- const GA_BASE_URL = `https://www.google-analytics.com/mp/collect?measurement_id=${GA_MEASUREMENT_ID}&api_secret=${GA_API_SECRET}`;
17
- const GA_DEBUG_BASE_URL = `https://www.google-analytics.com/debug/mp/collect?measurement_id=${GA_MEASUREMENT_ID}&api_secret=${GA_API_SECRET}`;
18
- // Will be initialized when needed
19
- let uniqueUserId = 'unknown';
20
- // Function to get or create a persistent UUID
21
- async function getOrCreateUUID() {
22
- try {
23
- // Try to get the UUID from the config
24
- let clientId = await configManager.getValue('clientId');
25
- // If it doesn't exist, create a new one and save it
26
- if (!clientId) {
27
- clientId = randomUUID();
28
- await configManager.setValue('clientId', clientId);
29
- }
30
- return clientId;
31
- }
32
- catch (error) {
33
- // Fallback to a random UUID if config operations fail
34
- return randomUUID();
35
- }
36
- }
37
- /**
38
- * Sanitizes error objects to remove potentially sensitive information like file paths
39
- * @param error Error object or string to sanitize
40
- * @returns An object with sanitized message and optional error code
41
- */
42
- export function sanitizeError(error) {
43
- let errorMessage = '';
44
- let errorCode = undefined;
45
- if (error instanceof Error) {
46
- // Extract just the error name and message without stack trace
47
- errorMessage = error.name + ': ' + error.message;
48
- // Extract error code if available (common in Node.js errors)
49
- if ('code' in error) {
50
- errorCode = error.code;
51
- }
52
- }
53
- else if (typeof error === 'string') {
54
- errorMessage = error;
55
- }
56
- else {
57
- errorMessage = 'Unknown error';
58
- }
59
- // Remove any file paths using regex
60
- // This pattern matches common path formats including Windows and Unix-style paths
61
- errorMessage = errorMessage.replace(/(?:\/|\\)[\w\d_.-\/\\]+/g, '[PATH]');
62
- errorMessage = errorMessage.replace(/[A-Za-z]:\\[\w\d_.-\/\\]+/g, '[PATH]');
63
- return {
64
- message: errorMessage,
65
- code: errorCode
66
- };
67
- }
68
- /**
69
- * Send an event to Google Analytics
70
- * @param event Event name
71
- * @param properties Optional event properties
72
- */
73
- export const capture = async (event, properties) => {
74
- try {
75
- // Check if telemetry is enabled in config (defaults to true if not set)
76
- const telemetryEnabled = await configManager.getValue('telemetryEnabled');
77
- // If telemetry is explicitly disabled or GA credentials are missing, don't send
78
- if (telemetryEnabled === false || !GA_MEASUREMENT_ID || !GA_API_SECRET) {
79
- return;
80
- }
81
- // Get or create the client ID if not already initialized
82
- if (uniqueUserId === 'unknown') {
83
- uniqueUserId = await getOrCreateUUID();
84
- }
85
- // Create a deep copy of properties to avoid modifying the original objects
86
- // This ensures we don't alter error objects that are also returned to the AI
87
- let sanitizedProperties;
88
- try {
89
- sanitizedProperties = properties ? JSON.parse(JSON.stringify(properties)) : {};
90
- }
91
- catch (e) {
92
- sanitizedProperties = {};
93
- }
94
- // Sanitize error objects if present
95
- if (sanitizedProperties.error) {
96
- // Handle different types of error objects
97
- if (typeof sanitizedProperties.error === 'object' && sanitizedProperties.error !== null) {
98
- const sanitized = sanitizeError(sanitizedProperties.error);
99
- sanitizedProperties.error = sanitized.message;
100
- if (sanitized.code) {
101
- sanitizedProperties.errorCode = sanitized.code;
102
- }
103
- }
104
- else if (typeof sanitizedProperties.error === 'string') {
105
- sanitizedProperties.error = sanitizeError(sanitizedProperties.error).message;
106
- }
107
- }
108
- // Remove any properties that might contain paths
109
- const sensitiveKeys = ['path', 'filePath', 'directory', 'file_path', 'sourcePath', 'destinationPath', 'fullPath', 'rootPath'];
110
- for (const key of Object.keys(sanitizedProperties)) {
111
- const lowerKey = key.toLowerCase();
112
- if (sensitiveKeys.some(sensitiveKey => lowerKey.includes(sensitiveKey)) &&
113
- lowerKey !== 'fileextension') { // keep fileExtension as it's safe
114
- delete sanitizedProperties[key];
115
- }
116
- }
117
- // Prepare standard properties
118
- const baseProperties = {
119
- timestamp: new Date().toISOString(),
120
- platform: platform(),
121
- app_version: VERSION,
122
- engagement_time_msec: "100"
123
- };
124
- // Combine with sanitized properties
125
- const eventProperties = {
126
- ...baseProperties,
127
- ...sanitizedProperties
128
- };
129
- // Prepare GA4 payload
130
- const payload = {
131
- client_id: uniqueUserId,
132
- non_personalized_ads: false,
133
- timestamp_micros: Date.now() * 1000,
134
- events: [{
135
- name: event,
136
- params: eventProperties
137
- }]
138
- };
139
- // Send data to Google Analytics
140
- const postData = JSON.stringify(payload);
141
- const options = {
142
- method: 'POST',
143
- headers: {
144
- 'Content-Type': 'application/json',
145
- 'Content-Length': Buffer.byteLength(postData)
146
- }
147
- };
148
- const req = https.request(GA_BASE_URL, options, (res) => {
149
- // Response handling (optional)
150
- let data = '';
151
- res.on('data', (chunk) => {
152
- data += chunk;
153
- });
154
- res.on('end', () => {
155
- if (res.statusCode !== 200 && res.statusCode !== 204) {
156
- // Optional debug logging
157
- // console.debug(`GA tracking error: ${res.statusCode} ${data}`);
158
- }
159
- });
160
- });
161
- req.on('error', () => {
162
- // Silently fail - we don't want analytics issues to break functionality
163
- });
164
- // Set timeout to prevent blocking the app
165
- req.setTimeout(3000, () => {
166
- req.destroy();
167
- });
168
- // Send data
169
- req.write(postData);
170
- req.end();
171
- }
172
- catch {
173
- // Silently fail - we don't want analytics issues to break functionality
174
- }
175
- };
176
- /**
177
- * Executes a promise with a timeout. If the promise doesn't resolve or reject within
178
- * the specified timeout, returns the provided default value.
179
- *
180
- * @param operation The promise to execute
181
- * @param timeoutMs Timeout in milliseconds
182
- * @param operationName Name of the operation (for logs)
183
- * @param defaultValue Value to return if the operation times out
184
- * @returns Promise that resolves with the operation result or the default value on timeout
185
- */
186
- export function withTimeout(operation, timeoutMs, operationName, defaultValue) {
187
- // Don't sanitize operation name for logs - only telemetry will sanitize if needed
188
- return new Promise((resolve, reject) => {
189
- let isCompleted = false;
190
- // Set up timeout
191
- const timeoutId = setTimeout(() => {
192
- if (!isCompleted) {
193
- isCompleted = true;
194
- if (defaultValue !== null) {
195
- resolve(defaultValue);
196
- }
197
- else {
198
- // Keep the original operation name in the error message
199
- // Telemetry sanitization happens at the capture level
200
- reject(`__ERROR__: ${operationName} timed out after ${timeoutMs / 1000} seconds`);
201
- }
202
- }
203
- }, timeoutMs);
204
- // Execute the operation
205
- operation
206
- .then(result => {
207
- if (!isCompleted) {
208
- isCompleted = true;
209
- clearTimeout(timeoutId);
210
- resolve(result);
211
- }
212
- })
213
- .catch(error => {
214
- if (!isCompleted) {
215
- isCompleted = true;
216
- clearTimeout(timeoutId);
217
- if (defaultValue !== null) {
218
- resolve(defaultValue);
219
- }
220
- else {
221
- // Pass the original error unchanged - sanitization for telemetry happens in capture
222
- reject(error);
223
- }
224
- }
225
- });
226
- });
227
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}