fixos 2.2.38__tar.gz → 2.2.40__tar.gz

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 (179) hide show
  1. {fixos-2.2.38 → fixos-2.2.40}/CHANGELOG.md +80 -0
  2. {fixos-2.2.38 → fixos-2.2.40}/PKG-INFO +37 -13
  3. {fixos-2.2.38 → fixos-2.2.40}/README.md +37 -13
  4. {fixos-2.2.38 → fixos-2.2.40}/fixos/__init__.py +1 -1
  5. fixos-2.2.40/fixos/__main__.py +7 -0
  6. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/session_handlers.py +16 -8
  7. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/cleanup_cmd.py +117 -19
  8. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/fix_cmd.py +16 -4
  9. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/main.py +28 -4
  10. fixos-2.2.40/fixos/cli/quick_cmd.py +226 -0
  11. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli.py +3 -0
  12. fixos-2.2.40/fixos/diagnostics/__init__.py +4 -0
  13. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/dev_project_analyzer.py +44 -29
  14. fixos-2.2.40/fixos/diagnostics/quick_snapshot.py +827 -0
  15. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/service_cleanup.py +64 -22
  16. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/service_scanner.py +60 -17
  17. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/system_checks.py +5 -5
  18. {fixos-2.2.38 → fixos-2.2.40}/fixos/watch.py +32 -1
  19. {fixos-2.2.38 → fixos-2.2.40}/fixos.egg-info/PKG-INFO +37 -13
  20. {fixos-2.2.38 → fixos-2.2.40}/fixos.egg-info/SOURCES.txt +7 -0
  21. {fixos-2.2.38 → fixos-2.2.40}/pyproject.toml +1 -1
  22. {fixos-2.2.38 → fixos-2.2.40}/setup.py +1 -1
  23. fixos-2.2.40/tests/unit/test_cleanup_cmd.py +87 -0
  24. fixos-2.2.40/tests/unit/test_dev_project_analyzer.py +56 -0
  25. fixos-2.2.40/tests/unit/test_quick_cmd.py +87 -0
  26. fixos-2.2.40/tests/unit/test_quick_snapshot.py +176 -0
  27. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_service_cleanup.py +84 -6
  28. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_service_scanner.py +24 -4
  29. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_system_checks_parallel.py +4 -2
  30. fixos-2.2.38/fixos/diagnostics/__init__.py +0 -3
  31. {fixos-2.2.38 → fixos-2.2.40}/.env.example +0 -0
  32. {fixos-2.2.38 → fixos-2.2.40}/LICENSE +0 -0
  33. {fixos-2.2.38 → fixos-2.2.40}/MANIFEST.in +0 -0
  34. {fixos-2.2.38 → fixos-2.2.40}/docker/README.md +0 -0
  35. {fixos-2.2.38 → fixos-2.2.40}/docker/TEST_RESULTS.md +0 -0
  36. {fixos-2.2.38 → fixos-2.2.40}/docker/TEST_RESULTS_V2.md +0 -0
  37. {fixos-2.2.38 → fixos-2.2.40}/docker/alpine/Dockerfile +0 -0
  38. {fixos-2.2.38 → fixos-2.2.40}/docker/arch/Dockerfile +0 -0
  39. {fixos-2.2.38 → fixos-2.2.40}/docker/base/Dockerfile +0 -0
  40. {fixos-2.2.38 → fixos-2.2.40}/docker/broken-audio/Dockerfile +0 -0
  41. {fixos-2.2.38 → fixos-2.2.40}/docker/broken-full/Dockerfile +0 -0
  42. {fixos-2.2.38 → fixos-2.2.40}/docker/broken-network/Dockerfile +0 -0
  43. {fixos-2.2.38 → fixos-2.2.40}/docker/broken-thumbnails/Dockerfile +0 -0
  44. {fixos-2.2.38 → fixos-2.2.40}/docker/debian/Dockerfile +0 -0
  45. {fixos-2.2.38 → fixos-2.2.40}/docker/docker-compose.multi-system.yml +0 -0
  46. {fixos-2.2.38 → fixos-2.2.40}/docker/docker-compose.yml +0 -0
  47. {fixos-2.2.38 → fixos-2.2.40}/docker/fedora/Dockerfile +0 -0
  48. {fixos-2.2.38 → fixos-2.2.40}/docker/test-multi-system.sh +0 -0
  49. {fixos-2.2.38 → fixos-2.2.40}/docker/test-scenarios.sh +0 -0
  50. {fixos-2.2.38 → fixos-2.2.40}/docker/ubuntu/Dockerfile +0 -0
  51. {fixos-2.2.38 → fixos-2.2.40}/docker/validate-scenario.py +0 -0
  52. {fixos-2.2.38 → fixos-2.2.40}/docs/examples/advanced_usage.py +0 -0
  53. {fixos-2.2.38 → fixos-2.2.40}/docs/examples/quickstart.py +0 -0
  54. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/__init__.py +0 -0
  55. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/autonomous.py +0 -0
  56. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/autonomous_session.py +0 -0
  57. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/hitl.py +0 -0
  58. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/hitl_session.py +0 -0
  59. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/session_core.py +0 -0
  60. {fixos-2.2.38 → fixos-2.2.40}/fixos/agent/session_io.py +0 -0
  61. {fixos-2.2.38 → fixos-2.2.40}/fixos/anonymizer.py +0 -0
  62. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/__init__.py +0 -0
  63. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/_cleanup_flatpak.py +0 -0
  64. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/_cleanup_home.py +0 -0
  65. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/_cleanup_snap.py +0 -0
  66. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/_cleanup_system.py +0 -0
  67. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/_cleanup_utils.py +0 -0
  68. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/ask_cmd.py +0 -0
  69. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/config_cmd.py +0 -0
  70. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/features_cmd.py +0 -0
  71. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/history_cmd.py +0 -0
  72. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/orchestrate_cmd.py +0 -0
  73. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/output_formatter.py +0 -0
  74. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/profile_cmd.py +0 -0
  75. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/projects_cmd.py +0 -0
  76. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/provider_cmd.py +0 -0
  77. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/quickfix_cmd.py +0 -0
  78. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/report_cmd.py +0 -0
  79. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/rollback_cmd.py +0 -0
  80. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/scan_cmd.py +0 -0
  81. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/shared.py +0 -0
  82. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/token_cmd.py +0 -0
  83. {fixos-2.2.38 → fixos-2.2.40}/fixos/cli/watch_cmd.py +0 -0
  84. {fixos-2.2.38 → fixos-2.2.40}/fixos/config.py +0 -0
  85. {fixos-2.2.38 → fixos-2.2.40}/fixos/config_interactive.py +0 -0
  86. {fixos-2.2.38 → fixos-2.2.40}/fixos/constants.py +0 -0
  87. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/_flatpak_analysis_mixin.py +0 -0
  88. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/_flatpak_execution_mixin.py +0 -0
  89. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/_flatpak_recommendations_mixin.py +0 -0
  90. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/_storage_container_mixin.py +0 -0
  91. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/_storage_system_mixin.py +0 -0
  92. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/_storage_user_mixin.py +0 -0
  93. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/cache_discovery.py +0 -0
  94. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/__init__.py +0 -0
  95. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/_shared.py +0 -0
  96. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/audio.py +0 -0
  97. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/file_analysis.py +0 -0
  98. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/hardware.py +0 -0
  99. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/packages.py +0 -0
  100. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/resources.py +0 -0
  101. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/security.py +0 -0
  102. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/storage_optimization.py +0 -0
  103. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/system_core.py +0 -0
  104. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/checks/thumbnails.py +0 -0
  105. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/disk_analyzer.py +0 -0
  106. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/flatpak_analyzer.py +0 -0
  107. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/project_scanner.py +0 -0
  108. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/service_details.py +0 -0
  109. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/storage_analyzer.py +0 -0
  110. {fixos-2.2.38 → fixos-2.2.40}/fixos/diagnostics/utils.py +0 -0
  111. {fixos-2.2.38 → fixos-2.2.40}/fixos/features/__init__.py +0 -0
  112. {fixos-2.2.38 → fixos-2.2.40}/fixos/features/auditor.py +0 -0
  113. {fixos-2.2.38 → fixos-2.2.40}/fixos/features/catalog.py +0 -0
  114. {fixos-2.2.38 → fixos-2.2.40}/fixos/features/installer.py +0 -0
  115. {fixos-2.2.38 → fixos-2.2.40}/fixos/features/profiles.py +0 -0
  116. {fixos-2.2.38 → fixos-2.2.40}/fixos/features/renderer.py +0 -0
  117. {fixos-2.2.38 → fixos-2.2.40}/fixos/fixes/__init__.py +0 -0
  118. {fixos-2.2.38 → fixos-2.2.40}/fixos/interactive/__init__.py +0 -0
  119. {fixos-2.2.38 → fixos-2.2.40}/fixos/interactive/cleanup_planner.py +0 -0
  120. {fixos-2.2.38 → fixos-2.2.40}/fixos/llm_shell.py +0 -0
  121. {fixos-2.2.38 → fixos-2.2.40}/fixos/orchestrator/__init__.py +0 -0
  122. {fixos-2.2.38 → fixos-2.2.40}/fixos/orchestrator/executor.py +0 -0
  123. {fixos-2.2.38 → fixos-2.2.40}/fixos/orchestrator/graph.py +0 -0
  124. {fixos-2.2.38 → fixos-2.2.40}/fixos/orchestrator/orchestrator.py +0 -0
  125. {fixos-2.2.38 → fixos-2.2.40}/fixos/orchestrator/rollback.py +0 -0
  126. {fixos-2.2.38 → fixos-2.2.40}/fixos/platform_utils.py +0 -0
  127. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/__init__.py +0 -0
  128. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/base.py +0 -0
  129. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/__init__.py +0 -0
  130. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/audio.py +0 -0
  131. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/disk.py +0 -0
  132. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/hardware.py +0 -0
  133. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/resources.py +0 -0
  134. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/security.py +0 -0
  135. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/builtin/thumbnails.py +0 -0
  136. {fixos-2.2.38 → fixos-2.2.40}/fixos/plugins/registry.py +0 -0
  137. {fixos-2.2.38 → fixos-2.2.40}/fixos/profiles/__init__.py +0 -0
  138. {fixos-2.2.38 → fixos-2.2.40}/fixos/providers/__init__.py +0 -0
  139. {fixos-2.2.38 → fixos-2.2.40}/fixos/providers/llm.py +0 -0
  140. {fixos-2.2.38 → fixos-2.2.40}/fixos/providers/llm_analyzer.py +0 -0
  141. {fixos-2.2.38 → fixos-2.2.40}/fixos/providers/schemas.py +0 -0
  142. {fixos-2.2.38 → fixos-2.2.40}/fixos/system_checks.py +0 -0
  143. {fixos-2.2.38 → fixos-2.2.40}/fixos/utils/__init__.py +0 -0
  144. {fixos-2.2.38 → fixos-2.2.40}/fixos/utils/anonymizer.py +0 -0
  145. {fixos-2.2.38 → fixos-2.2.40}/fixos/utils/terminal.py +0 -0
  146. {fixos-2.2.38 → fixos-2.2.40}/fixos/utils/timeout.py +0 -0
  147. {fixos-2.2.38 → fixos-2.2.40}/fixos/utils/web_search.py +0 -0
  148. {fixos-2.2.38 → fixos-2.2.40}/fixos.egg-info/dependency_links.txt +0 -0
  149. {fixos-2.2.38 → fixos-2.2.40}/fixos.egg-info/entry_points.txt +0 -0
  150. {fixos-2.2.38 → fixos-2.2.40}/fixos.egg-info/requires.txt +0 -0
  151. {fixos-2.2.38 → fixos-2.2.40}/fixos.egg-info/top_level.txt +0 -0
  152. {fixos-2.2.38 → fixos-2.2.40}/pytest.ini +0 -0
  153. {fixos-2.2.38 → fixos-2.2.40}/requirements-dev.txt +0 -0
  154. {fixos-2.2.38 → fixos-2.2.40}/requirements.txt +0 -0
  155. {fixos-2.2.38 → fixos-2.2.40}/scripts/pyqual-calibrate.py +0 -0
  156. {fixos-2.2.38 → fixos-2.2.40}/setup.cfg +0 -0
  157. {fixos-2.2.38 → fixos-2.2.40}/tests/__init__.py +0 -0
  158. {fixos-2.2.38 → fixos-2.2.40}/tests/conftest.py +0 -0
  159. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/__init__.py +0 -0
  160. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_anonymization_layers.py +0 -0
  161. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_audio_broken.py +0 -0
  162. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_cli.py +0 -0
  163. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_diagnostics_integration.py +0 -0
  164. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_executor.py +0 -0
  165. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_multi_system.py +0 -0
  166. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_network_broken.py +0 -0
  167. {fixos-2.2.38 → fixos-2.2.40}/tests/e2e/test_thumbnails_broken.py +0 -0
  168. {fixos-2.2.38 → fixos-2.2.40}/tests/test_fixos.py +0 -0
  169. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/__init__.py +0 -0
  170. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_anonymizer.py +0 -0
  171. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_cache_discovery.py +0 -0
  172. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_core.py +0 -0
  173. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_executor.py +0 -0
  174. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_llm_provider.py +0 -0
  175. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_orchestrator.py +0 -0
  176. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_project_scanner.py +0 -0
  177. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_projects_cmd.py +0 -0
  178. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_resources_quick.py +0 -0
  179. {fixos-2.2.38 → fixos-2.2.40}/tests/unit/test_security_quick.py +0 -0
