no-cluely-detector 0.0.1__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.
@@ -0,0 +1,412 @@
1
+ """
2
+ No-Cluely Detector - Python Library
3
+
4
+ Detect Cluely employee monitoring software and its evasion techniques.
5
+ This library provides Python bindings to a fast Rust-based detection engine.
6
+
7
+ Basic Usage:
8
+ >>> from no_cluely_detector import ClueLyDetector
9
+ >>> if ClueLyDetector.is_cluely_running():
10
+ ... print("⚠️ Employee monitoring detected!")
11
+
12
+ Advanced Usage:
13
+ >>> detection = ClueLyDetector.detect_cluely_detailed()
14
+ >>> print(f"Severity: {detection.severity_level}")
15
+ >>> print(f"Techniques: {', '.join(detection.evasion_techniques)}")
16
+ """
17
+
18
+ import ctypes
19
+ import platform
20
+ import os
21
+ from pathlib import Path
22
+ from typing import List, Optional, NamedTuple, Union
23
+ from dataclasses import dataclass
24
+ from datetime import datetime
25
+ import threading
26
+ import time
27
+
28
+ # Ensure we're on macOS
29
+ if platform.system() != "Darwin":
30
+ raise RuntimeError("Cluely Detector is only supported on macOS")
31
+
32
+
33
+ # Locate the dynamic library
34
+ def _find_library() -> str:
35
+ """Find the Rust dynamic library."""
36
+ # Try relative to this package first
37
+ current_dir = Path(__file__).parent
38
+ lib_paths = [
39
+ current_dir
40
+ / ".."
41
+ / ".."
42
+ / ".."
43
+ / "target"
44
+ / "release"
45
+ / "libno_cluely_driver.dylib",
46
+ current_dir / ".." / ".." / "target" / "release" / "libno_cluely_driver.dylib",
47
+ current_dir / "libno_cluely_driver.dylib",
48
+ Path("/usr/local/lib/libno_cluely_driver.dylib"),
49
+ Path("/opt/homebrew/lib/libno_cluely_driver.dylib"),
50
+ ]
51
+
52
+ for lib_path in lib_paths:
53
+ lib_path = lib_path.resolve()
54
+ if lib_path.exists():
55
+ return str(lib_path)
56
+
57
+ raise FileNotFoundError(
58
+ "Could not find libno_cluely_driver.dylib. "
59
+ "Please ensure the Rust library is built: cargo build --lib --release"
60
+ )
61
+
62
+
63
+ # Load the library
64
+ _lib_path = _find_library()
65
+ _lib = ctypes.CDLL(_lib_path)
66
+
67
+
68
+ # Define C structures
69
+ class _ClueLyDetectionResult(ctypes.Structure):
70
+ """C structure for detection results."""
71
+
72
+ _fields_ = [
73
+ ("is_detected", ctypes.c_bool),
74
+ ("window_count", ctypes.c_uint32),
75
+ ("screen_capture_evasion_count", ctypes.c_uint32),
76
+ ("elevated_layer_count", ctypes.c_uint32),
77
+ ("max_layer_detected", ctypes.c_int32),
78
+ ]
79
+
80
+
81
+ # Define function signatures
82
+ _lib.is_cluely_running.argtypes = []
83
+ _lib.is_cluely_running.restype = ctypes.c_int
84
+
85
+ _lib.detect_cluely.argtypes = []
86
+ _lib.detect_cluely.restype = _ClueLyDetectionResult
87
+
88
+ _lib.get_cluely_report.argtypes = []
89
+ _lib.get_cluely_report.restype = ctypes.c_char_p
90
+
91
+ _lib.free_cluely_report.argtypes = [ctypes.c_char_p]
92
+ _lib.free_cluely_report.restype = None
93
+
94
+ _lib.get_cluely_window_count.argtypes = []
95
+ _lib.get_cluely_window_count.restype = ctypes.c_uint32
96
+
97
+
98
+ @dataclass(frozen=True)
99
+ class ClueLyDetection:
100
+ """
101
+ Detailed information about Cluely detection.
102
+
103
+ Attributes:
104
+ is_detected: True if Cluely monitoring software is detected
105
+ window_count: Total number of Cluely windows found
106
+ screen_capture_evasion_count: Number of windows using screen capture evasion
107
+ elevated_layer_count: Number of windows using elevated layer positioning
108
+ max_layer_detected: Highest layer number detected
109
+ severity_level: Human-readable severity level ('None', 'Low', 'Medium', 'High')
110
+ evasion_techniques: List of detected evasion techniques
111
+ report: Detailed text report
112
+ timestamp: Detection timestamp
113
+ """
114
+
115
+ is_detected: bool
116
+ window_count: int
117
+ screen_capture_evasion_count: int
118
+ elevated_layer_count: int
119
+ max_layer_detected: int
120
+ severity_level: str
121
+ evasion_techniques: List[str]
122
+ report: str
123
+ timestamp: datetime
124
+
125
+
126
+ class ClueLyDetector:
127
+ """
128
+ Cluely Detection Library
129
+
130
+ Detects Cluely employee monitoring software and its specific evasion techniques.
131
+ All methods are thread-safe and can be called from any thread.
132
+ """
133
+
134
+ @staticmethod
135
+ def is_cluely_running() -> bool:
136
+ """
137
+ Simple check if Cluely monitoring software is running.
138
+
139
+ Returns:
140
+ True if Cluely is detected, False otherwise
141
+
142
+ Example:
143
+ >>> if ClueLyDetector.is_cluely_running():
144
+ ... print("⚠️ Employee monitoring detected!")
145
+ """
146
+ return _lib.is_cluely_running() != 0
147
+
148
+ @staticmethod
149
+ def detect_cluely() -> tuple[bool, int]:
150
+ """
151
+ Basic detection with window count.
152
+
153
+ Returns:
154
+ Tuple of (is_detected, window_count)
155
+
156
+ Example:
157
+ >>> is_detected, window_count = ClueLyDetector.detect_cluely()
158
+ >>> print(f"Detected: {is_detected}, Windows: {window_count}")
159
+ """
160
+ result = _lib.detect_cluely()
161
+ return result.is_detected, result.window_count
162
+
163
+ @staticmethod
164
+ def detect_cluely_detailed() -> ClueLyDetection:
165
+ """
166
+ Detailed detection with evasion technique analysis.
167
+
168
+ Returns:
169
+ ClueLyDetection object with comprehensive information
170
+
171
+ Example:
172
+ >>> detection = ClueLyDetector.detect_cluely_detailed()
173
+ >>> if detection.is_detected:
174
+ ... print(f"Severity: {detection.severity_level}")
175
+ ... print(f"Techniques: {', '.join(detection.evasion_techniques)}")
176
+ """
177
+ result = _lib.detect_cluely()
178
+
179
+ # Get the detailed report
180
+ report_ptr = _lib.get_cluely_report()
181
+ try:
182
+ if report_ptr:
183
+ report = report_ptr.decode("utf-8")
184
+ else:
185
+ report = "No detailed report available"
186
+ finally:
187
+ if report_ptr:
188
+ _lib.free_cluely_report(report_ptr)
189
+
190
+ # Calculate severity level
191
+ technique_count = 0
192
+ if result.screen_capture_evasion_count > 0:
193
+ technique_count += 1
194
+ if result.elevated_layer_count > 0:
195
+ technique_count += 1
196
+
197
+ if not result.is_detected:
198
+ severity_level = "None"
199
+ elif technique_count == 0:
200
+ severity_level = "Low"
201
+ elif technique_count == 1:
202
+ severity_level = "Medium"
203
+ else:
204
+ severity_level = "High"
205
+
206
+ # Build evasion techniques list
207
+ evasion_techniques = []
208
+ if result.screen_capture_evasion_count > 0:
209
+ evasion_techniques.append(
210
+ f"Screen capture evasion ({result.screen_capture_evasion_count} windows)"
211
+ )
212
+ if result.elevated_layer_count > 0:
213
+ evasion_techniques.append(
214
+ f"Elevated layer positioning ({result.elevated_layer_count} windows)"
215
+ )
216
+
217
+ return ClueLyDetection(
218
+ is_detected=result.is_detected,
219
+ window_count=result.window_count,
220
+ screen_capture_evasion_count=result.screen_capture_evasion_count,
221
+ elevated_layer_count=result.elevated_layer_count,
222
+ max_layer_detected=result.max_layer_detected,
223
+ severity_level=severity_level,
224
+ evasion_techniques=evasion_techniques,
225
+ report=report,
226
+ timestamp=datetime.now(),
227
+ )
228
+
229
+ @staticmethod
230
+ def get_cluely_report() -> str:
231
+ """
232
+ Get detailed text report of detection results.
233
+
234
+ Returns:
235
+ Detailed text report explaining what was found
236
+
237
+ Example:
238
+ >>> report = ClueLyDetector.get_cluely_report()
239
+ >>> print(report)
240
+ """
241
+ report_ptr = _lib.get_cluely_report()
242
+ try:
243
+ if report_ptr:
244
+ return report_ptr.decode("utf-8")
245
+ else:
246
+ return "No report available"
247
+ finally:
248
+ if report_ptr:
249
+ _lib.free_cluely_report(report_ptr)
250
+
251
+ @staticmethod
252
+ def get_cluely_window_count() -> int:
253
+ """
254
+ Get the number of Cluely windows detected.
255
+
256
+ Returns:
257
+ Number of Cluely windows
258
+
259
+ Example:
260
+ >>> count = ClueLyDetector.get_cluely_window_count()
261
+ >>> print(f"Found {count} Cluely windows")
262
+ """
263
+ return _lib.get_cluely_window_count()
264
+
265
+
266
+ class ClueLyMonitor:
267
+ """
268
+ Monitor for Cluely detection changes with event callbacks.
269
+
270
+ This class provides continuous monitoring with callbacks for detection events.
271
+ It runs in a separate thread to avoid blocking the main application.
272
+ """
273
+
274
+ def __init__(self):
275
+ self._running = False
276
+ self._thread: Optional[threading.Thread] = None
277
+ self._last_detection: Optional[ClueLyDetection] = None
278
+ self._callbacks = {}
279
+
280
+ def start(
281
+ self,
282
+ interval: float = 10.0,
283
+ on_detected: Optional[callable] = None,
284
+ on_removed: Optional[callable] = None,
285
+ on_change: Optional[callable] = None,
286
+ ) -> None:
287
+ """
288
+ Start monitoring for Cluely detection changes.
289
+
290
+ Args:
291
+ interval: Check interval in seconds (default: 10.0)
292
+ on_detected: Callback when Cluely is first detected
293
+ on_removed: Callback when Cluely monitoring stops
294
+ on_change: Callback on every detection check
295
+
296
+ Example:
297
+ >>> def alert(detection):
298
+ ... print(f"🚨 Cluely detected! Severity: {detection.severity_level}")
299
+ >>>
300
+ >>> monitor = ClueLyMonitor()
301
+ >>> monitor.start(interval=5.0, on_detected=alert)
302
+ """
303
+ if self._running:
304
+ raise RuntimeError("Monitor is already running")
305
+
306
+ self._callbacks = {
307
+ "on_detected": on_detected,
308
+ "on_removed": on_removed,
309
+ "on_change": on_change,
310
+ }
311
+
312
+ self._running = True
313
+ self._thread = threading.Thread(target=self._monitor_loop, args=(interval,))
314
+ self._thread.daemon = True
315
+ self._thread.start()
316
+
317
+ def stop(self) -> None:
318
+ """
319
+ Stop monitoring.
320
+
321
+ Example:
322
+ >>> monitor.stop()
323
+ """
324
+ self._running = False
325
+ if self._thread:
326
+ self._thread.join(timeout=5.0)
327
+ self._thread = None
328
+
329
+ def get_last_detection(self) -> Optional[ClueLyDetection]:
330
+ """
331
+ Get the last detection result.
332
+
333
+ Returns:
334
+ Last ClueLyDetection result or None if no detection has been performed
335
+
336
+ Example:
337
+ >>> last = monitor.get_last_detection()
338
+ >>> if last and last.is_detected:
339
+ ... print("Still detected")
340
+ """
341
+ return self._last_detection
342
+
343
+ def _monitor_loop(self, interval: float) -> None:
344
+ """Internal monitoring loop."""
345
+ while self._running:
346
+ try:
347
+ detection = ClueLyDetector.detect_cluely_detailed()
348
+
349
+ # Check for state changes
350
+ if self._last_detection:
351
+ if detection.is_detected and not self._last_detection.is_detected:
352
+ # Just detected
353
+ if self._callbacks["on_detected"]:
354
+ self._callbacks["on_detected"](detection)
355
+ elif not detection.is_detected and self._last_detection.is_detected:
356
+ # Just stopped
357
+ if self._callbacks["on_removed"]:
358
+ self._callbacks["on_removed"]()
359
+ else:
360
+ # First check
361
+ if detection.is_detected and self._callbacks["on_detected"]:
362
+ self._callbacks["on_detected"](detection)
363
+
364
+ # Always call on_change if provided
365
+ if self._callbacks["on_change"]:
366
+ self._callbacks["on_change"](detection)
367
+
368
+ self._last_detection = detection
369
+
370
+ except Exception as e:
371
+ # Log error but continue monitoring
372
+ print(f"Monitoring error: {e}")
373
+
374
+ if self._running:
375
+ time.sleep(interval)
376
+
377
+
378
+ # Convenience functions for quick access
379
+ def is_cluely_running() -> bool:
380
+ """Convenience function: Check if Cluely is running."""
381
+ return ClueLyDetector.is_cluely_running()
382
+
383
+
384
+ def detect_cluely() -> tuple[bool, int]:
385
+ """Convenience function: Basic detection with window count."""
386
+ return ClueLyDetector.detect_cluely()
387
+
388
+
389
+ def detect_cluely_detailed() -> ClueLyDetection:
390
+ """Convenience function: Detailed detection with evasion analysis."""
391
+ return ClueLyDetector.detect_cluely_detailed()
392
+
393
+
394
+ def get_cluely_report() -> str:
395
+ """Convenience function: Get detailed text report."""
396
+ return ClueLyDetector.get_cluely_report()
397
+
398
+
399
+ # Export public API
400
+ __all__ = [
401
+ "ClueLyDetector",
402
+ "ClueLyDetection",
403
+ "ClueLyMonitor",
404
+ "is_cluely_running",
405
+ "detect_cluely",
406
+ "detect_cluely_detailed",
407
+ "get_cluely_report",
408
+ ]
409
+
410
+ # Version information
411
+ __version__ = "1.0.0"
412
+ __author__ = "No-Cluely Team"
@@ -0,0 +1 @@
1
+ # This file indicates that this package supports type hints (PEP 561)
@@ -0,0 +1,586 @@
1
+ Metadata-Version: 2.4
2
+ Name: no-cluely-detector
3
+ Version: 0.0.1
4
+ Summary: Detect Cluely employee monitoring software and its evasion techniques
5
+ Author: No-Cluely Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/your-org/no-cluely-driver
8
+ Project-URL: Bug Reports, https://github.com/your-org/no-cluely-driver/issues
9
+ Project-URL: Source, https://github.com/your-org/no-cluely-driver
10
+ Project-URL: Documentation, https://github.com/your-org/no-cluely-driver#readme
11
+ Keywords: privacy,monitoring,detection,cluely,employee,screen-sharing,evasion,macos
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Security
24
+ Classifier: Topic :: System :: Monitoring
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ Requires-Dist: typing-extensions>=4.0.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
31
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
32
+ Requires-Dist: black>=22.0.0; extra == "dev"
33
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
34
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
35
+
36
+ # no-cluely-detector 🎯
37
+
38
+ Python library for detecting Cluely employee monitoring software and its evasion techniques.
39
+
40
+ ## Features
41
+
42
+ - **Fast Detection**: Built on a high-performance Rust engine
43
+ - **Thread-Safe**: Use from any thread in your Python application
44
+ - **Type-Safe**: Full type hints support with mypy compatibility
45
+ - **Event Monitoring**: Real-time callbacks for detection changes
46
+ - **Detailed Analysis**: Comprehensive evasion technique reporting
47
+ - **Easy Integration**: Simple API for any Python project
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ pip install no-cluely-detector
53
+ ```
54
+
55
+ ### Requirements
56
+
57
+ - **Python**: 3.8 or later
58
+ - **Platform**: macOS only (Cluely is macOS-specific)
59
+ - **Architecture**: x64 (Intel/Apple Silicon)
60
+
61
+ ## Quick Start
62
+
63
+ ### Simple Detection
64
+ ```python
65
+ from no_cluely_detector import ClueLyDetector
66
+
67
+ # Quick check
68
+ if ClueLyDetector.is_cluely_running():
69
+ print("⚠️ Employee monitoring detected!")
70
+ else:
71
+ print("✅ No monitoring software found")
72
+ ```
73
+
74
+ ### Detailed Analysis
75
+ ```python
76
+ from no_cluely_detector import ClueLyDetector
77
+
78
+ detection = ClueLyDetector.detect_cluely_detailed()
79
+
80
+ if detection.is_detected:
81
+ print(f"🚨 Cluely Detected!")
82
+ print(f" Severity: {detection.severity_level}")
83
+ print(f" Windows: {detection.window_count}")
84
+ print(f" Techniques: {', '.join(detection.evasion_techniques)}")
85
+ else:
86
+ print("✅ System clean")
87
+ ```
88
+
89
+ ### Real-time Monitoring
90
+ ```python
91
+ from no_cluely_detector import ClueLyMonitor
92
+
93
+ def on_detected(detection):
94
+ print(f"🚨 Monitoring started! Severity: {detection.severity_level}")
95
+
96
+ def on_removed():
97
+ print("✅ Monitoring stopped")
98
+
99
+ monitor = ClueLyMonitor()
100
+ monitor.start(
101
+ interval=5.0, # Check every 5 seconds
102
+ on_detected=on_detected,
103
+ on_removed=on_removed
104
+ )
105
+
106
+ # Your application continues...
107
+ # Call monitor.stop() when done
108
+ ```
109
+
110
+ ## API Reference
111
+
112
+ ### ClueLyDetector
113
+
114
+ Main detection class with static methods for detecting Cluely monitoring software.
115
+
116
+ #### Methods
117
+
118
+ ##### `ClueLyDetector.is_cluely_running() -> bool`
119
+ Simple boolean check for Cluely presence.
120
+
121
+ ```python
122
+ detected = ClueLyDetector.is_cluely_running()
123
+ ```
124
+
125
+ ##### `ClueLyDetector.detect_cluely() -> tuple[bool, int]`
126
+ Basic detection returning status and window count.
127
+
128
+ ```python
129
+ is_detected, window_count = ClueLyDetector.detect_cluely()
130
+ print(f"Detected: {is_detected}, Windows: {window_count}")
131
+ ```
132
+
133
+ ##### `ClueLyDetector.detect_cluely_detailed() -> ClueLyDetection`
134
+ Comprehensive detection with full analysis.
135
+
136
+ ```python
137
+ detection = ClueLyDetector.detect_cluely_detailed()
138
+ # Returns ClueLyDetection object with all details
139
+ ```
140
+
141
+ ##### `ClueLyDetector.get_cluely_report() -> str`
142
+ Detailed text report of findings.
143
+
144
+ ```python
145
+ report = ClueLyDetector.get_cluely_report()
146
+ print(report)
147
+ ```
148
+
149
+ ##### `ClueLyDetector.get_cluely_window_count() -> int`
150
+ Number of Cluely windows detected.
151
+
152
+ ```python
153
+ count = ClueLyDetector.get_cluely_window_count()
154
+ ```
155
+
156
+ ### ClueLyDetection
157
+
158
+ Data class containing detailed detection information.
159
+
160
+ #### Attributes
161
+
162
+ - `is_detected: bool` - True if Cluely is detected
163
+ - `window_count: int` - Total number of Cluely windows
164
+ - `screen_capture_evasion_count: int` - Windows using screen capture evasion
165
+ - `elevated_layer_count: int` - Windows using elevated layer positioning
166
+ - `max_layer_detected: int` - Highest layer number found
167
+ - `severity_level: str` - Severity ('None', 'Low', 'Medium', 'High')
168
+ - `evasion_techniques: List[str]` - List of detected techniques
169
+ - `report: str` - Detailed text report
170
+ - `timestamp: datetime` - Detection timestamp
171
+
172
+ ```python
173
+ detection = ClueLyDetector.detect_cluely_detailed()
174
+
175
+ print(f"Detected: {detection.is_detected}")
176
+ print(f"Severity: {detection.severity_level}")
177
+ print(f"Evasion Techniques:")
178
+ for technique in detection.evasion_techniques:
179
+ print(f" - {technique}")
180
+ ```
181
+
182
+ ### ClueLyMonitor
183
+
184
+ Event-based monitoring for detection changes.
185
+
186
+ #### Methods
187
+
188
+ ##### `start(interval=10.0, on_detected=None, on_removed=None, on_change=None)`
189
+ Start monitoring with event callbacks.
190
+
191
+ - `interval: float` - Check interval in seconds
192
+ - `on_detected: callable` - Called when Cluely is first detected
193
+ - `on_removed: callable` - Called when Cluely monitoring stops
194
+ - `on_change: callable` - Called on every check
195
+
196
+ ##### `stop()`
197
+ Stop monitoring and cleanup resources.
198
+
199
+ ##### `get_last_detection() -> Optional[ClueLyDetection]`
200
+ Get the most recent detection result.
201
+
202
+ ```python
203
+ monitor = ClueLyMonitor()
204
+
205
+ def alert(detection):
206
+ send_email(f"Security Alert: {detection.severity_level}")
207
+
208
+ monitor.start(interval=30.0, on_detected=alert)
209
+ ```
210
+
211
+ ## Usage Examples
212
+
213
+ ### Flask Web Application
214
+ ```python
215
+ from flask import Flask, jsonify
216
+ from no_cluely_detector import ClueLyDetector
217
+
218
+ app = Flask(__name__)
219
+
220
+ @app.route('/api/security/check')
221
+ def security_check():
222
+ detection = ClueLyDetector.detect_cluely_detailed()
223
+
224
+ return jsonify({
225
+ 'monitoring_detected': detection.is_detected,
226
+ 'severity': detection.severity_level,
227
+ 'evasion_techniques': detection.evasion_techniques,
228
+ 'window_count': detection.window_count,
229
+ 'timestamp': detection.timestamp.isoformat()
230
+ })
231
+
232
+ if __name__ == '__main__':
233
+ app.run(debug=True)
234
+ ```
235
+
236
+ ### Django Integration
237
+ ```python
238
+ # views.py
239
+ from django.http import JsonResponse
240
+ from django.views.decorators.http import require_http_methods
241
+ from no_cluely_detector import ClueLyDetector
242
+
243
+ @require_http_methods(["GET"])
244
+ def check_monitoring(request):
245
+ detection = ClueLyDetector.detect_cluely_detailed()
246
+
247
+ return JsonResponse({
248
+ 'detected': detection.is_detected,
249
+ 'severity': detection.severity_level,
250
+ 'techniques': detection.evasion_techniques,
251
+ 'report': detection.report
252
+ })
253
+
254
+ # urls.py
255
+ from django.urls import path
256
+ from . import views
257
+
258
+ urlpatterns = [
259
+ path('security/check/', views.check_monitoring, name='check_monitoring'),
260
+ ]
261
+ ```
262
+
263
+ ### FastAPI Application
264
+ ```python
265
+ from fastapi import FastAPI
266
+ from pydantic import BaseModel
267
+ from typing import List
268
+ from datetime import datetime
269
+ from no_cluely_detector import ClueLyDetector, ClueLyDetection
270
+
271
+ app = FastAPI(title="Security Monitor API")
272
+
273
+ class SecurityStatus(BaseModel):
274
+ detected: bool
275
+ severity: str
276
+ evasion_techniques: List[str]
277
+ window_count: int
278
+ timestamp: datetime
279
+
280
+ @app.get("/security/check", response_model=SecurityStatus)
281
+ async def check_security():
282
+ detection = ClueLyDetector.detect_cluely_detailed()
283
+
284
+ return SecurityStatus(
285
+ detected=detection.is_detected,
286
+ severity=detection.severity_level,
287
+ evasion_techniques=detection.evasion_techniques,
288
+ window_count=detection.window_count,
289
+ timestamp=detection.timestamp
290
+ )
291
+ ```
292
+
293
+ ### Background Monitoring Service
294
+ ```python
295
+ import time
296
+ import logging
297
+ from no_cluely_detector import ClueLyMonitor
298
+ from email.mime.text import MimeText
299
+ import smtplib
300
+
301
+ logging.basicConfig(level=logging.INFO)
302
+ logger = logging.getLogger(__name__)
303
+
304
+ class SecurityMonitorService:
305
+ def __init__(self, email_alerts=True):
306
+ self.monitor = ClueLyMonitor()
307
+ self.email_alerts = email_alerts
308
+
309
+ def start(self):
310
+ logger.info("Starting security monitoring service...")
311
+
312
+ self.monitor.start(
313
+ interval=60.0, # Check every minute
314
+ on_detected=self._on_threat_detected,
315
+ on_removed=self._on_threat_removed,
316
+ on_change=self._on_status_change
317
+ )
318
+
319
+ def stop(self):
320
+ logger.info("Stopping security monitoring service...")
321
+ self.monitor.stop()
322
+
323
+ def _on_threat_detected(self, detection):
324
+ logger.warning(f"🚨 SECURITY THREAT DETECTED - Severity: {detection.severity_level}")
325
+
326
+ if self.email_alerts:
327
+ self._send_alert_email(detection)
328
+
329
+ # Log to security system
330
+ self._log_security_event("THREAT_DETECTED", detection)
331
+
332
+ def _on_threat_removed(self):
333
+ logger.info("✅ Security threat removed")
334
+ self._log_security_event("THREAT_REMOVED", None)
335
+
336
+ def _on_status_change(self, detection):
337
+ # Log periodic status (every 10 minutes)
338
+ if int(time.time()) % 600 == 0:
339
+ status = "DETECTED" if detection.is_detected else "CLEAN"
340
+ logger.info(f"Security status: {status}")
341
+
342
+ def _send_alert_email(self, detection):
343
+ # Implementation depends on your email setup
344
+ subject = f"Security Alert: Employee Monitoring Detected ({detection.severity_level})"
345
+ body = f"""
346
+ Security Alert: Cluely employee monitoring software detected
347
+
348
+ Severity: {detection.severity_level}
349
+ Evasion Techniques: {', '.join(detection.evasion_techniques)}
350
+ Window Count: {detection.window_count}
351
+ Time: {detection.timestamp}
352
+
353
+ Report:
354
+ {detection.report}
355
+ """
356
+ # Send email implementation here
357
+
358
+ def _log_security_event(self, event_type, detection):
359
+ # Log to your security information system
360
+ event_data = {
361
+ 'event_type': event_type,
362
+ 'timestamp': time.time(),
363
+ 'detection': detection.__dict__ if detection else None
364
+ }
365
+ logger.info(f"Security event: {event_data}")
366
+
367
+ # Usage
368
+ if __name__ == "__main__":
369
+ service = SecurityMonitorService()
370
+ service.start()
371
+
372
+ try:
373
+ # Keep the service running
374
+ while True:
375
+ time.sleep(60)
376
+ except KeyboardInterrupt:
377
+ service.stop()
378
+ ```
379
+
380
+ ### Jupyter Notebook Integration
381
+ ```python
382
+ # Cell 1: Setup
383
+ from no_cluely_detector import ClueLyDetector, ClueLyMonitor
384
+ import pandas as pd
385
+ from datetime import datetime
386
+ import matplotlib.pyplot as plt
387
+
388
+ # Cell 2: Single Check
389
+ detection = ClueLyDetector.detect_cluely_detailed()
390
+
391
+ print(f"🔍 Security Check Results")
392
+ print(f"========================")
393
+ print(f"Detected: {'🚨 YES' if detection.is_detected else '✅ NO'}")
394
+ if detection.is_detected:
395
+ print(f"Severity: {detection.severity_level}")
396
+ print(f"Techniques: {', '.join(detection.evasion_techniques)}")
397
+
398
+ # Cell 3: Historical Analysis
399
+ detection_history = []
400
+
401
+ def record_detection(detection):
402
+ detection_history.append({
403
+ 'timestamp': detection.timestamp,
404
+ 'detected': detection.is_detected,
405
+ 'severity': detection.severity_level,
406
+ 'window_count': detection.window_count
407
+ })
408
+
409
+ monitor = ClueLyMonitor()
410
+ monitor.start(interval=30.0, on_change=record_detection)
411
+
412
+ # Let it run for a while, then analyze
413
+ # monitor.stop()
414
+
415
+ # Cell 4: Visualization
416
+ df = pd.DataFrame(detection_history)
417
+ df['timestamp'] = pd.to_datetime(df['timestamp'])
418
+
419
+ plt.figure(figsize=(12, 6))
420
+ plt.subplot(2, 1, 1)
421
+ plt.plot(df['timestamp'], df['detected'].astype(int))
422
+ plt.title('Detection Status Over Time')
423
+ plt.ylabel('Detected (1=Yes, 0=No)')
424
+
425
+ plt.subplot(2, 1, 2)
426
+ plt.plot(df['timestamp'], df['window_count'])
427
+ plt.title('Window Count Over Time')
428
+ plt.ylabel('Window Count')
429
+ plt.xlabel('Time')
430
+
431
+ plt.tight_layout()
432
+ plt.show()
433
+ ```
434
+
435
+ ### Automation Script
436
+ ```python
437
+ #!/usr/bin/env python3
438
+ """
439
+ Security monitoring automation script
440
+ Usage: python security_monitor.py [--interval SECONDS] [--log-file PATH]
441
+ """
442
+
443
+ import argparse
444
+ import sys
445
+ import time
446
+ import json
447
+ from pathlib import Path
448
+ from no_cluely_detector import ClueLyMonitor
449
+
450
+ def main():
451
+ parser = argparse.ArgumentParser(description='Monitor for Cluely employee monitoring software')
452
+ parser.add_argument('--interval', type=float, default=60.0,
453
+ help='Check interval in seconds (default: 60)')
454
+ parser.add_argument('--log-file', type=Path,
455
+ help='JSON log file path')
456
+ parser.add_argument('--alert-command', type=str,
457
+ help='Command to run when threat detected')
458
+
459
+ args = parser.parse_args()
460
+
461
+ def log_detection(detection):
462
+ log_entry = {
463
+ 'timestamp': detection.timestamp.isoformat(),
464
+ 'detected': detection.is_detected,
465
+ 'severity': detection.severity_level,
466
+ 'evasion_techniques': detection.evasion_techniques,
467
+ 'window_count': detection.window_count
468
+ }
469
+
470
+ if args.log_file:
471
+ with open(args.log_file, 'a') as f:
472
+ f.write(json.dumps(log_entry) + '\n')
473
+
474
+ # Print to console
475
+ status = f"🚨 DETECTED ({detection.severity_level})" if detection.is_detected else "✅ CLEAN"
476
+ print(f"[{detection.timestamp}] {status}")
477
+
478
+ if detection.is_detected and detection.evasion_techniques:
479
+ print(f" Techniques: {', '.join(detection.evasion_techniques)}")
480
+
481
+ def on_detected(detection):
482
+ print(f"🚨 ALERT: Employee monitoring detected! Severity: {detection.severity_level}")
483
+
484
+ if args.alert_command:
485
+ import subprocess
486
+ try:
487
+ subprocess.run(args.alert_command.split(), check=True)
488
+ except subprocess.CalledProcessError as e:
489
+ print(f"Alert command failed: {e}")
490
+
491
+ print(f"Starting security monitor (interval: {args.interval}s)")
492
+ if args.log_file:
493
+ print(f"Logging to: {args.log_file}")
494
+
495
+ monitor = ClueLyMonitor()
496
+ monitor.start(
497
+ interval=args.interval,
498
+ on_detected=on_detected,
499
+ on_change=log_detection
500
+ )
501
+
502
+ try:
503
+ while True:
504
+ time.sleep(1)
505
+ except KeyboardInterrupt:
506
+ print("\nStopping monitor...")
507
+ monitor.stop()
508
+
509
+ if __name__ == '__main__':
510
+ main()
511
+ ```
512
+
513
+ ## Error Handling
514
+
515
+ ```python
516
+ from no_cluely_detector import ClueLyDetector
517
+ import platform
518
+
519
+ try:
520
+ detection = ClueLyDetector.detect_cluely_detailed()
521
+ # Process detection...
522
+ except RuntimeError as e:
523
+ if "only supported on macOS" in str(e):
524
+ print("This library only works on macOS")
525
+ else:
526
+ print(f"Detection error: {e}")
527
+ except FileNotFoundError as e:
528
+ print("Rust library not found. Please install properly.")
529
+ except Exception as e:
530
+ print(f"Unexpected error: {e}")
531
+ ```
532
+
533
+ ## Performance
534
+
535
+ - **Detection Speed**: < 50ms per check
536
+ - **Memory Usage**: < 2MB resident memory
537
+ - **Thread Safety**: All methods are thread-safe
538
+ - **CPU Usage**: Minimal (< 0.1% during checks)
539
+
540
+ ## Testing
541
+
542
+ ```python
543
+ # test_detection.py
544
+ import pytest
545
+ from no_cluely_detector import ClueLyDetector, ClueLyMonitor
546
+
547
+ def test_basic_detection():
548
+ """Test basic detection functionality."""
549
+ result = ClueLyDetector.is_cluely_running()
550
+ assert isinstance(result, bool)
551
+
552
+ def test_detailed_detection():
553
+ """Test detailed detection."""
554
+ detection = ClueLyDetector.detect_cluely_detailed()
555
+
556
+ assert hasattr(detection, 'is_detected')
557
+ assert hasattr(detection, 'severity_level')
558
+ assert isinstance(detection.evasion_techniques, list)
559
+ assert detection.severity_level in ['None', 'Low', 'Medium', 'High']
560
+
561
+ def test_monitor():
562
+ """Test monitoring functionality."""
563
+ monitor = ClueLyMonitor()
564
+
565
+ # Should start and stop without issues
566
+ monitor.start(interval=1.0)
567
+ time.sleep(2)
568
+ monitor.stop()
569
+
570
+ if __name__ == '__main__':
571
+ pytest.main([__file__])
572
+ ```
573
+
574
+ Run tests:
575
+ ```bash
576
+ pip install pytest
577
+ python -m pytest test_detection.py -v
578
+ ```
579
+
580
+ ## License
581
+
582
+ MIT License
583
+
584
+ ## Contributing
585
+
586
+ Issues and pull requests welcome at: https://github.com/your-org/no-cluely-driver
@@ -0,0 +1,6 @@
1
+ no_cluely_detector/__init__.py,sha256=CpJrFN-by68C1zJ3O_XAXLqya4TrZ40-EBOENLwYOPY,12836
2
+ no_cluely_detector/py.typed,sha256=ly_OTohiB3OSMv5IvZcW13LkzgSEk-ieT7d3zlEXpdc,70
3
+ no_cluely_detector-0.0.1.dist-info/METADATA,sha256=n8N2ceZnzSNPdJhvsim43sgLweTfh_1HyigRHfvvqUk,16899
4
+ no_cluely_detector-0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ no_cluely_detector-0.0.1.dist-info/top_level.txt,sha256=BCY0tJTlX9NWuKdsapwC3nY9tnYQ_iymXuZlFpWoeAc,19
6
+ no_cluely_detector-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ no_cluely_detector