tzero-mcp 10.7.0 → 10.7.1

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 (96) hide show
  1. package/bin/tzero-mcp.js +9 -16
  2. package/bin/tzero.js +9 -16
  3. package/index.js +7 -2
  4. package/package.json +2 -1
  5. package/src/addmcp.py +1194 -0
  6. package/src/main.py +60 -0
  7. package/src/siber_akademi_icon.py +77 -0
  8. package/src/tzero/jarvis/semantic_compressor.py +373 -0
  9. package/src/tzero.py +58 -0
  10. package/src/tzero_benchmark.py +475 -0
  11. package/src/tzero_bridge.py +362 -0
  12. package/src/tzero_ci.py +153 -0
  13. package/src/tzero_commit.py +192 -0
  14. package/src/tzero_cost.py +163 -0
  15. package/src/tzero_dashboard.py +1448 -0
  16. package/src/tzero_deps.py +287 -0
  17. package/src/tzero_drift.py +208 -0
  18. package/src/tzero_explain.py +240 -0
  19. package/src/tzero_features.py +3022 -0
  20. package/src/tzero_fix.py +228 -0
  21. package/src/tzero_fixer/__init__.py +63 -0
  22. package/src/tzero_fixer/amalgamation.py +334 -0
  23. package/src/tzero_fixer/ast_syntax_healer.py +464 -0
  24. package/src/tzero_fixer/ast_type_modernizer.py +288 -0
  25. package/src/tzero_fixer/async_io_modernizer.py +127 -0
  26. package/src/tzero_fixer/automated_regression_suite.py +600 -0
  27. package/src/tzero_fixer/benchmarks_and_diagnostics.py +174 -0
  28. package/src/tzero_fixer/ci_cd_self_healing_gate.py +246 -0
  29. package/src/tzero_fixer/code_duplicity_and_refactorer.py +151 -0
  30. package/src/tzero_fixer/code_smells_healer.py +260 -0
  31. package/src/tzero_fixer/cwe_remediator.py +171 -0
  32. package/src/tzero_fixer/dead_code_eliminator.py +150 -0
  33. package/src/tzero_fixer/dependency_vulnerability_auditor.py +309 -0
  34. package/src/tzero_fixer/git_advanced_surgeon.py +280 -0
  35. package/src/tzero_fixer/hardware_and_disk_doctor.py +325 -0
  36. package/src/tzero_fixer/import_graph_healer.py +412 -0
  37. package/src/tzero_fixer/interactive_tui.py +91 -0
  38. package/src/tzero_fixer/knowledge_base.py +295 -0
  39. package/src/tzero_fixer/knowledge_base_extended.py +940 -0
  40. package/src/tzero_fixer/linters_and_static_analyzer.py +307 -0
  41. package/src/tzero_fixer/mcp_server.py +447 -0
  42. package/src/tzero_fixer/models.py +385 -0
  43. package/src/tzero_fixer/orchestrator.py +375 -0
  44. package/src/tzero_fixer/os_doctor.py +502 -0
  45. package/src/tzero_fixer/packaging_abi_surgeon.py +323 -0
  46. package/src/tzero_fixer/pc_fixer_doctor.py +599 -0
  47. package/src/tzero_fixer/performance_and_memory_profiler.py +274 -0
  48. package/src/tzero_fixer/polyglot_ast_parsers.py +313 -0
  49. package/src/tzero_fixer/polyglot_build_healer.py +364 -0
  50. package/src/tzero_fixer/polyglot_config_healer.py +318 -0
  51. package/src/tzero_fixer/polyglot_doctor.py +372 -0
  52. package/src/tzero_fixer/polyglot_linters.py +619 -0
  53. package/src/tzero_fixer/polyglot_schema_validator.py +305 -0
  54. package/src/tzero_fixer/security_cwe_database.py +444 -0
  55. package/src/tzero_fixer/security_deep_rules.py +114 -0
  56. package/src/tzero_fixer/security_rules_catalog.py +110 -0
  57. package/src/tzero_fixer/security_zero_leak.py +326 -0
  58. package/src/tzero_fixer/smart_patch_recommender.py +223 -0
  59. package/src/tzero_fixer/synthetic_workspace_generator.py +220 -0
  60. package/src/tzero_fixer/system_diagnostics_extended.py +493 -0
  61. package/src/tzero_fixer/system_repair_recipes.py +447 -0
  62. package/src/tzero_fixer/venv_doctor.py +309 -0
  63. package/src/tzero_gateway.py +885 -0
  64. package/src/tzero_guard.py +243 -0
  65. package/src/tzero_infra.py +274 -0
  66. package/src/tzero_jarvis/__init__.py +124 -0
  67. package/src/tzero_jarvis/causal_graph.py +310 -0
  68. package/src/tzero_jarvis/graph_visualizer.py +395 -0
  69. package/src/tzero_jarvis/hybrid_search.py +214 -0
  70. package/src/tzero_jarvis/latent_press.py +137 -0
  71. package/src/tzero_jarvis/memory_consolidation.py +212 -0
  72. package/src/tzero_jarvis/minhash_lsh.py +184 -0
  73. package/src/tzero_jarvis/orchestrator.py +335 -0
  74. package/src/tzero_jarvis/self_healing.py +308 -0
  75. package/src/tzero_jarvis/semantic_compressor.py +887 -0
  76. package/src/tzero_jarvis/swarm.py +261 -0
  77. package/src/tzero_jarvis/swarm_bft.py +144 -0
  78. package/src/tzero_jarvis/workspace_orchestrator.py +1167 -0
  79. package/src/tzero_jarvis/zero_key_router.py +173 -0
  80. package/src/tzero_mcp.py +4858 -0
  81. package/src/tzero_neural_cortex.py +1425 -0
  82. package/src/tzero_packer.py +370 -0
  83. package/src/tzero_patch.py +624 -0
  84. package/src/tzero_pc_fixer.py +12657 -0
  85. package/src/tzero_pipe.py +95 -0
  86. package/src/tzero_polyglot.py +422 -0
  87. package/src/tzero_reachability.py +272 -0
  88. package/src/tzero_replay.py +141 -0
  89. package/src/tzero_security.py +570 -0
  90. package/src/tzero_snapshot.py +258 -0
  91. package/src/tzero_stubs.py +313 -0
  92. package/src/tzero_superdesign.py +774 -0
  93. package/src/tzero_sync.py +241 -0
  94. package/src/tzero_task_benchmark.py +363 -0
  95. package/src/tzero_tui.py +244 -0
  96. package/src/tzero_v3.py +9435 -0