@@ -1,3 +1,83 @@
1
+ ## [Unreleased]
2
+
3
+ ### Added
4
+
5
+ - `fixos quick`: ograniczona czasowo analiza heurystyczna bez LLM, która od razu
6
+ pokazuje presję CPU/RAM/dysku i maksymalny rozmiar jawnie odtwarzalnych cache.
7
+ - Lokalna historia szybkich próbek z porównaniem ostatnich godzin i bieżącego
8
+ dnia oraz alarmami o szybkim wzroście dysku, RAM, swapu lub obciążenia CPU.
9
+ - Rozpoznawanie systemu, profilu użytkownika i stosu technologicznego oraz
10
+ opcjonalne przejście do wolniejszej analizy przez `fixos quick --deep`.
11
+
12
+ ### Fixed
13
+
14
+ - Tryb `fixos cleanup` → „Wybierz pojedyncze” przechodzi teraz kolejno przez
15
+ wszystkie usługi: bezpieczne, wymagające przeglądu i chronione. Pozycje bez
16
+ bezpiecznej operacji zbiorczej pokazują komendę podglądu, dane chronione
17
+ wymagają dodatkowego potwierdzenia, a wykonanie jest przypięte do dokładnie
18
+ wybranej ścieżki i poziomu ryzyka.
19
+ - Skany cache npm, pnpm, Yarn, Maven i uv obejmują teraz wyłącznie
20
+ odtwarzalne katalogi. `~/.local/share/uv` (narzędzia, interpretery i
21
+ credentials) oraz `.tools` pnpm nie są już błędnie liczone jako bezpieczne
22
+ cache; czyszczenie npm faktycznie obejmuje raportowane `_npx`.
23
+ - Naprawiono scenariusze TestQL i dodano punkt wejścia `python -m fixos`.
24
+ `cleanup -c <chroniona-usługa> --dry-run` pokazuje bezpieczną komendę
25
+ diagnostyczną zamiast kończyć się mylącym błędem.
26
+ - Stabilny raport Docker z osobnym rozmiarem aktywnym i odzyskiwalnym oraz
27
+ poprawnym pomiarem przed/po czyszczeniu.
28
+ - Usunięto niebezpieczne zbiorcze komendy kasowania wolumenów Docker i
29
+ wszystkich modeli Ollama.
30
+ - Skrócono domyślną diagnostykę przez równoległe moduły i usunięcie
31
+ rekurencyjnych skanów `/` oraz `/home` z szybkich kontroli.
32
+ - Czyszczenie cache JetBrains trafia w aktualną ścieżkę i wymaga zamknięcia IDE.
33
+
34
+ ## [2.2.40] - 2026-07-23
35
+
36
+ ### Docs
37
+ - Update CHANGELOG.md
38
+ - Update README.md
39
+
40
+ ### Test
41
+ - Update testql-scenarios/generated-cli-tests.testql.toon.yaml
42
+ - Update testql-scenarios/generated-from-pytests.testql.toon.yaml
43
+ - Update tests/unit/test_cleanup_cmd.py
44
+ - Update tests/unit/test_service_cleanup.py
45
+ - Update tests/unit/test_service_scanner.py
46
+
47
+ ### Other
48
+ - Update fixos/__main__.py
49
+ - Update fixos/cli/cleanup_cmd.py
50
+ - Update fixos/diagnostics/quick_snapshot.py
51
+ - Update fixos/diagnostics/service_cleanup.py
52
+ - Update fixos/diagnostics/service_scanner.py
53
+ - Update uv.lock
54
+
55
+ ## [2.2.39] - 2026-07-23
56
+
57
+ ### Docs
58
+ - Update CHANGELOG.md
59
+ - Update README.md
60
+
61
+ ### Test
62
+ - Update tests/unit/test_dev_project_analyzer.py
63
+ - Update tests/unit/test_quick_cmd.py
64
+ - Update tests/unit/test_quick_snapshot.py
65
+ - Update tests/unit/test_service_scanner.py
66
+ - Update tests/unit/test_system_checks_parallel.py
67
+
68
+ ### Other
69
+ - Update fixos/agent/session_handlers.py
70
+ - Update fixos/cli.py
71
+ - Update fixos/cli/fix_cmd.py
72
+ - Update fixos/cli/main.py
73
+ - Update fixos/cli/quick_cmd.py
74
+ - Update fixos/diagnostics/__init__.py
75
+ - Update fixos/diagnostics/dev_project_analyzer.py
76
+ - Update fixos/diagnostics/quick_snapshot.py
77
+ - Update fixos/diagnostics/service_scanner.py
78
+ - Update fixos/diagnostics/system_checks.py
79
+ - ... and 2 more files
80
+
1
81
  ## [2.2.0] - 2026-04-04
