fixos 2.2.41__tar.gz → 2.2.45__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.41 → fixos-2.2.45}/CHANGELOG.md +17 -0
- {fixos-2.2.41 → fixos-2.2.45}/PKG-INFO +6 -6
- {fixos-2.2.41 → fixos-2.2.45}/README.md +5 -5
- {fixos-2.2.41 → fixos-2.2.45}/fixos/__init__.py +1 -1
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/cleanup_cmd.py +205 -15
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/main.py +17 -1
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/service_cleanup.py +457 -7
- {fixos-2.2.41 → fixos-2.2.45}/fixos.egg-info/PKG-INFO +6 -6
- {fixos-2.2.41 → fixos-2.2.45}/pyproject.toml +1 -1
- {fixos-2.2.41 → fixos-2.2.45}/setup.py +1 -1
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_cleanup_cmd.py +195 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_service_cleanup.py +187 -0
- {fixos-2.2.41 → fixos-2.2.45}/.env.example +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/LICENSE +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/MANIFEST.in +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/README.md +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/TEST_RESULTS.md +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/TEST_RESULTS_V2.md +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/alpine/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/arch/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/base/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/broken-audio/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/broken-full/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/broken-network/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/broken-thumbnails/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/debian/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/docker-compose.multi-system.yml +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/docker-compose.yml +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/fedora/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/test-multi-system.sh +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/test-scenarios.sh +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/ubuntu/Dockerfile +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docker/validate-scenario.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docs/examples/advanced_usage.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/docs/examples/quickstart.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/__main__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/autonomous.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/autonomous_session.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/hitl.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/hitl_session.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/session_core.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/session_handlers.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/agent/session_io.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/anonymizer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/_cleanup_flatpak.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/_cleanup_home.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/_cleanup_snap.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/_cleanup_system.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/_cleanup_utils.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/ask_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/config_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/features_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/fix_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/history_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/orchestrate_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/output_formatter.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/profile_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/projects_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/provider_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/quick_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/quickfix_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/report_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/rollback_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/scan_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/shared.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/token_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli/watch_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/cli.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/config.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/config_interactive.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/constants.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/_flatpak_analysis_mixin.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/_flatpak_execution_mixin.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/_flatpak_recommendations_mixin.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/_storage_container_mixin.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/_storage_system_mixin.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/_storage_user_mixin.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/cache_discovery.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/_shared.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/audio.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/file_analysis.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/hardware.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/packages.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/resources.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/security.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/storage_optimization.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/system_core.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/checks/thumbnails.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/dev_project_analyzer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/disk_analyzer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/flatpak_analyzer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/project_scanner.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/quick_snapshot.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/service_details.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/service_scanner.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/storage_analyzer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/system_checks.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/diagnostics/utils.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/features/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/features/auditor.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/features/catalog.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/features/installer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/features/profiles.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/features/renderer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/fixes/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/interactive/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/interactive/cleanup_planner.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/llm_shell.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/orchestrator/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/orchestrator/executor.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/orchestrator/graph.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/orchestrator/orchestrator.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/orchestrator/rollback.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/platform_utils.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/base.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/audio.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/disk.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/hardware.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/resources.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/security.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/builtin/thumbnails.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/plugins/registry.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/profiles/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/providers/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/providers/llm.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/providers/llm_analyzer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/providers/schemas.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/system_checks.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/utils/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/utils/anonymizer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/utils/terminal.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/utils/timeout.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/utils/web_search.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos/watch.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos.egg-info/SOURCES.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos.egg-info/dependency_links.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos.egg-info/entry_points.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos.egg-info/requires.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/fixos.egg-info/top_level.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/pytest.ini +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/requirements-dev.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/requirements.txt +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/scripts/pyqual-calibrate.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/setup.cfg +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/conftest.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_anonymization_layers.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_audio_broken.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_cli.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_diagnostics_integration.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_executor.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_multi_system.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_network_broken.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/e2e/test_thumbnails_broken.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/test_fixos.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/__init__.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_anonymizer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_cache_discovery.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_core.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_dev_project_analyzer.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_executor.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_llm_provider.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_orchestrator.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_project_scanner.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_projects_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_quick_cmd.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_quick_snapshot.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_resources_quick.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_security_quick.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_service_scanner.py +0 -0
- {fixos-2.2.41 → fixos-2.2.45}/tests/unit/test_system_checks_parallel.py +0 -0
|
@@ -51,6 +51,23 @@
|
|
|
51
51
|
rekurencyjnych skanów `/` oraz `/home` z szybkich kontroli.
|
|
52
52
|
- Czyszczenie cache JetBrains trafia w aktualną ścieżkę i wymaga zamknięcia IDE.
|
|
53
53
|
|
|
54
|
+
## [2.2.45] - 2026-08-07
|
|
55
|
+
|
|
56
|
+
### Docs
|
|
57
|
+
- Update README.md
|
|
58
|
+
|
|
59
|
+
### Test
|
|
60
|
+
- Update tests/unit/test_cleanup_cmd.py
|
|
61
|
+
- Update tests/unit/test_service_cleanup.py
|
|
62
|
+
|
|
63
|
+
### Other
|
|
64
|
+
- Update VERSION
|
|
65
|
+
- Update fixos/__init__.py
|
|
66
|
+
- Update fixos/cli/cleanup_cmd.py
|
|
67
|
+
- Update fixos/cli/main.py
|
|
68
|
+
- Update fixos/diagnostics/service_cleanup.py
|
|
69
|
+
- Update uv.lock
|
|
70
|
+
|
|
54
71
|
## [2.2.41] - 2026-07-23
|
|
55
72
|
|
|
56
73
|
### Docs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fixos
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.45
|
|
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,13 +63,13 @@ 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.8099 (150 commits)
|
|
70
|
+
- 👤 **Human dev:** ~$3959 (39.6h @ $100/h, 30min dedup)
|
|
71
71
|
|
|
72
|
-
Generated on 2026-07
|
|
72
|
+
Generated on 2026-08-07 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
@@ -19,13 +19,13 @@ 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.8099 (150 commits)
|
|
26
|
+
- 👤 **Human dev:** ~$3959 (39.6h @ $100/h, 30min dedup)
|
|
27
27
|
|
|
28
|
-
Generated on 2026-07
|
|
28
|
+
Generated on 2026-08-07 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -17,6 +17,11 @@ from fixos.constants import DEFAULT_CLEANUP_THRESHOLD_MB
|
|
|
17
17
|
# Re-export public symbols used by fixos.cli (backward-compat)
|
|
18
18
|
from fixos.cli._cleanup_flatpak import _cleanup_flatpak_detailed # noqa: F401
|
|
19
19
|
from fixos.cli._cleanup_system import _cleanup_full_system
|
|
20
|
+
from fixos.diagnostics.service_cleanup import (
|
|
21
|
+
DEFAULT_DOCKER_OLD_UNUSED_DAYS,
|
|
22
|
+
DEFAULT_OLLAMA_OLD_UNUSED_DAYS,
|
|
23
|
+
ServiceCleaner,
|
|
24
|
+
)
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
# ── Service display helpers ───────────────────────────────────────────────
|
|
@@ -129,17 +134,33 @@ def _error_message(result: dict) -> str:
|
|
|
129
134
|
return "nieznany błąd"
|
|
130
135
|
|
|
131
136
|
|
|
137
|
+
def _execute_planned_cleanup(scanner, svc: dict, *, dry_run: bool = False) -> dict:
|
|
138
|
+
"""Run a planned cleanup entry (including age-bounded docker/ollama actions)."""
|
|
139
|
+
kind = svc.get("cleanup_kind")
|
|
140
|
+
cleaner = ServiceCleaner(scanner)
|
|
141
|
+
if kind == "ollama-old":
|
|
142
|
+
return cleaner.cleanup_ollama_old_unused(
|
|
143
|
+
days=int(svc.get("days") or DEFAULT_OLLAMA_OLD_UNUSED_DAYS),
|
|
144
|
+
dry_run=dry_run,
|
|
145
|
+
)
|
|
146
|
+
if kind == "docker-old":
|
|
147
|
+
return cleaner.cleanup_docker_old_unused(
|
|
148
|
+
days=int(svc.get("days") or DEFAULT_DOCKER_OLD_UNUSED_DAYS),
|
|
149
|
+
dry_run=dry_run,
|
|
150
|
+
)
|
|
151
|
+
return scanner.cleanup_service(
|
|
152
|
+
svc["service_type"],
|
|
153
|
+
dry_run=dry_run,
|
|
154
|
+
planned_service=svc,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
132
158
|
def _execute_safe_cleanup(services: list, scanner) -> float:
|
|
133
159
|
"""Execute cleanup for safe-to-remove services. Returns total space freed in GB."""
|
|
134
160
|
total_freed = 0.0
|
|
135
161
|
for svc in services:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
result = scanner.cleanup_service(
|
|
139
|
-
svc_type,
|
|
140
|
-
dry_run=False,
|
|
141
|
-
planned_service=svc,
|
|
142
|
-
)
|
|
162
|
+
click.echo(f"Czyszczenie {svc.get('name') or svc['service_type']}...")
|
|
163
|
+
result = _execute_planned_cleanup(scanner, svc, dry_run=False)
|
|
143
164
|
if result["success"]:
|
|
144
165
|
freed = result.get("space_freed_gb", 0)
|
|
145
166
|
total_freed += freed
|
|
@@ -441,6 +462,112 @@ def _cleanup_single_service(
|
|
|
441
462
|
click.echo(f"Output: {result['output']}")
|
|
442
463
|
|
|
443
464
|
|
|
465
|
+
def _cleanup_docker_old_unused(
|
|
466
|
+
scanner, days: int, json_output: bool, dry_run: bool
|
|
467
|
+
) -> None:
|
|
468
|
+
"""Prune unused Docker images (and old build cache) older than N days."""
|
|
469
|
+
cleaner = ServiceCleaner(scanner)
|
|
470
|
+
try:
|
|
471
|
+
result = cleaner.cleanup_docker_old_unused(days=days, dry_run=dry_run)
|
|
472
|
+
except ValueError as exc:
|
|
473
|
+
click.echo(click.style(f"Błąd: {exc}", fg="red"))
|
|
474
|
+
return
|
|
475
|
+
|
|
476
|
+
if json_output:
|
|
477
|
+
import json
|
|
478
|
+
|
|
479
|
+
click.echo(json.dumps(result, indent=2, default=str))
|
|
480
|
+
return
|
|
481
|
+
|
|
482
|
+
click.echo(
|
|
483
|
+
click.style(
|
|
484
|
+
f"Docker — nieużywane obrazy starsze niż {days} dni",
|
|
485
|
+
fg="yellow",
|
|
486
|
+
)
|
|
487
|
+
)
|
|
488
|
+
click.echo(f" Komenda: {result.get('command')}")
|
|
489
|
+
if dry_run:
|
|
490
|
+
click.echo(click.style("[TRYB DRY-RUN] - brak faktycznych zmian", fg="cyan"))
|
|
491
|
+
|
|
492
|
+
if result.get("success"):
|
|
493
|
+
if dry_run:
|
|
494
|
+
click.echo(click.style("Symulacja zakończona", fg="green"))
|
|
495
|
+
if result.get("output"):
|
|
496
|
+
for line in str(result["output"]).splitlines():
|
|
497
|
+
click.echo(f" {line}")
|
|
498
|
+
if result.get("estimated_max_gb", 0) > 0:
|
|
499
|
+
click.echo(
|
|
500
|
+
f" Szacowane maksimum (Images+Build Cache reclaimable): "
|
|
501
|
+
f"{result['estimated_max_gb']:.2f} GB "
|
|
502
|
+
f"(filtr until zwykle usunie mniej)"
|
|
503
|
+
)
|
|
504
|
+
else:
|
|
505
|
+
click.echo(click.style("Zakończono czyszczenie docker-old", fg="green"))
|
|
506
|
+
if result.get("space_freed_gb", 0) > 0:
|
|
507
|
+
click.echo(f" Zwolniono: {result['space_freed_gb']:.2f} GB")
|
|
508
|
+
elif result.get("output"):
|
|
509
|
+
click.echo(f" {result['output'].strip()[:500]}")
|
|
510
|
+
else:
|
|
511
|
+
click.echo(click.style(f"Błąd: {_error_message(result)}", fg="red"))
|
|
512
|
+
if result.get("output"):
|
|
513
|
+
click.echo(f"Output: {result['output']}")
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def _cleanup_ollama_old_unused(
|
|
517
|
+
scanner, days: int, json_output: bool, dry_run: bool
|
|
518
|
+
) -> None:
|
|
519
|
+
"""Remove Ollama models not modified for more than N days."""
|
|
520
|
+
cleaner = ServiceCleaner(scanner)
|
|
521
|
+
try:
|
|
522
|
+
result = cleaner.cleanup_ollama_old_unused(days=days, dry_run=dry_run)
|
|
523
|
+
except ValueError as exc:
|
|
524
|
+
click.echo(click.style(f"Błąd: {exc}", fg="red"))
|
|
525
|
+
return
|
|
526
|
+
|
|
527
|
+
if json_output:
|
|
528
|
+
import json
|
|
529
|
+
|
|
530
|
+
click.echo(json.dumps(result, indent=2, default=str))
|
|
531
|
+
return
|
|
532
|
+
|
|
533
|
+
click.echo(
|
|
534
|
+
click.style(
|
|
535
|
+
f"Ollama — modele niezmieniane od {days}+ dni",
|
|
536
|
+
fg="yellow",
|
|
537
|
+
)
|
|
538
|
+
)
|
|
539
|
+
if result.get("command"):
|
|
540
|
+
click.echo(f" Komenda: {result['command']}")
|
|
541
|
+
if dry_run:
|
|
542
|
+
click.echo(click.style("[TRYB DRY-RUN] - brak faktycznych zmian", fg="cyan"))
|
|
543
|
+
|
|
544
|
+
if result.get("success"):
|
|
545
|
+
if dry_run:
|
|
546
|
+
click.echo(click.style("Symulacja zakończona", fg="green"))
|
|
547
|
+
if result.get("output"):
|
|
548
|
+
for line in str(result["output"]).splitlines():
|
|
549
|
+
click.echo(f" {line}")
|
|
550
|
+
if result.get("estimated_max_gb", 0) > 0:
|
|
551
|
+
click.echo(
|
|
552
|
+
f" Szacowane zwolnienie: {result['estimated_max_gb']:.2f} GB"
|
|
553
|
+
)
|
|
554
|
+
if result.get("skipped_running"):
|
|
555
|
+
click.echo(
|
|
556
|
+
" Pominięto uruchomione: "
|
|
557
|
+
+ ", ".join(result["skipped_running"])
|
|
558
|
+
)
|
|
559
|
+
else:
|
|
560
|
+
click.echo(click.style("Zakończono czyszczenie ollama-old", fg="green"))
|
|
561
|
+
if result.get("space_freed_gb", 0) > 0:
|
|
562
|
+
click.echo(f" Zwolniono: {result['space_freed_gb']:.2f} GB")
|
|
563
|
+
if result.get("output"):
|
|
564
|
+
click.echo(f" {result['output'].strip()[:500]}")
|
|
565
|
+
else:
|
|
566
|
+
click.echo(click.style(f"Błąd: {_error_message(result)}", fg="red"))
|
|
567
|
+
if result.get("output"):
|
|
568
|
+
click.echo(f"Output: {result['output']}")
|
|
569
|
+
|
|
570
|
+
|
|
444
571
|
# ── Interactive cleanup orchestration ─────────────────────────────────────
|
|
445
572
|
|
|
446
573
|
|
|
@@ -540,11 +667,7 @@ def _execute_individual_cleanup(services: list, scanner) -> float:
|
|
|
540
667
|
continue
|
|
541
668
|
|
|
542
669
|
click.echo(f"Czyszczenie {svc['name']}...")
|
|
543
|
-
result = scanner
|
|
544
|
-
svc["service_type"],
|
|
545
|
-
dry_run=False,
|
|
546
|
-
planned_service=svc,
|
|
547
|
-
)
|
|
670
|
+
result = _execute_planned_cleanup(scanner, svc, dry_run=False)
|
|
548
671
|
if result["success"]:
|
|
549
672
|
freed = float(result.get("space_freed_gb", 0))
|
|
550
673
|
total_freed += freed
|
|
@@ -602,7 +725,37 @@ def _run_interactive_cleanup(plan: dict, list_only: bool, scanner) -> None:
|
|
|
602
725
|
"--cleanup",
|
|
603
726
|
"-c",
|
|
604
727
|
default=None,
|
|
605
|
-
help="Wyczyść konkretną usługę (docker, ollama, npm, ...)",
|
|
728
|
+
help="Wyczyść konkretną usługę (docker, docker-old, ollama-old, ollama, npm, ...)",
|
|
729
|
+
)
|
|
730
|
+
@click.option(
|
|
731
|
+
"--docker-old",
|
|
732
|
+
"docker_old",
|
|
733
|
+
is_flag=True,
|
|
734
|
+
default=False,
|
|
735
|
+
help=(
|
|
736
|
+
"Usuń nieużywane obrazy Docker (i stary build cache) starsze niż --days "
|
|
737
|
+
f"(domyślnie {DEFAULT_DOCKER_OLD_UNUSED_DAYS}); nie rusza wolumenów ani obrazów w użyciu"
|
|
738
|
+
),
|
|
739
|
+
)
|
|
740
|
+
@click.option(
|
|
741
|
+
"--ollama-old",
|
|
742
|
+
"ollama_old",
|
|
743
|
+
is_flag=True,
|
|
744
|
+
default=False,
|
|
745
|
+
help=(
|
|
746
|
+
"Usuń modele Ollama niezmieniane od --days dni "
|
|
747
|
+
f"(domyślnie {DEFAULT_OLLAMA_OLD_UNUSED_DAYS}); pomija modele aktualnie uruchomione"
|
|
748
|
+
),
|
|
749
|
+
)
|
|
750
|
+
@click.option(
|
|
751
|
+
"--days",
|
|
752
|
+
default=None,
|
|
753
|
+
type=int,
|
|
754
|
+
help=(
|
|
755
|
+
"Wiek w dniach dla --docker-old "
|
|
756
|
+
f"(domyślnie {DEFAULT_DOCKER_OLD_UNUSED_DAYS}) lub --ollama-old "
|
|
757
|
+
f"(domyślnie {DEFAULT_OLLAMA_OLD_UNUSED_DAYS})"
|
|
758
|
+
),
|
|
606
759
|
)
|
|
607
760
|
@click.option(
|
|
608
761
|
"--dry-run",
|
|
@@ -626,7 +779,16 @@ def _run_interactive_cleanup(plan: dict, list_only: bool, scanner) -> None:
|
|
|
626
779
|
help="Pełna analiza systemu (DNF, kernels, logs, Docker, cache)",
|
|
627
780
|
)
|
|
628
781
|
def cleanup_services(
|
|
629
|
-
threshold,
|
|
782
|
+
threshold,
|
|
783
|
+
services,
|
|
784
|
+
json_output,
|
|
785
|
+
cleanup,
|
|
786
|
+
docker_old,
|
|
787
|
+
ollama_old,
|
|
788
|
+
days,
|
|
789
|
+
dry_run,
|
|
790
|
+
list_only,
|
|
791
|
+
full_analysis,
|
|
630
792
|
) -> None:
|
|
631
793
|
"""
|
|
632
794
|
Skanuje i czyści dane usług przekraczające próg.
|
|
@@ -643,7 +805,12 @@ def cleanup_services(
|
|
|
643
805
|
fixos cleanup -t 1000 # próg 1000MB (1GB)
|
|
644
806
|
fixos cleanup -s docker,ollama # tylko Docker i Ollama
|
|
645
807
|
fixos cleanup --list # tylko lista, bez czyszczenia
|
|
646
|
-
fixos cleanup -c docker --dry-run #
|
|
808
|
+
fixos cleanup -c docker --dry-run # tylko cache buildów >7 dni
|
|
809
|
+
fixos cleanup --docker-old --days 30 --dry-run
|
|
810
|
+
# nieużywane obrazy (+ cache) starsze niż 30 dni
|
|
811
|
+
fixos cleanup --ollama-old --days 90 --dry-run
|
|
812
|
+
# modele Ollama niezmieniane od 90+ dni
|
|
813
|
+
fixos cleanup -c ollama-old
|
|
647
814
|
fixos cleanup --full # pełna analiza systemu
|
|
648
815
|
"""
|
|
649
816
|
if full_analysis:
|
|
@@ -652,6 +819,29 @@ def cleanup_services(
|
|
|
652
819
|
|
|
653
820
|
scanner = ServiceDataScanner(threshold_mb=threshold)
|
|
654
821
|
|
|
822
|
+
want_docker_old = docker_old or (cleanup == "docker-old")
|
|
823
|
+
want_ollama_old = ollama_old or (cleanup == "ollama-old")
|
|
824
|
+
if want_docker_old and want_ollama_old:
|
|
825
|
+
click.echo(
|
|
826
|
+
click.style(
|
|
827
|
+
"Wybierz jedno: --docker-old albo --ollama-old (nie oba naraz).",
|
|
828
|
+
fg="red",
|
|
829
|
+
)
|
|
830
|
+
)
|
|
831
|
+
return
|
|
832
|
+
if want_docker_old:
|
|
833
|
+
effective_days = (
|
|
834
|
+
days if days is not None else DEFAULT_DOCKER_OLD_UNUSED_DAYS
|
|
835
|
+
)
|
|
836
|
+
_cleanup_docker_old_unused(scanner, effective_days, json_output, dry_run)
|
|
837
|
+
return
|
|
838
|
+
if want_ollama_old:
|
|
839
|
+
effective_days = (
|
|
840
|
+
days if days is not None else DEFAULT_OLLAMA_OLD_UNUSED_DAYS
|
|
841
|
+
)
|
|
842
|
+
_cleanup_ollama_old_unused(scanner, effective_days, json_output, dry_run)
|
|
843
|
+
return
|
|
844
|
+
|
|
655
845
|
if cleanup:
|
|
656
846
|
if cleanup == "flatpak":
|
|
657
847
|
_cleanup_flatpak_detailed(scanner, json_output, dry_run)
|
|
@@ -72,6 +72,16 @@ def _print_welcome() -> None:
|
|
|
72
72
|
("fixos scan", "", "Diagnostyka systemu bez AI"),
|
|
73
73
|
("fixos quickfix", "", "Naprawy offline bez API (baza znanych bugów)"),
|
|
74
74
|
("fixos cleanup", "", "Skanuj i czyść dane usług (Docker, Ollama)"),
|
|
75
|
+
(
|
|
76
|
+
"fixos cleanup --docker-old",
|
|
77
|
+
"",
|
|
78
|
+
"Usuń nieużywane obrazy Docker starsze niż 30 dni",
|
|
79
|
+
),
|
|
80
|
+
(
|
|
81
|
+
"fixos cleanup --ollama-old",
|
|
82
|
+
"",
|
|
83
|
+
"Usuń modele Ollama niezmieniane od 90+ dni",
|
|
84
|
+
),
|
|
75
85
|
(
|
|
76
86
|
"fixos projects",
|
|
77
87
|
"",
|
|
@@ -90,7 +100,7 @@ def _print_welcome() -> None:
|
|
|
90
100
|
]
|
|
91
101
|
|
|
92
102
|
for cmd, icon, desc in commands:
|
|
93
|
-
cmd_styled = click.style(f"{cmd:<
|
|
103
|
+
cmd_styled = click.style(f"{cmd:<32}", fg="yellow")
|
|
94
104
|
click.echo(f" {icon} {cmd_styled} {desc}")
|
|
95
105
|
|
|
96
106
|
click.echo()
|
|
@@ -142,6 +152,12 @@ def _print_welcome() -> None:
|
|
|
142
152
|
click.echo(
|
|
143
153
|
f"{click.style(' fixos fix', fg='yellow')} # pełna diagnostyka + naprawa"
|
|
144
154
|
)
|
|
155
|
+
click.echo(
|
|
156
|
+
f"{click.style(' fixos cleanup --docker-old --dry-run', fg='yellow')} # stare nieużywane obrazy Docker"
|
|
157
|
+
)
|
|
158
|
+
click.echo(
|
|
159
|
+
f"{click.style(' fixos cleanup --ollama-old --dry-run', fg='yellow')} # stare modele Ollama (90+ dni)"
|
|
160
|
+
)
|
|
145
161
|
click.echo(
|
|
146
162
|
f"{click.style(' fixos fix --modules security,resources', fg='yellow')} # bezpieczeństwo + zasoby"
|
|
147
163
|
)
|