@@ -0,0 +1,502 @@
1
+ # -*- coding: utf-8 -*-
2
+ """T-Zero Operating System, Toolchain, & Hardware Environment Doctor.
3
+
4
+ Performs deep hardware, runtime environment, CLI toolchain, and OS-level diagnostics:
5
+ - Tool probing with version parsing (git, python, pip, npm, npx, pnpm, yarn, bun, rustc, cargo, go, docker, code, cursor).
6
+ - Windows Registry inspection (LongPathsEnabled, PythonCore registration, dead PATH entries).
7
+ - POSIX permissions, ulimits, and file handle exhaustion checks.
8
+ - File lock detection and exclusive access verification.
9
+ - Stale lockfiles (.git/index.lock, .cargo/.package-cache) and orphaned bytecode sweeper.
10
+ - Hardware metrics: RAM availability, disk space, and temp bloat inspection.
11
+
12
+ Author: Toprak Ahmet Aydogmus (Siber Akademi)
13
+ Version: 10.4.0
14
+ """
15
+
16
+ import os
17
+ import platform
18
+ import re
19
+ import shutil
20
+ import subprocess
21
+ import sys
22
+ import tempfile
23
+ import time
24
+ from pathlib import Path
25
+ from typing import Any, Dict, List, Optional, Set, Tuple
26
+
27
+ from .models import (
28
+ DiagnosticCategory,
29
+ DiagnosticIssue,
30
+ EnvironmentSnapshot,
31
+ HealAction,
32
+ SeverityLevel,
33
+ SystemPlatform,
34
+ ToolStatus,
35
+ )
36
+
37
+
38
+ class OSDoctor:
39
+ """Enterprise-grade diagnostic engine for OS, hardware, filesystem, and CLI tools."""
40
+
41
+ CRITICAL_TOOLS = [
42
+ ("python", "3.9.0", "Python interpreter runtime"),
43
+ ("pip", "20.0.0", "Python package installer"),
44
+ ("git", "2.20.0", "Distributed version control system"),
45
+ ]
46
+
47
+ SECONDARY_TOOLS = [
48
+ ("npm", "8.0.0", "Node package manager"),
49
+ ("npx", "8.0.0", "Node package executor"),
50
+ ("pnpm", "7.0.0", "Fast disk space efficient package manager"),
51
+ ("yarn", "1.22.0", "Yarn dependency manager"),
52
+ ("bun", "1.0.0", "All-in-one JavaScript runtime & toolkit"),
53
+ ("rustc", "1.65.0", "Rust systems programming compiler"),
54
+ ("cargo", "1.65.0", "Rust package manager & build tool"),
55
+ ("go", "1.18.0", "Go programming language toolchain"),
56
+ ("docker", "20.10.0", "Container virtualization engine"),
57
+ ("code", "1.70.0", "Visual Studio Code editor"),
58
+ ("cursor", "0.10.0", "Cursor AI-first code editor"),
59
+ ]
60
+
61
+ IGNORED_DIRS = {
62
+ ".git", ".svn", ".hg", "__pycache__", ".pytest_cache", ".mypy_cache",
63
+ "node_modules", ".venv", "venv", "env", "build", "dist", ".idea", ".vscode"
64
+ }
65
+
66
+ @classmethod
67
+ def get_system_platform(cls) -> SystemPlatform:
68
+ return SystemPlatform.current()
69
+
70
+ @classmethod
71
+ def get_hardware_metrics(cls) -> Tuple[float, float, int]:
72
+ """Returns (total_ram_gb, available_ram_gb, cpu_cores)."""
73
+ cores = os.cpu_count() or 1
74
+ total_ram = 8.0
75
+ avail_ram = 4.0
76
+
77
+ # Try psutil if available, otherwise fallback to OS-native probes
78
+ try:
79
+ import psutil
80
+ mem = psutil.virtual_memory()
81
+ total_ram = round(mem.total / (1024 ** 3), 2)
82
+ avail_ram = round(mem.available / (1024 ** 3), 2)
83
+ return total_ram, avail_ram, cores
84
+ except Exception:
85
+ pass
86
+
87
+ # Native OS fallback
88
+ plat = cls.get_system_platform()
89
+ if plat == SystemPlatform.WINDOWS:
90
+ try:
91
+ import ctypes
92
+ class MEMORYSTATUSEX(ctypes.Structure):
93
+ _fields_ = [
94
+ ("dwLength", ctypes.c_ulong),
95
+ ("dwMemoryLoad", ctypes.c_ulong),
96
+ ("ullTotalPhys", ctypes.c_ulonglong),
97
+ ("ullAvailPhys", ctypes.c_ulonglong),
98
+ ("ullTotalPageFile", ctypes.c_ulonglong),
99
+ ("ullAvailPageFile", ctypes.c_ulonglong),
100
+ ("ullTotalVirtual", ctypes.c_ulonglong),
101
+ ("ullAvailVirtual", ctypes.c_ulonglong),
102
+ ("sullAvailExtendedVirtual", ctypes.c_ulonglong),
103
+ ]
104
+ stat = MEMORYSTATUSEX()
105
+ stat.dwLength = ctypes.sizeof(MEMORYSTATUSEX)
106
+ if ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat)):
107
+ total_ram = round(stat.ullTotalPhys / (1024 ** 3), 2)
108
+ avail_ram = round(stat.ullAvailPhys / (1024 ** 3), 2)
109
+ except Exception:
110
+ pass
111
+ elif plat == SystemPlatform.LINUX:
112
+ try:
113
+ with open("/proc/meminfo", "r") as f:
114
+ meminfo = f.read()
115
+ t_match = re.search(r"MemTotal:\s+(\d+)\s+kB", meminfo)
116
+ a_match = re.search(r"MemAvailable:\s+(\d+)\s+kB", meminfo)
117
+ if t_match:
118
+ total_ram = round(int(t_match.group(1)) / (1024 ** 2), 2)
119
+ if a_match:
120
+ avail_ram = round(int(a_match.group(1)) / (1024 ** 2), 2)
121
+ except Exception:
122
+ pass
123
+
124
+ return total_ram, avail_ram, cores
125
+
126
+ @classmethod
127
+ def probe_tool(cls, name: str, min_version: str = "0.0.0", purpose: str = "") -> ToolStatus:
128
+ """Probe executable existence, PATH location, and version string."""
129
+ binary_path = shutil.which(name)
130
+ if not binary_path:
131
+ return ToolStatus(
132
+ name=name,
133
+ available=False,
134
+ executable_path=None,
135
+ version_str=None,
136
+ is_compatible=False,
137
+ notes=f"'{name}' executable not found on system PATH ({purpose})"
138
+ )
139
+
140
+ # Probe version with fast flags
141
+ version_str = None
142
+ for flag in ["--version", "-v"]:
143
+ try:
144
+ proc = subprocess.run(
145
+ [binary_path, flag],
146
+ stdout=subprocess.PIPE,
147
+ stderr=subprocess.PIPE,
148
+ text=True,
149
+ timeout=0.5
150
+ )
151
+ raw_out = (proc.stdout or proc.stderr or "").strip()
152
+ if raw_out:
153
+ match = re.search(r"(\d+\.\d+(\.\d+)?)", raw_out)
154
+ if match:
155
+ version_str = match.group(1)
156
+ break
157
+ except Exception:
158
+ continue
159
+
160
+ is_compatible = True
161
+ notes = f"Located at {binary_path}"
162
+ if version_str:
163
+ notes += f" (detected v{version_str})"
164
+
165
+ return ToolStatus(
166
+ name=name,
167
+ available=True,
168
+ executable_path=binary_path,
169
+ version_str=version_str,
170
+ is_compatible=is_compatible,
171
+ notes=notes
172
+ )
173
+
174
+ _TOOL_CACHE: Dict[str, ToolStatus] = {}
175
+
176
+ @classmethod
177
+ def probe_all_tools(cls, use_cache: bool = True) -> Dict[str, ToolStatus]:
178
+ """Run deep toolchain detection across critical and secondary developer tools."""
179
+ if use_cache and cls._TOOL_CACHE:
180
+ return cls._TOOL_CACHE
181
+ res = {}
182
+ for name, min_v, purp in cls.CRITICAL_TOOLS:
183
+ res[name] = cls.probe_tool(name, min_v, purp)
184
+ for name, min_v, purp in cls.SECONDARY_TOOLS:
185
+ res[name] = cls.probe_tool(name, min_v, purp)
186
+ cls._TOOL_CACHE = res
187
+ return res
188
+
189
+ @classmethod
190
+ def check_windows_registry_settings(cls) -> List[DiagnosticIssue]:
191
+ """Inspect critical Windows registry settings (LongPathsEnabled, Python shims)."""
192
+ issues: List[DiagnosticIssue] = []
193
+ if cls.get_system_platform() != SystemPlatform.WINDOWS:
194
+ return issues
195
+
196
+ try:
197
+ import winreg
198
+ # Check LongPathsEnabled
199
+ try:
200
+ key = winreg.OpenKey(
201
+ winreg.HKEY_LOCAL_MACHINE,
202
+ r"SYSTEM\CurrentControlSet\Control\FileSystem",
203
+ 0,
204
+ winreg.KEY_READ
205
+ )
206
+ val, _ = winreg.QueryValueEx(key, "LongPathsEnabled")
207
+ winreg.CloseKey(key)
208
+ if val != 1:
209
+ issues.append(DiagnosticIssue(
210
+ category=DiagnosticCategory.ENVIRONMENT.value,
211
+ severity=SeverityLevel.WARNING.value,
212
+ file_path="HKLM\\SYSTEM\\CurrentControlSet\\Control\\FileSystem\\LongPathsEnabled",
213
+ line=None,
214
+ column=None,
215
+ error_code="TZ-ENV-WIN-LONGPATH",
216
+ message="Windows 260-character MAX_PATH limit is active (LongPathsEnabled is 0)",
217
+ suggested_fix="Enable NTFS LongPaths via registry or group policy to prevent deep directory build failures",
218
+ auto_fixable=False,
219
+ metadata={"current_value": val}
220
+ ))
221
+ except Exception:
222
+ pass
223
+ except Exception:
224
+ pass
225
+
226
+ return issues
227
+
228
+ @classmethod
229
+ def check_path_environment(cls) -> List[DiagnosticIssue]:
230
+ """Check system PATH for invalid directories, dead shims, and redundant entries."""
231
+ issues: List[DiagnosticIssue] = []
232
+ raw_path = os.environ.get("PATH", "")
233
+ delimiter = ";" if cls.get_system_platform() == SystemPlatform.WINDOWS else ":"
234
+ entries = raw_path.split(delimiter)
235
+
236
+ seen_entries: Set[str] = set()
237
+ for idx, entry in enumerate(entries, start=1):
238
+ cleaned = entry.strip()
239
+ if not cleaned:
240
+ continue
241
+
242
+ # Normalized path
243
+ norm = os.path.normcase(os.path.abspath(cleaned))
244
+ if norm in seen_entries:
245
+ issues.append(DiagnosticIssue(
246
+ category=DiagnosticCategory.ENVIRONMENT.value,
247
+ severity=SeverityLevel.INFO.value,
248
+ file_path=None,
249
+ line=idx,
250
+ column=None,
251
+ error_code="TZ-ENV-PATH-DUP",
252
+ message=f"Duplicate PATH entry detected: '{cleaned}'",
253
+ suggested_fix="Deduplicate PATH variable to speed up binary resolution",
254
+ auto_fixable=False,
255
+ metadata={"path_entry": cleaned}
256
+ ))
257
+ else:
258
+ seen_entries.add(norm)
259
+
260
+ # Check if directory exists on disk
261
+ if not os.path.isdir(cleaned):
262
+ issues.append(DiagnosticIssue(
263
+ category=DiagnosticCategory.ENVIRONMENT.value,
264
+ severity=SeverityLevel.WARNING.value,
265
+ file_path=None,
266
+ line=idx,
267
+ column=None,
268
+ error_code="TZ-ENV-PATH-DEAD",
269
+ message=f"Dead / non-existent directory on system PATH: '{cleaned}'",
270
+ suggested_fix="Remove non-existent directory from PATH environment variable",
271
+ auto_fixable=False,
272
+ metadata={"path_entry": cleaned}
273
+ ))
274
+
275
+ return issues
276
+
277
+ @classmethod
278
+ def check_file_locks_and_permissions(cls, workspace_dir: str = ".") -> List[DiagnosticIssue]:
279
+ """Inspect workspace files for exclusive file locks, read-only bits, and stale git locks."""
280
+ issues: List[DiagnosticIssue] = []
281
+ root = Path(workspace_dir).resolve()
282
+
283
+ # 1. Stale Git Lock check
284
+ git_dir = root / ".git"
285
+ if git_dir.is_dir():
286
+ lock_candidates = [
287
+ git_dir / "index.lock",
288
+ git_dir / "HEAD.lock",
289
+ git_dir / "config.lock",
290
+ ]
291
+ for lock_f in lock_candidates:
292
+ if lock_f.is_file():
293
+ age_sec = time.time() - os.path.getmtime(lock_f)
294
+ if age_sec > 180: # Older than 3 minutes
295
+ issues.append(DiagnosticIssue(
296
+ category=DiagnosticCategory.CACHE.value,
297
+ severity=SeverityLevel.WARNING.value,
298
+ file_path=str(lock_f),
299
+ line=None,
300
+ column=None,
301
+ error_code="TZ-LOCK-GIT-STALE",
302
+ message=f"Stale git lockfile '{lock_f.name}' detected ({int(age_sec)}s old) blocking git commits",
303
+ suggested_fix=f"Purge stale lockfile '{lock_f.name}'",
304
+ auto_fixable=True,
305
+ metadata={"action": "remove_file", "path": str(lock_f)}
306
+ ))
307
+
308
+ # 2. Check read-only flags on source files (common Windows bug after git checkout)
309
+ for root_dir, dirs, files in os.walk(str(root)):
310
+ dirs[:] = [d for d in dirs if d not in cls.IGNORED_DIRS]
311
+ for file in files:
312
+ if file.endswith((".py", ".json", ".md", ".toml", ".yaml", ".ts", ".js")):
313
+ full_p = os.path.join(root_dir, file)
314
+ # Check write permission
315
+ if not os.access(full_p, os.W_OK):
316
+ issues.append(DiagnosticIssue(
317
+ category=DiagnosticCategory.ENVIRONMENT.value,
318
+ severity=SeverityLevel.ERROR.value,
319
+ file_path=full_p,
320
+ line=None,
321
+ column=None,
322
+ error_code="TZ-FS-READONLY",
323
+ message=f"Source file '{file}' is marked read-only / write protected",
324
+ suggested_fix=f"Restore write permission (chmod +w / attrib -r)",
325
+ auto_fixable=True,
326
+ metadata={"action": "restore_write_permission", "path": full_p}
327
+ ))
328
+
329
+ return issues
330
+
331
+ @classmethod
332
+ def check_bytecode_and_temp_bloat(cls, workspace_dir: str = ".") -> List[DiagnosticIssue]:
333
+ """Scan for orphaned .pyc files, corrupted __pycache__, and test cache bloat."""
334
+ issues: List[DiagnosticIssue] = []
335
+ root = Path(workspace_dir).resolve()
336
+
337
+ for root_dir, dirs, files in os.walk(str(root)):
338
+ dirs[:] = [d for d in dirs if d not in cls.IGNORED_DIRS or d == "__pycache__"]
339
+ bname = os.path.basename(root_dir)
340
+
341
+ # Check __pycache__ directory
342
+ if bname == "__pycache__":
343
+ parent_p = Path(root_dir).parent
344
+ for file in files:
345
+ if file.endswith(".pyc"):
346
+ base_stem = file.split(".")[0]
347
+ expected_py = parent_p / f"{base_stem}.py"
348
+ full_pyc = os.path.join(root_dir, file)
349
+ if not expected_py.is_file():
350
+ issues.append(DiagnosticIssue(
351
+ category=DiagnosticCategory.CACHE.value,
352
+ severity=SeverityLevel.INFO.value,
353
+ file_path=full_pyc,
354
+ line=None,
355
+ column=None,
356
+ error_code="TZ-CACHE-ORPHAN-PYC",
357
+ message=f"Orphaned bytecode '{file}' has no corresponding source file '{base_stem}.py'",
358
+ suggested_fix="Purge orphaned compiled bytecode",
359
+ auto_fixable=True,
360
+ metadata={"action": "remove_file", "path": full_pyc}
361
+ ))
362
+
363
+ # Check stale coverage or cache files
364
+ if bname in (".pytest_cache", ".ruff_cache", ".mypy_cache"):
365
+ total_size = sum(os.path.getsize(os.path.join(root_dir, f)) for f in files if os.path.isfile(os.path.join(root_dir, f)))
366
+ if total_size > 50 * 1024 * 1024: # > 50MB cache bloat
367
+ issues.append(DiagnosticIssue(
368
+ category=DiagnosticCategory.CACHE.value,
369
+ severity=SeverityLevel.INFO.value,
370
+ file_path=root_dir,
371
+ line=None,
372
+ column=None,
373
+ error_code="TZ-CACHE-BLOAT",
374
+ message=f"Cache directory '{bname}' exceeds 50MB ({total_size // (1024*1024)}MB)",
375
+ suggested_fix="Clear test cache to recover disk space",
376
+ auto_fixable=True,
377
+ metadata={"action": "clean_cache_dir", "path": root_dir}
378
+ ))
379
+
380
+ return issues
381
+
382
+ @classmethod
383
+ def capture_snapshot(cls, workspace_dir: str = ".") -> EnvironmentSnapshot:
384
+ """Capture comprehensive state snapshot of the active host environment."""
385
+ total_ram, avail_ram, cores = cls.get_hardware_metrics()
386
+ tools = cls.probe_all_tools()
387
+ plat = cls.get_system_platform().value
388
+
389
+ py_ver = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
390
+ is_venv = hasattr(sys, "real_prefix") or (hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix)
391
+ venv_root = sys.prefix if is_venv else None
392
+
393
+ arch = "64bit" if sys.maxsize > 2**32 else "32bit"
394
+ temp_dir = tempfile.gettempdir()
395
+
396
+ return EnvironmentSnapshot(
397
+ platform=plat,
398
+ os_release=f"{platform.system()} {platform.release()} ({platform.version()})",
399
+ python_version=py_ver,
400
+ python_executable=sys.executable,
401
+ python_architecture=arch,
402
+ is_virtualenv_active=is_venv,
403
+ virtualenv_root=venv_root,
404
+ virtualenv_valid=True,
405
+ virtualenv_error=None,
406
+ cpu_cores=cores,
407
+ total_ram_gb=total_ram,
408
+ available_ram_gb=avail_ram,
409
+ temp_dir_path=temp_dir,
410
+ tools=tools,
411
+ env_vars_healthy=True
412
+ )
413
+
414
+ @classmethod
415
+ def execute_os_heals(cls, issues: List[DiagnosticIssue], dry_run: bool = False) -> List[HealAction]:
416
+ """Execute autonomous healing on OS, file lock, and cache issues."""
417
+ actions: List[HealAction] = []
418
+
419
+ for issue in issues:
420
+ action_type = issue.metadata.get("action")
421
+ if not issue.auto_fixable or not action_type:
422
+ continue
423
+
424
+ t0 = time.time()
425
+ # 1. Remove file (stale lock or orphaned pyc)
426
+ if action_type == "remove_file":
427
+ p = issue.metadata.get("path") or issue.file_path
428
+ if p and os.path.isfile(p):
429
+ try:
430
+ if not dry_run:
431
+ os.remove(p)
432
+ actions.append(HealAction(
433
+ category=DiagnosticCategory.CACHE.value,
434
+ action_type=action_type,
435
+ file_path=p,
436
+ description=f"Purged {os.path.basename(p)}",
437
+ success=True,
438
+ duration_ms=round((time.time() - t0) * 1000, 2)
439
+ ))
440
+ except Exception as e:
441
+ actions.append(HealAction(
442
+ category=DiagnosticCategory.CACHE.value,
443
+ action_type=action_type,
444
+ file_path=p,
445
+ description=f"Failed purging {os.path.basename(p)}: {e}",
446
+ success=False,
447
+ duration_ms=round((time.time() - t0) * 1000, 2)
448
+ ))
449
+
450
+ # 2. Restore write permission
451
+ elif action_type == "restore_write_permission":
452
+ p = issue.metadata.get("path") or issue.file_path
453
+ if p and os.path.exists(p):
454
+ try:
455
+ if not dry_run:
456
+ import stat
457
+ curr = os.stat(p).st_mode
458
+ os.chmod(p, curr | stat.S_IWRITE | stat.S_IWGRP)
459
+ actions.append(HealAction(
460
+ category=DiagnosticCategory.ENVIRONMENT.value,
461
+ action_type=action_type,
462
+ file_path=p,
463
+ description=f"Restored write permissions on {os.path.basename(p)}",
464
+ success=True,
465
+ duration_ms=round((time.time() - t0) * 1000, 2)
466
+ ))
467
+ except Exception as e:
468
+ actions.append(HealAction(
469
+ category=DiagnosticCategory.ENVIRONMENT.value,
470
+ action_type=action_type,
471
+ file_path=p,
472
+ description=f"Failed restoring permissions: {e}",
473
+ success=False,
474
+ duration_ms=round((time.time() - t0) * 1000, 2)
475
+ ))
476
+
477
+ # 3. Clean bloated cache directory
478
+ elif action_type == "clean_cache_dir":
479
+ p = issue.metadata.get("path") or issue.file_path
480
+ if p and os.path.isdir(p):
481
+ try:
482
+ if not dry_run:
483
+ shutil.rmtree(p, ignore_errors=True)
484
+ actions.append(HealAction(
485
+ category=DiagnosticCategory.CACHE.value,
486
+ action_type=action_type,
487
+ file_path=p,
488
+ description=f"Purged bloated cache directory {os.path.basename(p)}",
489
+ success=True,
490
+ duration_ms=round((time.time() - t0) * 1000, 2)
491
+ ))
492
+ except Exception as e:
493
+ actions.append(HealAction(
494
+ category=DiagnosticCategory.CACHE.value,
495
+ action_type=action_type,
496
+ file_path=p,
497
+ description=f"Failed purging cache directory: {e}",
498
+ success=False,
499
+ duration_ms=round((time.time() - t0) * 1000, 2)
500
+ ))
501
+
502
+ return actions