2
82
 
3
83
  ### Summary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fixos
3
- Version: 2.2.38
3
+ Version: 2.2.40
4
4
  Summary: AI-powered Linux/Windows diagnostics and repair – audio, hardware, system issues
5
5
  Home-page: https://github.com/wronai/fixos
6
6
  Author: fixos contributors
@@ -63,11 +63,11 @@ AI-powered OS Diagnostics
63
63
 
64
64
  ## AI Cost Tracking
65
65
 
66
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-2.2.38-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
67
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$4.62-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-37.0h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
66
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-2.2.40-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
67
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$4.85-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-38.2h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
68
68
 
69
- - 🤖 **LLM usage:** $4.6178 (145 commits)
70
- - 👤 **Human dev:** ~$3695 (37.0h @ $100/h, 30min dedup)
69
+ - 🤖 **LLM usage:** $4.8451 (147 commits)
70
+ - 👤 **Human dev:** ~$3817 (38.2h @ $100/h, 30min dedup)
71
71
 
72
72
  Generated on 2026-07-23 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
73
73
 
@@ -98,10 +98,11 @@ z anonimizacją danych, trybem HITL/Autonomous, grafem problemów i 12 providera
98
98
  # 1. Instalacja
99
99
  pip install -e ".[dev]"
100
100
 
