golf-mcp 0.1.9__py3-none-any.whl → 0.1.11__py3-none-any.whl

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.

Potentially problematic release.


This version of golf-mcp might be problematic. Click here for more details.

golf/core/telemetry.py CHANGED
@@ -243,7 +243,7 @@ def track_event(event_name: str, properties: Optional[Dict[str, Any]] = None) ->
243
243
  # Filter properties to only include safe ones
244
244
  if properties:
245
245
  # Only include specific safe properties
246
- safe_keys = {"success", "environment", "template", "command_type"}
246
+ safe_keys = {"success", "environment", "template", "command_type", "error_type", "error_message"}
247
247
  for key in safe_keys:
248
248
  if key in properties:
249
249
  safe_properties[key] = properties[key]
@@ -260,15 +260,68 @@ def track_event(event_name: str, properties: Optional[Dict[str, Any]] = None) ->
260
260
  pass
261
261
 
262
262
 
263
- def track_command(command: str, success: bool = True) -> None:
263
+ def track_command(command: str, success: bool = True, error_type: Optional[str] = None, error_message: Optional[str] = None) -> None:
264
264
  """Track a CLI command execution with minimal info.
265
265
 
266
266
  Args:
267
267
  command: The command being executed (e.g., "init", "build", "run")
268
268
  success: Whether the command was successful
269
+ error_type: Type of error if command failed (e.g., "ValueError", "FileNotFoundError")
270
+ error_message: Sanitized error message (no sensitive data)
269
271
  """
270
- # Simplify the event to just command and success
271
- track_event(f"cli_{command}", {"success": success})
272
+ properties = {"success": success}
273
+
274
+ # Add error details if command failed
275
+ if not success and (error_type or error_message):
276
+ if error_type:
277
+ properties["error_type"] = error_type
278
+ if error_message:
279
+ # Sanitize error message - remove file paths and sensitive info
280
+ sanitized_message = _sanitize_error_message(error_message)
281
+ properties["error_message"] = sanitized_message
282
+
283
+ track_event(f"cli_{command}", properties)
284
+
285
+
286
+ def _sanitize_error_message(message: str) -> str:
287
+ """Sanitize error message to remove sensitive information.
288
+
289
+ Args:
290
+ message: Raw error message
291
+
292
+ Returns:
293
+ Sanitized error message
294
+ """
295
+ import re
296
+
297
+ # Remove absolute file paths but keep the filename
298
+ # Unix-style paths
299
+ message = re.sub(r'/(?:Users|home|var|tmp|opt|usr|etc)/[^\s"\']+/([^/\s"\']+)', r'\1', message)
300
+ # Windows-style paths
301
+ message = re.sub(r'[A-Za-z]:\\[^\s"\']+\\([^\\s"\']+)', r'\1', message)
302
+ # Generic path pattern (catches remaining paths)
303
+ message = re.sub(r'(?:^|[\s"])(/[^\s"\']+/)+([^/\s"\']+)', r'\2', message)
304
+
305
+ # Remove potential API keys or tokens (common patterns)
306
+ # Generic API keys (20+ alphanumeric with underscores/hyphens)
307
+ message = re.sub(r'\b[a-zA-Z0-9_-]{32,}\b', '[REDACTED]', message)
308
+ # Bearer tokens
309
+ message = re.sub(r'Bearer\s+[a-zA-Z0-9_.-]+', 'Bearer [REDACTED]', message)
310
+
311
+ # Remove email addresses
312
+ message = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', '[EMAIL]', message)
313
+
314
+ # Remove IP addresses
315
+ message = re.sub(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b', '[IP]', message)
316
+
317
+ # Remove port numbers in URLs
318
+ message = re.sub(r':[0-9]{2,5}(?=/|$|\s)', ':[PORT]', message)
319
+
320
+ # Truncate to reasonable length
321
+ if len(message) > 200:
322
+ message = message[:197] + "..."
323
+
324
+ return message
272
325
 
273
326
 
274
327
  def flush() -> None: