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.
- {fixos-2.2.38 → fixos-2.2.39}/CHANGELOG.md +47 -0
- {fixos-2.2.38 → fixos-2.2.39}/PKG-INFO +37 -13
- {fixos-2.2.38 → fixos-2.2.39}/README.md +37 -13
- {fixos-2.2.38 → fixos-2.2.39}/fixos/__init__.py +1 -1
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/session_handlers.py +16 -8
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/fix_cmd.py +16 -4
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/main.py +28 -4
- fixos-2.2.39/fixos/cli/quick_cmd.py +226 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli.py +3 -0
- fixos-2.2.39/fixos/diagnostics/__init__.py +4 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/dev_project_analyzer.py +44 -29
- fixos-2.2.39/fixos/diagnostics/quick_snapshot.py +823 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/service_scanner.py +41 -10
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/system_checks.py +5 -5
- {fixos-2.2.38 → fixos-2.2.39}/fixos/watch.py +32 -1
- {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/PKG-INFO +37 -13
- {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/SOURCES.txt +5 -0
- {fixos-2.2.38 → fixos-2.2.39}/pyproject.toml +1 -1
- {fixos-2.2.38 → fixos-2.2.39}/setup.py +1 -1
- fixos-2.2.39/tests/unit/test_dev_project_analyzer.py +56 -0
- fixos-2.2.39/tests/unit/test_quick_cmd.py +87 -0
- fixos-2.2.39/tests/unit/test_quick_snapshot.py +176 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_service_scanner.py +4 -4
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_system_checks_parallel.py +4 -2
- fixos-2.2.38/fixos/diagnostics/__init__.py +0 -3
- {fixos-2.2.38 → fixos-2.2.39}/.env.example +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/LICENSE +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/MANIFEST.in +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/README.md +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/TEST_RESULTS.md +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/TEST_RESULTS_V2.md +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/alpine/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/arch/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/base/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/broken-audio/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/broken-full/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/broken-network/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/broken-thumbnails/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/debian/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/docker-compose.multi-system.yml +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/docker-compose.yml +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/fedora/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/test-multi-system.sh +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/test-scenarios.sh +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/ubuntu/Dockerfile +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docker/validate-scenario.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docs/examples/advanced_usage.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/docs/examples/quickstart.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/autonomous.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/autonomous_session.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/hitl.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/hitl_session.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/session_core.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/agent/session_io.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/anonymizer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_flatpak.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_home.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_snap.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_system.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/_cleanup_utils.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/ask_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/cleanup_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/config_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/features_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/history_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/orchestrate_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/output_formatter.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/profile_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/projects_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/provider_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/quickfix_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/report_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/rollback_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/scan_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/shared.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/token_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/cli/watch_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/config.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/config_interactive.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/constants.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_flatpak_analysis_mixin.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_flatpak_execution_mixin.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_flatpak_recommendations_mixin.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_storage_container_mixin.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_storage_system_mixin.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/_storage_user_mixin.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/cache_discovery.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/_shared.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/audio.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/file_analysis.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/hardware.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/packages.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/resources.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/security.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/storage_optimization.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/system_core.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/checks/thumbnails.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/disk_analyzer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/flatpak_analyzer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/project_scanner.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/service_cleanup.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/service_details.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/storage_analyzer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/diagnostics/utils.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/features/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/features/auditor.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/features/catalog.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/features/installer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/features/profiles.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/features/renderer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/fixes/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/interactive/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/interactive/cleanup_planner.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/llm_shell.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/executor.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/graph.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/orchestrator.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/orchestrator/rollback.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/platform_utils.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/base.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/audio.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/disk.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/hardware.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/resources.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/security.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/builtin/thumbnails.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/plugins/registry.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/profiles/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/llm.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/llm_analyzer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/providers/schemas.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/system_checks.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/anonymizer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/terminal.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/timeout.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos/utils/web_search.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/dependency_links.txt +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/entry_points.txt +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/requires.txt +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/fixos.egg-info/top_level.txt +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/pytest.ini +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/requirements-dev.txt +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/requirements.txt +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/scripts/pyqual-calibrate.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/setup.cfg +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/conftest.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_anonymization_layers.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_audio_broken.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_cli.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_diagnostics_integration.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_executor.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_multi_system.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_network_broken.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/e2e/test_thumbnails_broken.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/test_fixos.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/__init__.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_anonymizer.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_cache_discovery.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_core.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_executor.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_llm_provider.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_orchestrator.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_project_scanner.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_projects_cmd.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_resources_quick.py +0 -0
- {fixos-2.2.38 → fixos-2.2.39}/tests/unit/test_security_quick.py +0 -0
- {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.
|
|
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
|
-
    
|
|
67
|
+
  
|
|
68
68
|
|
|
69
|
-
- 🤖 **LLM usage:** $4.
|
|
70
|
-
- 👤 **Human dev:** ~$
|
|
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.
|
|
102
|
-
fixos
|
|
101
|
+
# 2. Pierwszy lokalny wynik bez LLM
|
|
102
|
+
fixos quick # CPU/RAM/dysk/cache + początek historii
|
|
103
103
|
|
|
104
|
-
# 3.
|
|
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 (
|
|
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
|
-
- **
|
|
242
|
-
Docker/Podman/containerd, cała biblioteka
|
|
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
|
-
|
|
245
|
-
|
|
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
|
-
    
|
|
23
|
+
  
|
|
24
24
|
|
|
25
|
-
- 🤖 **LLM usage:** $4.
|
|
26
|
-
- 👤 **Human dev:** ~$
|
|
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.
|
|
58
|
-
fixos
|
|
57
|
+
# 2. Pierwszy lokalny wynik bez LLM
|
|
58
|
+
fixos quick # CPU/RAM/dysk/cache + początek historii
|
|
59
59
|
|
|
60
|
-
# 3.
|
|
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 (
|
|
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
|
-
- **
|
|
198
|
-
Docker/Podman/containerd, cała biblioteka
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-

|
|
594
|
+

|
|
@@ -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
|
-
|
|
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"{
|
|
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
|
|
322
|
-
|
|
323
|
-
|
|
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
|
|
328
|
-
user_in, messages, executed, run_single_command
|
|
329
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
28
|
-
fixos
|
|
29
|
-
fixos
|
|
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
|
-
(
|
|
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
|
+
)
|