101
- # 2. Wybierz provider i pobierz klucz API
102
- fixos llm # lista 12 providerów z linkami
101
+ # 2. Pierwszy lokalny wynik bez LLM
102
+ fixos quick # CPU/RAM/dysk/cache + początek historii
103
103
 
104
- # 3. Zapisz klucz i uruchom
104
+ # 3. Opcjonalnie wybierz provider i uruchom analizę pogłębioną
105
+ fixos llm # lista 12 providerów z linkami
105
106
  fixos token set AIzaSy... # Gemini (darmowy, domyślny)
106
107
  fixos fix
107
108
  ```
@@ -112,6 +113,8 @@ fixos fix
112
113
 
113
114
  ```
114
115
  fixos – ekran powitalny z listą komend i statusem
116
+ fixos quick – szybka analiza bez LLM + historia CPU/RAM/dysku
117
+ fixos quick --deep – szybki wynik, potem pełny skan danych usług
115
118
  fixos fix – diagnoza + sesja naprawcza z AI (HITL)
116
119
  fixos scan – diagnostyka systemu bez AI
117
120
  fixos cleanup – skanuj i czyść dane usług (Docker, npm, pip, ...)
@@ -132,6 +135,15 @@ fixos test-llm – testuj połączenie z LLM
132
135
  ### Przykłady użycia
133
136
 
134
137
  ```bash
138
+ # Wynik w kilka sekund: presja CPU/RAM/dysku, bezpieczne cache i ostatni przyrost
139
+ fixos quick
140
+
141
+ # JSON do monitoringu; porównanie z próbkami z ostatnich 12 godzin
142
+ fixos quick --json --hours 12
143
+
144
+ # Dopiero na żądanie wykonaj kosztowną inwentaryzację usług
145
+ fixos quick --deep
146
+
135
147
  # Tylko diagnostyka audio + zapis do pliku
136
148
  fixos scan --audio --output /tmp/audio-report.json
137
149
 
@@ -166,6 +178,10 @@ fixos projects --dry-run
166
178
  # Napraw audio i thumbnails (HITL – pyta o potwierdzenie)
167
179
  fixos fix --modules audio,thumbnails
168
180
 
181
+ # Domyślny szybki zestaw pomija wielokrotny skan całego katalogu domowego.
182
+ # Pełną inwentaryzację dużych/zdublowanych plików uruchom jawnie:
183
+ fixos fix --modules all
184
+
169
185
  # Tryb autonomiczny (agent sam naprawia, max 5 akcji)
170
186
  fixos fix --mode autonomous --max-fixes 5
171
187
 
@@ -183,6 +199,13 @@ fixos fix --provider groq
183
199
  fixos fix --timeout 1800
184
200
  ```
185
201
 
202
+ `fixos quick` nie wywołuje LLM ani nie przeszukuje całego katalogu domowego.
203
+ Pierwsze uruchomienie zapisuje mały punkt odniesienia w
204
+ `~/.local/state/fixos/quick-history.json`; kolejne pokazują zmianę dysku, RAM,
205
+ swapu i znanych cache w wybranym oknie oraz od początku bieżącego dnia. Kwota
206
+ „bezpieczne cache” obejmuje wyłącznie jawnie odtwarzalne dane. Docker, modele
207
+ AI, rozszerzenia i cache IDE są raportowane osobno jako wymagające decyzji.
208
+
186
209
  ### Przykładowy widok w terminalu (Czyszczenie dysku)
187
210
 
