fixos 2.2.38__tar.gz → 2.2.39__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 (177) hide show
  1. {fixos-2.2.38 → fixos-2.2.39}/CHANGELOG.md +47 -0
  2. {fixos-2.2.38 → fixos-2.2.39}/PKG-INFO +37 -13
  3. {fixos-2.2.38 → fixos-2.2.39}/README.md +37 -13
  4. {fixos-2.2.38 → fixos-2.2.39}/fixos/__init__.py +1 -1
  5. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/session_handlers.py +16 -8
  6. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/fix_cmd.py +16 -4
  7. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/main.py +28 -4
  8. fixos-2.2.39/fixos/cli/quick_cmd.py +226 -0
  9. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli.py +3 -0
  10. fixos-2.2.39/fixos/diagnostics/__init__.py +4 -0
  11. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/dev_project_analyzer.py +44 -29
  12. fixos-2.2.39/fixos/diagnostics/quick_snapshot.py +823 -0
  13. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/service_scanner.py +41 -10
  14. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/system_checks.py +5 -5
  15. {fixos-2.2.38 → fixos-2.2.39}/fixos/watch.py +32 -1
  16. {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/PKG-INFO +37 -13
  17. {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/SOURCES.txt +5 -0
  18. {fixos-2.2.38 → fixos-2.2.39}/pyproject.toml +1 -1
  19. {fixos-2.2.38 → fixos-2.2.39}/setup.py +1 -1
  20. fixos-2.2.39/tests/unit/test_dev_project_analyzer.py +56 -0
  21. fixos-2.2.39/tests/unit/test_quick_cmd.py +87 -0
  22. fixos-2.2.39/tests/unit/test_quick_snapshot.py +176 -0
  23. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_service_scanner.py +4 -4
  24. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_system_checks_parallel.py +4 -2
  25. fixos-2.2.38/fixos/diagnostics/__init__.py +0 -3
  26. {fixos-2.2.38 → fixos-2.2.39}/.env.example +0 -0
  27. {fixos-2.2.38 → fixos-2.2.39}/LICENSE +0 -0
  28. {fixos-2.2.38 → fixos-2.2.39}/MANIFEST.in +0 -0
  29. {fixos-2.2.38 → fixos-2.2.39}/docker/README.md +0 -0
  30. {fixos-2.2.38 → fixos-2.2.39}/docker/TEST_RESULTS.md +0 -0
  31. {fixos-2.2.38 → fixos-2.2.39}/docker/TEST_RESULTS_V2.md +0 -0
  32. {fixos-2.2.38 → fixos-2.2.39}/docker/alpine/Dockerfile +0 -0
  33. {fixos-2.2.38 → fixos-2.2.39}/docker/arch/Dockerfile +0 -0
  34. {fixos-2.2.38 → fixos-2.2.39}/docker/base/Dockerfile +0 -0
  35. {fixos-2.2.38 → fixos-2.2.39}/docker/broken-audio/Dockerfile +0 -0
  36. {fixos-2.2.38 → fixos-2.2.39}/docker/broken-full/Dockerfile +0 -0
  37. {fixos-2.2.38 → fixos-2.2.39}/docker/broken-network/Dockerfile +0 -0
  38. {fixos-2.2.38 → fixos-2.2.39}/docker/broken-thumbnails/Dockerfile +0 -0
  39. {fixos-2.2.38 → fixos-2.2.39}/docker/debian/Dockerfile +0 -0
  40. {fixos-2.2.38 → fixos-2.2.39}/docker/docker-compose.multi-system.yml +0 -0
  41. {fixos-2.2.38 → fixos-2.2.39}/docker/docker-compose.yml +0 -0
  42. {fixos-2.2.38 → fixos-2.2.39}/docker/fedora/Dockerfile +0 -0
  43. {fixos-2.2.38 → fixos-2.2.39}/docker/test-multi-system.sh +0 -0
  44. {fixos-2.2.38 → fixos-2.2.39}/docker/test-scenarios.sh +0 -0
  45. {fixos-2.2.38 → fixos-2.2.39}/docker/ubuntu/Dockerfile +0 -0
  46. {fixos-2.2.38 → fixos-2.2.39}/docker/validate-scenario.py +0 -0
  47. {fixos-2.2.38 → fixos-2.2.39}/docs/examples/advanced_usage.py +0 -0
  48. {fixos-2.2.38 → fixos-2.2.39}/docs/examples/quickstart.py +0 -0
  49. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/__init__.py +0 -0
  50. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/autonomous.py +0 -0
  51. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/autonomous_session.py +0 -0
  52. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/hitl.py +0 -0
  53. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/hitl_session.py +0 -0
  54. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/session_core.py +0 -0
  55. {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/session_io.py +0 -0
  56. {fixos-2.2.38 → fixos-2.2.39}/fixos/anonymizer.py +0 -0
  57. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/__init__.py +0 -0
  58. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_flatpak.py +0 -0
  59. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_home.py +0 -0
  60. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_snap.py +0 -0
  61. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_system.py +0 -0
  62. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_utils.py +0 -0
  63. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/ask_cmd.py +0 -0
  64. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/cleanup_cmd.py +0 -0
  65. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/config_cmd.py +0 -0
  66. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/features_cmd.py +0 -0
  67. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/history_cmd.py +0 -0
  68. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/orchestrate_cmd.py +0 -0
  69. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/output_formatter.py +0 -0
  70. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/profile_cmd.py +0 -0
  71. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/projects_cmd.py +0 -0
  72. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/provider_cmd.py +0 -0
  73. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/quickfix_cmd.py +0 -0
  74. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/report_cmd.py +0 -0
  75. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/rollback_cmd.py +0 -0
  76. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/scan_cmd.py +0 -0
  77. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/shared.py +0 -0
  78. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/token_cmd.py +0 -0
  79. {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/watch_cmd.py +0 -0
  80. {fixos-2.2.38 → fixos-2.2.39}/fixos/config.py +0 -0
  81. {fixos-2.2.38 → fixos-2.2.39}/fixos/config_interactive.py +0 -0
  82. {fixos-2.2.38 → fixos-2.2.39}/fixos/constants.py +0 -0
  83. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_flatpak_analysis_mixin.py +0 -0
  84. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_flatpak_execution_mixin.py +0 -0
  85. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_flatpak_recommendations_mixin.py +0 -0
  86. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_storage_container_mixin.py +0 -0
  87. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_storage_system_mixin.py +0 -0
  88. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_storage_user_mixin.py +0 -0
  89. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/cache_discovery.py +0 -0
  90. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/__init__.py +0 -0
  91. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/_shared.py +0 -0
  92. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/audio.py +0 -0
  93. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/file_analysis.py +0 -0
  94. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/hardware.py +0 -0
  95. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/packages.py +0 -0
  96. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/resources.py +0 -0
  97. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/security.py +0 -0
  98. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/storage_optimization.py +0 -0
  99. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/system_core.py +0 -0
  100. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/thumbnails.py +0 -0
  101. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/disk_analyzer.py +0 -0
  102. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/flatpak_analyzer.py +0 -0
  103. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/project_scanner.py +0 -0
  104. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/service_cleanup.py +0 -0
  105. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/service_details.py +0 -0
  106. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/storage_analyzer.py +0 -0
  107. {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/utils.py +0 -0
  108. {fixos-2.2.38 → fixos-2.2.39}/fixos/features/__init__.py +0 -0
  109. {fixos-2.2.38 → fixos-2.2.39}/fixos/features/auditor.py +0 -0
  110. {fixos-2.2.38 → fixos-2.2.39}/fixos/features/catalog.py +0 -0
  111. {fixos-2.2.38 → fixos-2.2.39}/fixos/features/installer.py +0 -0
  112. {fixos-2.2.38 → fixos-2.2.39}/fixos/features/profiles.py +0 -0
  113. {fixos-2.2.38 → fixos-2.2.39}/fixos/features/renderer.py +0 -0
  114. {fixos-2.2.38 → fixos-2.2.39}/fixos/fixes/__init__.py +0 -0
  115. {fixos-2.2.38 → fixos-2.2.39}/fixos/interactive/__init__.py +0 -0
  116. {fixos-2.2.38 → fixos-2.2.39}/fixos/interactive/cleanup_planner.py +0 -0
  117. {fixos-2.2.38 → fixos-2.2.39}/fixos/llm_shell.py +0 -0
  118. {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/__init__.py +0 -0
  119. {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/executor.py +0 -0
  120. {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/graph.py +0 -0
  121. {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/orchestrator.py +0 -0
  122. {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/rollback.py +0 -0
  123. {fixos-2.2.38 → fixos-2.2.39}/fixos/platform_utils.py +0 -0
  124. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/__init__.py +0 -0
  125. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/base.py +0 -0
  126. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/__init__.py +0 -0
  127. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/audio.py +0 -0
  128. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/disk.py +0 -0
  129. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/hardware.py +0 -0
  130. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/resources.py +0 -0
  131. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/security.py +0 -0
  132. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/thumbnails.py +0 -0
  133. {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/registry.py +0 -0
  134. {fixos-2.2.38 → fixos-2.2.39}/fixos/profiles/__init__.py +0 -0
  135. {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/__init__.py +0 -0
  136. {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/llm.py +0 -0
  137. {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/llm_analyzer.py +0 -0
  138. {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/schemas.py +0 -0
  139. {fixos-2.2.38 → fixos-2.2.39}/fixos/system_checks.py +0 -0
  140. {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/__init__.py +0 -0
  141. {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/anonymizer.py +0 -0
  142. {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/terminal.py +0 -0
  143. {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/timeout.py +0 -0
  144. {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/web_search.py +0 -0
  145. {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/dependency_links.txt +0 -0
  146. {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/entry_points.txt +0 -0
  147. {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/requires.txt +0 -0
  148. {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/top_level.txt +0 -0
  149. {fixos-2.2.38 → fixos-2.2.39}/pytest.ini +0 -0
  150. {fixos-2.2.38 → fixos-2.2.39}/requirements-dev.txt +0 -0
  151. {fixos-2.2.38 → fixos-2.2.39}/requirements.txt +0 -0
  152. {fixos-2.2.38 → fixos-2.2.39}/scripts/pyqual-calibrate.py +0 -0
  153. {fixos-2.2.38 → fixos-2.2.39}/setup.cfg +0 -0
  154. {fixos-2.2.38 → fixos-2.2.39}/tests/__init__.py +0 -0
  155. {fixos-2.2.38 → fixos-2.2.39}/tests/conftest.py +0 -0
  156. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/__init__.py +0 -0
  157. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_anonymization_layers.py +0 -0
  158. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_audio_broken.py +0 -0
  159. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_cli.py +0 -0
  160. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_diagnostics_integration.py +0 -0
  161. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_executor.py +0 -0
  162. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_multi_system.py +0 -0
  163. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_network_broken.py +0 -0
  164. {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_thumbnails_broken.py +0 -0
  165. {fixos-2.2.38 → fixos-2.2.39}/tests/test_fixos.py +0 -0
  166. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/__init__.py +0 -0
  167. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_anonymizer.py +0 -0
  168. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_cache_discovery.py +0 -0
  169. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_core.py +0 -0
  170. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_executor.py +0 -0
  171. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_llm_provider.py +0 -0
  172. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_orchestrator.py +0 -0
  173. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_project_scanner.py +0 -0
  174. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_projects_cmd.py +0 -0
  175. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_resources_quick.py +0 -0
  176. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_security_quick.py +0 -0
  177. {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_service_cleanup.py +0 -0
@@ -1,3 +1,50 @@
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
+ - Stabilny raport Docker z osobnym rozmiarem aktywnym i odzyskiwalnym oraz
15
+ poprawnym pomiarem przed/po czyszczeniu.
16
+ - Usunięto niebezpieczne zbiorcze komendy kasowania wolumenów Docker i
17
+ wszystkich modeli Ollama.
18
+ - Skrócono domyślną diagnostykę przez równoległe moduły i usunięcie
19
+ rekurencyjnych skanów `/` oraz `/home` z szybkich kontroli.
20
+ - Czyszczenie cache JetBrains trafia w aktualną ścieżkę i wymaga zamknięcia IDE.
21
+
22
+ ## [2.2.39] - 2026-07-23
23
+
24
+ ### Docs
25
+ - Update CHANGELOG.md
26
+ - Update README.md
27
+
28
+ ### Test
29
+ - Update tests/unit/test_dev_project_analyzer.py
30
+ - Update tests/unit/test_quick_cmd.py
31
+ - Update tests/unit/test_quick_snapshot.py
32
+ - Update tests/unit/test_service_scanner.py
33
+ - Update tests/unit/test_system_checks_parallel.py
34
+
35
+ ### Other
36
+ - Update fixos/agent/session_handlers.py
37
+ - Update fixos/cli.py
38
+ - Update fixos/cli/fix_cmd.py
39
+ - Update fixos/cli/main.py
40
+ - Update fixos/cli/quick_cmd.py
41
+ - Update fixos/diagnostics/__init__.py
42
+ - Update fixos/diagnostics/dev_project_analyzer.py
43
+ - Update fixos/diagnostics/quick_snapshot.py
44
+ - Update fixos/diagnostics/service_scanner.py
45
+ - Update fixos/diagnostics/system_checks.py
46
+ - ... and 2 more files
47
+
1
48
  ## [2.2.0] - 2026-04-04
2
49
 
3
50
  ### Summary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fixos
3
- Version: 2.2.38
3
+ Version: 2.2.39
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.39-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.76-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-38.0h-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.7645 (146 commits)
70
+ - 👤 **Human dev:** ~$3795 (38.0h @ $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.39-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.76-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-38.0h-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.7645 (146 commits)
26
+ - 👤 **Human dev:** ~$3795 (38.0h @ $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.39"
@@ -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 "):
@@ -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
@@ -24,9 +24,9 @@ def cli(ctx, dry_run, version) -> None:
24
24
 
25
25
  \b
26
26
  Szybki start:
27
- fixos token set AIzaSy... # zapisz token Gemini
28
- fixos fix # diagnostyka + naprawa
29
- fixos scan --audio # tylko skan audio
27
+ fixos quick # wynik w kilka sekund, bez LLM
28
+ fixos token set AIzaSy... # opcjonalnie: zapisz token Gemini
29
+ fixos fix # pogłębiona diagnostyka + naprawa
30
30
 
31
31
  \b
32
32
  Polecenia w jezyku naturalnym:
@@ -50,6 +50,7 @@ def cli(ctx, dry_run, version) -> None:
50
50
  def _print_welcome() -> None:
51
51
  """Display welcome screen when no subcommand is specified."""
52
52
  click.echo(click.style(BANNER, fg="cyan"))
53
+ _print_quick_status()
53
54
 
54
55
  cfg = FixOsConfig.load()
55
56
  has_key = bool(cfg.api_key)
@@ -66,11 +67,16 @@ def _print_welcome() -> None:
66
67
  click.echo()
67
68
 
68
69
  commands = [
70
+ ("fixos quick", "", "Szybki wynik bez LLM + trend CPU/RAM/dysku"),
69
71
  ("fixos fix", "", "Diagnostyka + sesja naprawcza z AI (HITL)"),
70
72
  ("fixos scan", "", "Diagnostyka systemu bez AI"),
71
73
  ("fixos quickfix", "", "Naprawy offline bez API (baza znanych bugów)"),
72
74
  ("fixos cleanup", "", "Skanuj i czyść dane usług (Docker, Ollama)"),
73
- ("fixos projects", "", "Skanuj projekty dev (venv, node_modules, ~/github/*/*)"),
75
+ (
76
+ "fixos projects",
77
+ "",
78
+ "Skanuj projekty dev (venv, node_modules, ~/github/*/*)",
79
+ ),
74
80
  ("fixos orchestrate", "", "Zaawansowana orkiestracja napraw (graf problemów)"),
75
81
  ("fixos watch", "", "Monitoring w tle z powiadomieniami"),
76
82
  ("fixos report", "", "Eksport diagnostyki do HTML/Markdown/JSON"),
@@ -148,6 +154,22 @@ def _print_welcome() -> None:
148
154
  click.echo()
149
155
 
150
156
 
157
+ def _print_quick_status() -> None:
158
+ """Best-effort quick result; a welcome screen must never fail on telemetry."""
159
+ try:
160
+ from fixos.cli.quick_cmd import render_quick_snapshot
161
+ from fixos.diagnostics.quick_snapshot import collect_quick_snapshot
162
+
163
+ render_quick_snapshot(collect_quick_snapshot(), compact=True)
164
+ except Exception as exc:
165
+ click.echo(
166
+ click.style(
167
+ f"Szybka analiza chwilowo niedostępna: {exc}",
168
+ fg="yellow",
169
+ )
170
+ )
171
+
172
+
151
173
  def main() -> None:
152
174
  """Entry point for fixOS CLI."""
153
175
  cli()
@@ -170,7 +192,9 @@ from fixos.cli.orchestrate_cmd import orchestrate
170
192
  from fixos.cli.cleanup_cmd import cleanup_services
171
193
  from fixos.cli.projects_cmd import projects_cmd
172
194
  from fixos.cli.features_cmd import features
195
+ from fixos.cli.quick_cmd import quick
173
196
 
197
+ cli.add_command(quick)
174
198
  cli.add_command(rollback)
175
199
  cli.add_command(watch)
176
200
  cli.add_command(profile)
@@ -0,0 +1,226 @@
1
+ """Fast heuristic diagnostics command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ from typing import Any
8
+
9
+ import click
10
+
11
+
12
+ def _human_bytes(value: int | float, *, signed: bool = False) -> str:
13
+ sign = ""
14
+ amount = float(value)
15
+ if signed:
16
+ sign = "+" if amount > 0 else ("−" if amount < 0 else "")
17
+ amount = abs(amount)
18
+ for unit in ("B", "KB", "MB", "GB", "TB"):
19
+ if amount < 1024 or unit == "TB":
20
+ precision = 0 if unit in ("B", "KB") else 2
21
+ return f"{sign}{amount:.{precision}f} {unit}"
22
+ amount /= 1024
23
+ return f"{sign}{amount:.2f} TB"
24
+
25
+
26
+ def render_quick_snapshot(snapshot: dict[str, Any], *, compact: bool = False) -> None:
27
+ """Render the quick snapshot in a stable, readable form."""
28
+ resources = snapshot["resources"]
29
+ context = snapshot["context"]
30
+ safe = snapshot["safe_reclaim"]
31
+ growth = snapshot["growth"]
32
+
33
+ click.echo()
34
+ click.echo(click.style("Szybka analiza lokalna", fg="cyan", bold=True))
35
+ stack = ", ".join(context["tech_stack"]) or "brak wykrytego stosu"
36
+ click.echo(
37
+ f" System: {context['distribution']} · profil {context['profile']} · {stack}"
38
+ )
39
+ click.echo(
40
+ " Zasoby: "
41
+ f"CPU {resources['cpu']['percent']:.0f}% · "
42
+ f"RAM {resources['memory']['percent']:.0f}% · "
43
+ f"dysk {resources['disk']['percent']:.0f}% "
44
+ f"({_human_bytes(resources['disk']['free_bytes'])} wolne)"
45
+ )
46
+ complete_note = "" if safe["measurement_complete"] else " (częściowy pomiar)"
47
+ click.echo(
48
+ click.style(
49
+ f" Bezpieczne cache: do {_human_bytes(safe['estimated_max_bytes'])}"
50
+ f"{complete_note}",
51
+ fg="green",
52
+ bold=True,
53
+ )
54
+ )
55
+
56
+ if not compact:
57
+ for item in safe["items"][:6]:
58
+ if item["size_bytes"] <= 0:
59
+ continue
60
+ click.echo(f" • {item['label']}: {_human_bytes(item['size_bytes'])}")
61
+ incomplete = [
62
+ item["label"]
63
+ for item in safe["items"] + snapshot["review"]
64
+ if not item.get("complete", True)
65
+ ]
66
+ if incomplete:
67
+ click.echo(
68
+ click.style(
69
+ f" Niezmierzone w krótkim budżecie: {', '.join(incomplete)}",
70
+ fg="yellow",
71
+ )
72
+ )
73
+ review = [item for item in snapshot["review"] if item["size_bytes"] > 0]
74
+ if review:
75
+ review_text = ", ".join(
76
+ f"{item['label']} ({_human_bytes(item['size_bytes'])})"
77
+ for item in review[:3]
78
+ )
79
+ click.echo(
80
+ click.style(
81
+ f" Do decyzji: {review_text}",
82
+ fg="yellow",
83
+ )
84
+ )
85
+
86
+ if growth["status"] == "baseline_created":
87
+ click.echo(f" Trend: {growth['message']}")
88
+ else:
89
+ click.echo(
90
+ f" Zmiana od {growth['since']}: "
91
+ f"dysk {_human_bytes(growth['disk_delta_bytes'], signed=True)}, "
92
+ f"RAM {_human_bytes(growth['memory_delta_bytes'], signed=True)}"
93
+ )
94
+ if growth["cache_growth"]:
95
+ labels = {
96
+ item["id"]: item["label"] for item in safe["items"] + snapshot["review"]
97
+ }
98
+ growing = ", ".join(
99
+ f"{labels.get(item['id'], item['id'])} "
100
+ f"{_human_bytes(item['delta_bytes'], signed=True)}"
101
+ for item in growth["cache_growth"][:3]
102
+ )
103
+ click.echo(f" Urosło: {growing}")
104
+ today = growth.get("today", {})
105
+ if (
106
+ not compact
107
+ and today.get("status") == "compared"
108
+ and today.get("since") != growth.get("since")
109
+ ):
110
+ click.echo(
111
+ f" Dzisiaj od {today['since']}: "
112
+ f"dysk {_human_bytes(today['disk_delta_bytes'], signed=True)}, "
113
+ f"RAM {_human_bytes(today['memory_delta_bytes'], signed=True)}"
114
+ )
115
+
116
+ for alert in snapshot["alerts"]:
117
+ color = "red" if alert["severity"] == "critical" else "yellow"
118
+ click.echo(
119
+ click.style(f" {alert['severity'].upper()}: {alert['message']}", fg=color)
120
+ )
121
+ pressured = {
122
+ alert["resource"]
123
+ for alert in snapshot["alerts"]
124
+ if alert["resource"] in {"cpu", "memory"}
125
+ }
126
+ if pressured and resources.get("top_processes"):
127
+ top = ", ".join(
128
+ f"{item['name']} (RAM {item['memory_percent']:.1f}%, "
129
+ f"CPU {item['cpu_percent']:.1f}%)"
130
+ for item in resources["top_processes"][:3]
131
+ )
132
+ click.echo(f" Największe procesy teraz: {top}")
133
+ click.echo(f" Wynik w {snapshot['duration_ms']} ms (bez LLM).")
134
+
135
+
136
+ def _run_deep_analysis() -> dict[str, Any]:
137
+ from fixos.diagnostics.service_scanner import ServiceDataScanner
138
+
139
+ scanner = ServiceDataScanner()
140
+ return scanner.get_cleanup_plan()
141
+
142
+
143
+ def _display_deep_plan(plan: dict[str, Any]) -> None:
144
+ from fixos.cli.cleanup_cmd import _display_cleanup_summary, _display_service_item
145
+ from fixos.constants import DEFAULT_CLEANUP_THRESHOLD_MB
146
+
147
+ _display_cleanup_summary(plan, DEFAULT_CLEANUP_THRESHOLD_MB)
148
+ for service in plan.get("services", []):
149
+ _display_service_item(service)
150
+ click.echo(
151
+ click.style(
152
+ "To był tylko podgląd. Aby wybrać czyszczenie: fixos cleanup",
153
+ fg="cyan",
154
+ )
155
+ )
156
+
157
+
158
+ def _is_interactive_terminal() -> bool:
159
+ return sys.stdin.isatty() and sys.stdout.isatty()
160
+
161
+
162
+ @click.command("quick")
163
+ @click.option(
164
+ "--hours",
165
+ type=click.IntRange(1, 168),
166
+ default=6,
167
+ show_default=True,
168
+ help="Okno historii używane do porównania wzrostu zasobów.",
169
+ )
170
+ @click.option("--json", "json_output", is_flag=True, help="Zwróć wynik jako JSON.")
171
+ @click.option(
172
+ "--deep",
173
+ is_flag=True,
174
+ help="Po szybkim wyniku wykonaj pełny, wolniejszy skan usług i danych.",
175
+ )
176
+ @click.option(
177
+ "--no-save",
178
+ is_flag=True,
179
+ help="Nie zapisuj tego pomiaru w lokalnej historii trendów.",
180
+ )
181
+ def quick(hours: int, json_output: bool, deep: bool, no_save: bool) -> None:
182
+ """Natychmiastowa analiza CPU, RAM, dysku, cache i ostatnich przyrostów.
183
+
184
+ Nie używa LLM i nie skanuje rekurencyjnie całego systemu. Pierwsze
185
+ uruchomienie tworzy punkt odniesienia; kolejne pokazują, co przyrosło.
186
+ """
187
+ from fixos.diagnostics.quick_snapshot import collect_quick_snapshot
188
+
189
+ snapshot = collect_quick_snapshot(hours=hours, save=not no_save)
190
+ if json_output and not deep:
191
+ click.echo(json.dumps(snapshot, ensure_ascii=False, indent=2))
192
+ return
193
+
194
+ if not json_output:
195
+ render_quick_snapshot(snapshot)
196
+
197
+ wants_deep = deep
198
+ if not wants_deep and not json_output and _is_interactive_terminal():
199
+ click.echo()
200
+ wants_deep = click.confirm(
201
+ "Uruchomić teraz analizę głęboką? Może potrwać kilka minut",
202
+ default=False,
203
+ )
204
+
205
+ if wants_deep:
206
+ if not json_output:
207
+ click.echo(click.style("\nUruchamiam analizę głęboką...", fg="yellow"))
208
+ plan = _run_deep_analysis()
209
+ if json_output:
210
+ click.echo(
211
+ json.dumps(
212
+ {"quick": snapshot, "deep_cleanup_plan": plan},
213
+ ensure_ascii=False,
214
+ indent=2,
215
+ default=str,
216
+ )
217
+ )
218
+ else:
219
+ _display_deep_plan(plan)
220
+ elif not json_output:
221
+ click.echo(
222
+ click.style(
223
+ "Analiza głęboka jest opcjonalna: fixos quick --deep",
224
+ fg="cyan",
225
+ )
226
+ )