188
211
  Wyjście jest zoptymalizowane pod standardowy Markdown bez nadmiernej ilości symboli Unicode, ułatwiając czytelność i wklejanie:
@@ -234,15 +257,16 @@ Tryb DRY-RUN - żadne akcje nie zostaną wykonane
234
257
 
235
258
  Każda znaleziona usługa jest klasyfikowana do jednej z trzech grup:
236
259
 
237
- - **bezpieczne** – cache do odtworzenia jednym poleceniem (docker/pip/npm/cargo/conda/nix/brew...).
260
+ - **bezpieczne** – cache do odtworzenia jednym poleceniem (pip/npm/cargo/conda/nix/brew...).
238
261
  Jedyna grupa oferowana do automatycznego usunięcia, z menu wyboru: wszystkie / pojedynczo / pomiń.
239
262
  - **do rozważenia** – reinstalowalne aplikacje, dane długo nieużywane, nierozpoznane
240
263
  foldery (JetBrains, Snap, Flatpak) – pokazywane z podpowiedziami, nigdy nie usuwane automatycznie.
241
- - **niebezpieczne** – realne dane aplikacji, nie cache (Ollama, LM Studio, HuggingFace hub,
242
- Docker/Podman/containerd, cała biblioteka Steam, `.cursor/extensions`/`.vscode/extensions`
264
+ - **chronione lub mieszane** – realne dane aplikacji albo magazyny łączące dane aktywne
265
+ z cache (Ollama, LM Studio, HuggingFace hub, Docker/Podman/containerd, cała biblioteka
266
+ Steam, `.cursor/extensions`/`.vscode/extensions`
243
267
  – zainstalowane rozszerzenia edytora, nie ich cache). Osobna sekcja z ostrzeżeniem;
244
- usunięcie pojedynczej usługi (`fixos cleanup -c <usluga>`) wymaga dodatkowego
245
- potwierdzenia z jawnym opisem ryzyka.
268
+ zbiorcze kasowanie modeli i wolumenów jest wyłączone. Docker pokazuje osobno
269
+ `SIZE` i `RECLAIMABLE`; domyślne czyszczenie ogranicza się do starego cache buildów.
246
270
 
247
271
  ### `fixos projects` – skaner artefaktów w projektach deweloperskich
248
272
 
@@ -19,11 +19,11 @@ AI-powered OS Diagnostics
19
19
 
20
20
  ## AI Cost Tracking
21
21
 
22
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-2.2.38-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
23
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$4.62-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-37.0h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
22
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-2.2.40-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
23
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$4.85-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-38.2h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
24
24
 
25
- - 🤖 **LLM usage:** $4.6178 (145 commits)
26
- - 👤 **Human dev:** ~$3695 (37.0h @ $100/h, 30min dedup)
25
+ - 🤖 **LLM usage:** $4.8451 (147 commits)
26
+ - 👤 **Human dev:** ~$3817 (38.2h @ $100/h, 30min dedup)
27
27
 
28
28
  Generated on 2026-07-23 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
29
29
 
@@ -54,10 +54,11 @@ z anonimizacją danych, trybem HITL/Autonomous, grafem problemów i 12 providera
54
54
  # 1. Instalacja
55
55
  pip install -e ".[dev]"
56
56
 
57
- # 2. Wybierz provider i pobierz klucz API
58
- fixos llm # lista 12 providerów z linkami
57
+ # 2. Pierwszy lokalny wynik bez LLM
58
+ fixos quick # CPU/RAM/dysk/cache + początek historii
59
59
 
60
- # 3. Zapisz klucz i uruchom
60
+ # 3. Opcjonalnie wybierz provider i uruchom analizę pogłębioną
61
+ fixos llm # lista 12 providerów z linkami
61
62
  fixos token set AIzaSy... # Gemini (darmowy, domyślny)
62
63
  fixos fix
63
64
  ```
@@ -68,6 +69,8 @@ fixos fix
68
69
 
69
70
  ```
70
71
  fixos – ekran powitalny z listą komend i statusem
72
+ fixos quick – szybka analiza bez LLM + historia CPU/RAM/dysku
73
+ fixos quick --deep – szybki wynik, potem pełny skan danych usług
71
74
  fixos fix – diagnoza + sesja naprawcza z AI (HITL)
72
75
  fixos scan – diagnostyka systemu bez AI
73
76
  fixos cleanup – skanuj i czyść dane usług (Docker, npm, pip, ...)
@@ -88,6 +91,15 @@ fixos test-llm – testuj połączenie z LLM
88
91
  ### Przykłady użycia
89
92
 
90
93
  ```bash
94
+ # Wynik w kilka sekund: presja CPU/RAM/dysku, bezpieczne cache i ostatni przyrost
95
+ fixos quick
96
+
97
+ # JSON do monitoringu; porównanie z próbkami z ostatnich 12 godzin
98
+ fixos quick --json --hours 12
99
+
100
+ # Dopiero na żądanie wykonaj kosztowną inwentaryzację usług
101
+ fixos quick --deep
102
+
91
103
  # Tylko diagnostyka audio + zapis do pliku
92
104
  fixos scan --audio --output /tmp/audio-report.json
93
105
 
@@ -122,6 +134,10 @@ fixos projects --dry-run
122
134
  # Napraw audio i thumbnails (HITL – pyta o potwierdzenie)
123
135
  fixos fix --modules audio,thumbnails
124
136
 
137
+ # Domyślny szybki zestaw pomija wielokrotny skan całego katalogu domowego.
138
+ # Pełną inwentaryzację dużych/zdublowanych plików uruchom jawnie:
139
+ fixos fix --modules all
140
+
125
141
  # Tryb autonomiczny (agent sam naprawia, max 5 akcji)
126
142
  fixos fix --mode autonomous --max-fixes 5
127
143
 
@@ -139,6 +155,13 @@ fixos fix --provider groq
139
155
  fixos fix --timeout 1800
140
156
  ```
141
157
 
158
+ `fixos quick` nie wywołuje LLM ani nie przeszukuje całego katalogu domowego.
159
+ Pierwsze uruchomienie zapisuje mały punkt odniesienia w
160
+ `~/.local/state/fixos/quick-history.json`; kolejne pokazują zmianę dysku, RAM,
161
+ swapu i znanych cache w wybranym oknie oraz od początku bieżącego dnia. Kwota
162
+ „bezpieczne cache” obejmuje wyłącznie jawnie odtwarzalne dane. Docker, modele
163
+ AI, rozszerzenia i cache IDE są raportowane osobno jako wymagające decyzji.
164
+
142
165
  ### Przykładowy widok w terminalu (Czyszczenie dysku)
143
166
 
144
167
  Wyjście jest zoptymalizowane pod standardowy Markdown bez nadmiernej ilości symboli Unicode, ułatwiając czytelność i wklejanie:
@@ -190,15 +213,16 @@ Tryb DRY-RUN - żadne akcje nie zostaną wykonane
190
213
 
191
214
  Każda znaleziona usługa jest klasyfikowana do jednej z trzech grup:
192
215
 
193
- - **bezpieczne** – cache do odtworzenia jednym poleceniem (docker/pip/npm/cargo/conda/nix/brew...).
216
+ - **bezpieczne** – cache do odtworzenia jednym poleceniem (pip/npm/cargo/conda/nix/brew...).
194
217
  Jedyna grupa oferowana do automatycznego usunięcia, z menu wyboru: wszystkie / pojedynczo / pomiń.
195
218
  - **do rozważenia** – reinstalowalne aplikacje, dane długo nieużywane, nierozpoznane
196
219
  foldery (JetBrains, Snap, Flatpak) – pokazywane z podpowiedziami, nigdy nie usuwane automatycznie.
197
- - **niebezpieczne** – realne dane aplikacji, nie cache (Ollama, LM Studio, HuggingFace hub,
198
- Docker/Podman/containerd, cała biblioteka Steam, `.cursor/extensions`/`.vscode/extensions`
220
+ - **chronione lub mieszane** – realne dane aplikacji albo magazyny łączące dane aktywne
221
+ z cache (Ollama, LM Studio, HuggingFace hub, Docker/Podman/containerd, cała biblioteka
222
+ Steam, `.cursor/extensions`/`.vscode/extensions`
199
223
  – zainstalowane rozszerzenia edytora, nie ich cache). Osobna sekcja z ostrzeżeniem;
200
- usunięcie pojedynczej usługi (`fixos cleanup -c <usluga>`) wymaga dodatkowego
201
- potwierdzenia z jawnym opisem ryzyka.
224
+ zbiorcze kasowanie modeli i wolumenów jest wyłączone. Docker pokazuje osobno
225
+ `SIZE` i `RECLAIMABLE`; domyślne czyszczenie ogranicza się do starego cache buildów.
202
226
 
203
227
  ### `fixos projects` – skaner artefaktów w projektach deweloperskich
204
228
 
@@ -567,4 +591,4 @@ Licensed under Apache-2.0.
567
591
  Tom Sapletta
568
592
  ## life is life
569
593
 
570
- ![img.png](img.png)
594
+ ![img.png](img.png)
@@ -1,3 +1,3 @@
1
1
  """fixos – AI-powered Linux/Windows diagnostics and repair."""
2
2
 
3
- __version__ = "2.2.38"
3
+ __version__ = "2.2.40"
@@ -0,0 +1,7 @@
1
+ """Allow running fixOS as ``python -m fixos``."""
2
+
3
+ from fixos.cli import main
4
+
5
+
6
+ if __name__ == "__main__":
7
+ main()
@@ -134,14 +134,18 @@ def handle_execute_all(fixes: list, messages: list, executed: list, run_cmd_fn)
134
134
  executed.append(result)
135
135
  anon_out, _ = anonymize(result.stdout + result.stderr)
136
136
  status = "✅ sukces" if result.ok else f"❌ błąd (kod {result.returncode})"
137
- summary_lines.append(f"- `{cmd}`: {status}")
137
+ summary = f"- `{cmd}`: {status}"
138
+ if anon_out.strip():
139
+ summary += f"\n Output: {anon_out.strip()[:MAX_ANON_PREVIEW_LENGTH]}"
140
+ summary_lines.append(summary)
138
141
 
142
+ joined_summary = "\n".join(summary_lines)
139
143
  messages.append(
140
144
  {
141
145
  "role": "user",
142
146
  "content": (
143
147
  f"Executed all commands:\n"
144
- f"{'\n'.join(summary_lines)}\n"
148
+ f"{joined_summary}\n"
145
149
  f"\nEvaluate results and suggest next steps."
146
150
  ),
147
151
  }
@@ -318,15 +322,19 @@ def parse_user_input(
318
322
 
319
323
  # [N] Execute specific fix by number
320
324
  if user_in.isdigit():
321
- return handle_fix_by_number(
322
- user_in, fixes, messages, executed, run_single_command
323
- ), True
325
+ return (
326
+ handle_fix_by_number(
327
+ user_in, fixes, messages, executed, run_single_command
328
+ ),
329
+ True,
330
+ )
324
331
 
325
332
  # [!cmd] Direct command execution
326
333
  if user_in.startswith("!"):
327
- return handle_direct_command(
328
- user_in, messages, executed, run_single_command
329
- ), True
334
+ return (
335
+ handle_direct_command(user_in, messages, executed, run_single_command),
336
+ True,
337
+ )
330
338
 
331
339
  # [search <q>] Web search
332
340
  if lo.startswith("search "):
@@ -79,9 +79,7 @@ def _display_service_item(svc: dict) -> None:
79
79
  risk = svc.get("risk_level") or ("safe" if svc["safe_to_cleanup"] else "review")
80
80
  safe_text, safe_color = _RISK_LABELS.get(risk, _RISK_LABELS["review"])
81
81
 
82
- click.echo(
83
- f" {click.style(svc['name'], fg='yellow', bold=True)} - {size_str}"
84
- )
82
+ click.echo(f" {click.style(svc['name'], fg='yellow', bold=True)} - {size_str}")
85
83
  click.echo(f" {svc['description']}")
86
84
  paths = svc.get("details", {}).get("paths") or [svc["path"]]
87
85
  if len(paths) > 1:
@@ -90,7 +88,9 @@ def _display_service_item(svc: dict) -> None:
90
88
  click.echo(f" • {path}")
91
89
  else:
92
90
  click.echo(f" Ścieżka: {svc['path']}")
93
- click.echo(f" {click.style(safe_text, fg=safe_color, bold=(risk == 'dangerous'))}")
91
+ click.echo(
92
+ f" {click.style(safe_text, fg=safe_color, bold=(risk == 'dangerous'))}"
93
+ )
94
94
 
95
95
  # Show details for specific services
96
96
  if svc.get("details"):
@@ -134,7 +134,11 @@ def _execute_safe_cleanup(services: list, scanner) -> float:
134
134
  for svc in services:
135
135
  svc_type = svc["service_type"]
136
136
  click.echo(f"Czyszczenie {svc_type}...")
137
- result = scanner.cleanup_service(svc_type, dry_run=False)
137
+ result = scanner.cleanup_service(
138
+ svc_type,
139
+ dry_run=False,
140
+ planned_service=svc,
141
+ )
138
142
  if result["success"]:
139
143
  freed = result.get("space_freed_gb", 0)
140
144
  total_freed += freed
@@ -327,7 +331,9 @@ def _cleanup_single_service(
327
331
  bold=True,
328
332
  )
329
333
  )
330
- click.echo(f" Podgląd bez usuwania: fixos cleanup -c {service_name} --dry-run")
334
+ click.echo(
335
+ f" Podgląd bez usuwania: fixos cleanup -c {service_name} --dry-run"
336
+ )
331
337
  if not click.confirm(f"Na pewno usunąć dane usługi {service_name}?"):
332
338
  click.echo("Anulowano.")
333
339
  return
@@ -340,7 +346,9 @@ def _cleanup_single_service(
340
346
 
341
347
  if result["success"]:
342
348
  if dry_run:
343
- click.echo(click.style(f"Symulacja dla {service_name} zakończona", fg="green"))
349
+ click.echo(
350
+ click.style(f"Symulacja dla {service_name} zakończona", fg="green")
351
+ )
344
352
  if result.get("output"):
345
353
  click.echo(f" {result['output']}")
346
354
  if result["space_freed_gb"] > 0:
@@ -349,7 +357,9 @@ def _cleanup_single_service(
349
357
  f"{result['space_freed_gb']:.2f} GB"
350
358
  )
351
359
  else:
352
- click.echo(click.style(f"Zakończono czyszczenie {service_name}", fg="green"))
360
+ click.echo(
361
+ click.style(f"Zakończono czyszczenie {service_name}", fg="green")
362
+ )
353
363
  if result["space_freed_gb"] > 0:
354
364
  click.echo(f" Zwolniono: {result['space_freed_gb']:.2f} GB")
355
365
  else:
@@ -362,11 +372,15 @@ def _cleanup_single_service(
362
372
 
363
373
 
364
374
  def _size_str(svc: dict) -> str:
365
- return f"{svc['size_gb']:.2f} GB" if svc["size_gb"] >= 1 else f"{svc['size_mb']:.0f} MB"
375
+ return (
376
+ f"{svc['size_gb']:.2f} GB"
377
+ if svc["size_gb"] >= 1
378
+ else f"{svc['size_mb']:.0f} MB"
379
+ )
366
380
 
367
381
 
368
- def _select_safe_services(safe_services: list) -> list:
369
- """Ask what to clean from the safe tier: all of it, hand-picked items, or none."""
382
+ def _select_safe_services(safe_services: list) -> tuple[str, list]:
383
+ """Choose bulk-safe cleanup, full individual selection, or no cleanup."""
370
384
  click.echo(click.style("Bezpieczne do wyczyszczenia:", fg="green"))
371
385
  for svc in safe_services:
372
386
  click.echo(f" • {svc['name']}: {_size_str(svc)}")
@@ -375,28 +389,112 @@ def _select_safe_services(safe_services: list) -> list:
375
389
  click.echo()
376
390
  click.echo("Co wyczyścić?")
377
391
  click.echo(f" [1] Wszystkie bezpieczne (zwolni {safe_total:.2f} GB)")
378
- click.echo(" [2] Wybierz pojedyncze usługi")
392
+ click.echo(" [2] Wybierz pojedyncze spośród wszystkich usług")
379
393
  click.echo(" [0] Nic — pomiń")
380
394
  choice = click.prompt(
381
395
  "Wybór", type=click.Choice(["0", "1", "2"]), default="1", show_choices=False
382
396
  )
383
397
 
384
398
  if choice == "0":
385
- return []
399
+ return "none", []
386
400
  if choice == "1":
387
- return safe_services
401
+ return "safe", safe_services
402
+ return "individual", []
388
403
 
389
- click.echo(click.style("Wybierz usługi do wyczyszczenia:", fg="cyan"))
390
- return [svc for svc in safe_services if click.confirm(f" {svc['name']} ({_size_str(svc)})")]
404
+
405
+ def _selection_description(svc: dict) -> str:
406
+ risk = svc.get("risk_level", "review")
407
+ labels = {
408
+ "safe": "bezpieczne cache",
409
+ "review": "do rozważenia",
410
+ "dangerous": "CHRONIONE/mieszane",
411
+ }
412
+ description = labels.get(risk, "do rozważenia")
413
+ if risk == "dangerous" and svc["service_type"] == "docker":
414
+ reclaimable = svc.get("details", {}).get("usage", {}).get("Build Cache", {})
415
+ reclaimable_gb = float(reclaimable.get("reclaimable_gb", 0))
416
+ if reclaimable_gb:
417
+ description += f"; komenda dotyczy do {reclaimable_gb:.2f} GB cache buildów"
418
+ return description
419
+
420
+
421
+ def _select_individual_services(services: list) -> list:
422
+ """Offer every scanned, executable entry in its displayed order."""
423
+ click.echo(
424
+ click.style(
425
+ "Wybierz kolejno spośród wszystkich możliwych usług:",
426
+ fg="cyan",
427
+ )
428
+ )
429
+ selected = []
430
+ for svc in services:
431
+ label = (
432
+ f" {svc['name']} ({_size_str(svc)}) " f"[{_selection_description(svc)}]"
433
+ )
434
+ if not svc.get("can_cleanup") or not svc.get("cleanup_command", "").strip():
435
+ click.echo(f"{label} — brak bezpiecznej operacji zbiorczej")
436
+ preview = svc.get("preview_command")
437
+ if preview:
438
+ click.echo(f" Podgląd: {preview}")
439
+ continue
440
+ if click.confirm(label, default=False):
441
+ selected.append(svc)
442
+ return selected
443
+
444
+
445
+ def _execute_individual_cleanup(services: list, scanner) -> float:
446
+ """Execute hand-picked entries with an extra gate for protected data."""
447
+ total_freed = 0.0
448
+ for svc in services:
449
+ risk = svc.get("risk_level", "review")
450
+ if risk == "dangerous":
451
+ click.echo(
452
+ click.style(
453
+ f"⚠️ {svc['name']} zawiera dane chronione lub mieszane. "
454
+ "Operacji nie da się automatycznie cofnąć.",
455
+ fg="red",
456
+ bold=True,
457
+ )
458
+ )
459
+ if not click.confirm(
460
+ f"Potwierdź wykonanie dokładnie dla: {svc['name']}",
461
+ default=False,
462
+ ):
463
+ click.echo(f" Pominięto {svc['name']}.")
464
+ continue
465
+
466
+ click.echo(f"Czyszczenie {svc['name']}...")
467
+ result = scanner.cleanup_service(
468
+ svc["service_type"],
469
+ dry_run=False,
470
+ planned_service=svc,
471
+ )
472
+ if result["success"]:
473
+ freed = float(result.get("space_freed_gb", 0))
474
+ total_freed += freed
475
+ click.echo(click.style(f" Zwolniono {freed:.2f} GB", fg="green"))
476
+ else:
477
+ click.echo(click.style(f" Błąd: {_error_message(result)}", fg="red"))
478
+ return total_freed
391
479
 
392
480
 
393
481
  def _run_interactive_cleanup(plan: dict, list_only: bool, scanner) -> None:
394
482
  """Offer interactive safe cleanup and display unsafe services."""
395
- if not list_only and plan["safe_to_cleanup"]:
396
- selected = _select_safe_services(plan["safe_to_cleanup"])
483
+ if not list_only and plan["services"]:
484
+ if plan["safe_to_cleanup"]:
485
+ mode, selected = _select_safe_services(plan["safe_to_cleanup"])
486
+ else:
487
+ mode, selected = "individual", []
488
+ if mode == "individual":
489
+ selected = _select_individual_services(plan["services"])
490
+ if selected:
491
+ _execute_individual_cleanup(selected, scanner)
492
+ else:
493
+ click.echo(click.style("Pominięto czyszczenie.", fg="yellow"))
494
+ return
397
495
  if selected:
398
496
  _execute_safe_cleanup(selected, scanner)
399
- else:
497
+ elif mode == "none":
400
498
  click.echo(click.style("Pominięto czyszczenie.", fg="yellow"))
401
499
  if plan["requires_review"] and not list_only:
402
500
  _display_unsafe_services(plan["requires_review"])
@@ -24,16 +24,28 @@ from fixos.constants import (
24
24
  def _collect_diagnostics(
25
25
  modules: str, disc: bool, fmt: OutputFormatter, output: str
26
26
  ) -> dict:
27
- """Run diagnostics collection and optionally disk analysis. Returns data dict."""
27
+ """Run quick-first diagnostics and optionally disk analysis."""
28
28
  selected_modules = modules.split(",") if modules else None
29
+ from fixos.diagnostics.quick_snapshot import collect_quick_snapshot
30
+
31
+ quick_snapshot = collect_quick_snapshot()
32
+ data: dict = {"quick": quick_snapshot}
33
+ if not fmt.is_machine:
34
+ from fixos.cli.quick_cmd import render_quick_snapshot
35
+
36
+ render_quick_snapshot(quick_snapshot)
29
37
 
30
38
  if disc and not modules:
31
- data: dict = {}
39
+ pass
32
40
  else:
33
- fmt.status("\nZbieranie diagnostyki...", fg="yellow")
41
+ fmt.status("\nZbieranie diagnostyki rozszerzonej...", fg="yellow")
34
42
  from fixos.diagnostics import get_full_diagnostics
43
+ from fixos.diagnostics.system_checks import DEFAULT_DIAGNOSTIC_MODULES
35
44
 
36
- data = get_full_diagnostics(selected_modules, progress_callback=fmt.progress)
45
+ diagnostic_modules = selected_modules or list(DEFAULT_DIAGNOSTIC_MODULES)
46
+ data.update(
47
+ get_full_diagnostics(diagnostic_modules, progress_callback=fmt.progress)
48
+ )
37
49
 
38
50
  if disc:
39
51
  from fixos.cli.scan_cmd import _run_disk_analysis