clutterxp 1.2.0__tar.gz → 1.2.1__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.
- clutterxp-1.2.1/PKG-INFO +220 -0
- clutterxp-1.2.1/README.md +186 -0
- clutterxp-1.2.1/assets/clutterxp_logo.png +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/pyproject.toml +7 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/__init__.py +1 -1
- clutterxp-1.2.0/PKG-INFO +0 -149
- clutterxp-1.2.0/README.md +0 -120
- {clutterxp-1.2.0 → clutterxp-1.2.1}/.github/workflows/ci.yml +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/.gitignore +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/CHANGELOG.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/config.example.yaml +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/00_PROJECT_PLAN.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/01_ARCHITECTURE.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/02_RULE_ENGINE.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/03_CONFIG.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/04_SAFE_MOVER.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/05_HISTORY_UNDO.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/06_WATCHER.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/07_DUPLICATES.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/08_CLI.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/09_SAFETY.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/10_TESTING.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/11_PACKAGING.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/12_GUI.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/13_ROADMAP.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/14_DECISIONS.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/15_ACCEPTANCE.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/16_RISKS.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/reviews/.gitkeep +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/reviews/acceptance_matrix.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/reviews/perf_report.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/docs/reviews/security_review.md +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/packaging/clutterxp.service +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/scripts/.gitkeep +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/scripts/check_contracts.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/scripts/check_ownership.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/scripts/contracts.lock.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/scripts/e2e.sh +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/scripts/smoke_readme.sh +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/app.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_config.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_doctor.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_duplicates.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_gui.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_history.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_init.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_organize.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_rules.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_scan.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_service.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_undo.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/cmd_watch.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/errors.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/cli/render.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/jsonschema.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/loader.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/placeholders.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/runtime.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/schema.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/validate.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/config/writer.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/duplicates/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/duplicates/detector.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/duplicates/hashcache.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/duplicates/namenorm.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/duplicates/quarantine.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/duplicates/report.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/api.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/app.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/models_qt.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/theme.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/dashboard.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/duplicates.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/folders.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/history.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/preview.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/rules.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/views/settings.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/gui/workers.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/db.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/pathcodec.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/recovery.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/schema.sql +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/service.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/history/undo.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/interfaces.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/locking.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/logging_setup.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/models.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/mover/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/mover/collision.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/mover/fsops.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/mover/safe_move.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/organizer.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/paths.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/planner.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/py.typed +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/rules/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/rules/engine.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/rules/matcher.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/rules/template.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/rules/tokenizer.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/safety.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/scanner.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/service_install.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/units.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/watch/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/watch/debounce.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/watch/events.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/watch/ignore.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/watch/service.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/src/clutterxp/watch/settle.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/.gitkeep +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/doctor.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/duplicates.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/history.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/organize.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/rules_list.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/rules_test.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/schemas/scan.json +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_config.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_doctor.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_duplicates.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_general.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_gui.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_history.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_init.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_organize.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_rules.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_scan.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_service.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_undo.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/cli/test_watch.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_jsonschema_and_logging.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_loader.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_paths.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_placeholders.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_runtime.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_validate.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/config/test_writer.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/duplicates/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/duplicates/test_detector.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/duplicates/test_hashcache.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/duplicates/test_namenorm.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/duplicates/test_quarantine.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A81_gui_launches_and_cli_never_imports_qt.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A82_dashboard_shows_watcher_and_recent_operations.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A83_folders_view_edits_watch_folders_and_settings.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A84_rules_editor_includes_live_trace.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A85_preview_data_equals_cli_json_plan.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A86_history_view_undo_shows_exact_refusal_reasons.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A87_duplicates_view_progress_and_cancel.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A88_duplicates_quarantine_gui.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A89_ui_thread_never_blocks_worker_cancellation.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_A90_gui_extra_documented.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_api_extra.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/gui/test_models_qt.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/helpers.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/history/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/history/test_db.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/history/test_pathcodec.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/history/test_recovery.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/history/test_service.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/history/test_undo.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/integration/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/integration/test_acceptance_sweep.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/integration/test_fault_injection.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/integration/test_properties.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/integration/test_scenarios.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/mover/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/mover/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/mover/test_collision.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/mover/test_fsops.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/mover/test_locking.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/mover/test_safe_move.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/organizer/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/organizer/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/organizer/test_organizer.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/organizer/test_planner.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/organizer/test_scanner.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/perf/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/perf/test_perf_budgets.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/test_engine.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/test_matcher.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/test_template.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/test_tokenizer.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/rules/test_vectors.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/safety/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/safety/test_invariants_full.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/safety/test_safety_module.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/test_harness.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/test_service_install.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/__init__.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/conftest.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_acceptance.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_debounce.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_events.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_ignore.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_invariants.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_service.py +0 -0
- {clutterxp-1.2.0 → clutterxp-1.2.1}/tests/watch/test_settle.py +0 -0
clutterxp-1.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: clutterxp
|
|
3
|
+
Version: 1.2.1
|
|
4
|
+
Summary: Configurable, safe, lightweight file organizer: rules, preview, undo, watch, duplicates.
|
|
5
|
+
Project-URL: Homepage, https://github.com/aigo-admin/clutterxp
|
|
6
|
+
Project-URL: Documentation, https://github.com/aigo-admin/clutterxp#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/aigo-admin/clutterxp.git
|
|
8
|
+
Project-URL: Issue Tracker, https://github.com/aigo-admin/clutterxp/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/aigo-admin/clutterxp/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: automation,cli,downloads,file-organizer,linux
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: System :: Filesystems
|
|
15
|
+
Classifier: Topic :: Utilities
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: platformdirs>=4.0
|
|
18
|
+
Requires-Dist: pydantic>=2.6
|
|
19
|
+
Requires-Dist: ruamel-yaml-clib>=0.2.12; platform_python_implementation == 'CPython'
|
|
20
|
+
Requires-Dist: ruamel-yaml>=0.18
|
|
21
|
+
Requires-Dist: typer>=0.12
|
|
22
|
+
Requires-Dist: watchdog>=4.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: hypothesis>=6.100; extra == 'dev'
|
|
26
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
31
|
+
Provides-Extra: gui
|
|
32
|
+
Requires-Dist: pyside6>=6.6; extra == 'gui'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://raw.githubusercontent.com/aigo-admin/clutterxp/0ec772e48eaf1022d81824e19f89d171e1df8640/assets/clutterxp_logo.png" alt="ClutterXP Logo" width="240">
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<h1 align="center">ClutterXP</h1>
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<strong>Configurable, safe, lightweight file organizer for Linux.</strong><br>
|
|
43
|
+
Tidies downloads, documents, and messy directories into place—on your terms, with zero risk of file loss.
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
| Category | Badges |
|
|
49
|
+
|:---|:---|
|
|
50
|
+
| **Package** | [](https://pypi.org/project/clutterxp/) [](https://pypi.org/project/clutterxp/) [](https://github.com/aigo-admin/clutterxp/blob/main/LICENSE) |
|
|
51
|
+
| **Quality** | [](https://github.com/aigo-admin/clutterxp) [](https://github.com/astral-sh/ruff) [](http://mypy-lang.org/) |
|
|
52
|
+
| **Safety** | [](https://github.com/aigo-admin/clutterxp) [](https://github.com/aigo-admin/clutterxp) |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## What is it?
|
|
57
|
+
|
|
58
|
+
**ClutterXP** is a modern, fast, and reliable file organization toolkit designed for developers, power users, and everyday Linux users who want an organized workspace. Whether your `Downloads` folder is buried under months of receipts, PDFs, installers, wallpapers, and screenshots, or you want background auto-sorting for incoming files, ClutterXP handles the job with ironclad safety guarantees:
|
|
59
|
+
|
|
60
|
+
- **Never deletes or overwrites**: Files only move when the destination is safe. If a file with the same name exists, ClutterXP automatically renames the incoming file (e.g., `report (1).pdf`) or skips it. Your existing files are never destroyed.
|
|
61
|
+
- **Only moves what you tell it to**: If a file does not match a configured rule, it stays untouched in its original location. No unexpected moves, no mystery dump directories.
|
|
62
|
+
- **One-click instant undo**: Every operation is logged in an ACID SQLite journal. Run `clutterxp undo` (or click Undo in the GUI) to restore files to their exact original locations.
|
|
63
|
+
- **100% private and offline**: Operates entirely on your local machine. No tracking, no cloud telemetry, and zero network calls.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Table of Contents
|
|
68
|
+
|
|
69
|
+
- [Main Features](#main-features)
|
|
70
|
+
- [Where to Get It](#where-to-get-it)
|
|
71
|
+
- [Quickstart: Desktop App](#quickstart-desktop-app)
|
|
72
|
+
- [Quickstart: Command Line](#quickstart-command-line)
|
|
73
|
+
- [Background Watcher Daemon](#background-watcher-daemon)
|
|
74
|
+
- [Duplicate File Quarantine](#duplicate-file-quarantine)
|
|
75
|
+
- [Customize Your Rules](#customize-your-rules)
|
|
76
|
+
- [Cheat Sheet](#cheat-sheet)
|
|
77
|
+
- [Dependencies](#dependencies)
|
|
78
|
+
- [License](#license)
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Main Features
|
|
83
|
+
|
|
84
|
+
- **Modern Minimalist Desktop App**: Clean obsidian-dark interface with one-click presets, visual plan previews, and real-time rule match testing.
|
|
85
|
+
- **Token-Aware Rule Engine**: Intelligent keyword matching that understands camelCase, PascalCase, hyphenated names, and compound extensions (e.g. `.tar.gz`).
|
|
86
|
+
- **Background Watcher**: Monitors designated folders using inotify with built-in settle and debounce to ensure browser downloads finish before moving.
|
|
87
|
+
- **Duplicate Detector & Safe Quarantine**: Multi-stage duplicate detection (size -> hardlinks -> head/tail partial hash -> streaming SHA-256) with safe quarantine isolation.
|
|
88
|
+
- **Instant LIFO Batch Undo**: Complete rollback capability for any batch of moves or quarantine actions.
|
|
89
|
+
- **Dual CLI Aliases**: Use full `clutterxp` or short alias `cxp` interchangeably.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Where to Get It
|
|
94
|
+
|
|
95
|
+
### Binary Installation via PyPI
|
|
96
|
+
|
|
97
|
+
Install ClutterXP using Python 3.10+:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Recommended: install with modern desktop app (GUI) support
|
|
101
|
+
pip install "clutterxp[gui]"
|
|
102
|
+
|
|
103
|
+
# CLI-only lightweight install
|
|
104
|
+
pip install clutterxp
|
|
105
|
+
|
|
106
|
+
# Or on Kali Linux / Debian / Ubuntu via pipx:
|
|
107
|
+
pipx install "clutterxp[gui]"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Quickstart: Desktop App
|
|
113
|
+
|
|
114
|
+
Launch the visual application with:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
clutterxp gui
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The desktop app provides:
|
|
121
|
+
- **Interactive Plan Preview**: Review every planned move with clear status badges before touching any files.
|
|
122
|
+
- **Rule Editor with Presets**: One-click setup for common categories (Invoices, Photos, Installers) plus live matching test as you type.
|
|
123
|
+
- **Duplicate Quarantine**: Safely isolate duplicate downloads without risking accidental deletion.
|
|
124
|
+
- **Batch History & Undo**: Restore any previous batch with a single click.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Quickstart: Command Line
|
|
129
|
+
|
|
130
|
+
Prefer the terminal? Use `clutterxp` or the shorthand `cxp`:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# 1. Create your default starter config
|
|
134
|
+
clutterxp init
|
|
135
|
+
|
|
136
|
+
# 2. Test which rule matches a filename
|
|
137
|
+
clutterxp rules test "invoice_march.pdf"
|
|
138
|
+
|
|
139
|
+
# 3. Preview what would be organized (dry-run, touches nothing)
|
|
140
|
+
clutterxp organize ~/Downloads --dry-run
|
|
141
|
+
|
|
142
|
+
# 4. Organize your Downloads folder
|
|
143
|
+
clutterxp organize ~/Downloads --yes
|
|
144
|
+
|
|
145
|
+
# 5. Changed your mind? Undo the entire batch instantly!
|
|
146
|
+
clutterxp undo --yes
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Background Watcher Daemon
|
|
152
|
+
|
|
153
|
+
Turn on automatic sorting. When a new file is downloaded or moved into a watched folder, ClutterXP waits until it is fully written to disk, then quietly sorts it into place:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
clutterxp watch
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
You can also install it as a systemd user service:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
clutterxp service install
|
|
163
|
+
clutterxp service status
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Duplicate File Quarantine
|
|
169
|
+
|
|
170
|
+
Identify duplicate files taking up storage and safely isolate them:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
clutterxp duplicates scan ~/Downloads
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Customize Your Rules
|
|
179
|
+
|
|
180
|
+
Rules are clean and human-readable. Group by keywords, file extensions, size, or date:
|
|
181
|
+
|
|
182
|
+
- *"Move files containing `invoice` or `receipt` to `~/Documents/Invoices/{year}/{month}`"*
|
|
183
|
+
- *"Move `.png` and `.jpg` with `wallpaper` to `~/Pictures/Wallpapers`"*
|
|
184
|
+
- *"Move `.deb`, `.iso`, `.rpm` to `~/Downloads/Installers`"*
|
|
185
|
+
|
|
186
|
+
Edit rules in the desktop GUI or directly via `clutterxp rules add`.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Cheat Sheet
|
|
191
|
+
|
|
192
|
+
| What you want to do | Command |
|
|
193
|
+
|:---|:---|
|
|
194
|
+
| Open the visual desktop app | `clutterxp gui` |
|
|
195
|
+
| Check version | `clutterxp --version` or `cxp --version` |
|
|
196
|
+
| Create default starter config | `clutterxp init` |
|
|
197
|
+
| Test rule matching on a filename | `clutterxp rules test "invoice_march.pdf"` |
|
|
198
|
+
| Preview organization without moving files | `cxp organize ~/Downloads --dry-run` |
|
|
199
|
+
| Organize a folder | `cxp organize ~/Downloads` |
|
|
200
|
+
| Undo the last batch of moves | `cxp undo` |
|
|
201
|
+
| Watch a folder and sort new files automatically | `cxp watch` |
|
|
202
|
+
| Install background watcher service | `cxp service install` |
|
|
203
|
+
| Check background service status | `cxp service status` |
|
|
204
|
+
| Scan for duplicate files | `cxp duplicates scan ~/Downloads` |
|
|
205
|
+
| Check system health and file integrity | `cxp doctor` |
|
|
206
|
+
| View organization history | `cxp history` |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Dependencies
|
|
211
|
+
|
|
212
|
+
- **Python**: `>= 3.10`
|
|
213
|
+
- **Core CLI**: `typer`, `pydantic`, `ruamel.yaml`, `watchdog`, `platformdirs`
|
|
214
|
+
- **Optional GUI**: `PySide6` (`pip install "clutterxp[gui]"`)
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/aigo-admin/clutterxp/0ec772e48eaf1022d81824e19f89d171e1df8640/assets/clutterxp_logo.png" alt="ClutterXP Logo" width="240">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">ClutterXP</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Configurable, safe, lightweight file organizer for Linux.</strong><br>
|
|
9
|
+
Tidies downloads, documents, and messy directories into place—on your terms, with zero risk of file loss.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
| Category | Badges |
|
|
15
|
+
|:---|:---|
|
|
16
|
+
| **Package** | [](https://pypi.org/project/clutterxp/) [](https://pypi.org/project/clutterxp/) [](https://github.com/aigo-admin/clutterxp/blob/main/LICENSE) |
|
|
17
|
+
| **Quality** | [](https://github.com/aigo-admin/clutterxp) [](https://github.com/astral-sh/ruff) [](http://mypy-lang.org/) |
|
|
18
|
+
| **Safety** | [](https://github.com/aigo-admin/clutterxp) [](https://github.com/aigo-admin/clutterxp) |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## What is it?
|
|
23
|
+
|
|
24
|
+
**ClutterXP** is a modern, fast, and reliable file organization toolkit designed for developers, power users, and everyday Linux users who want an organized workspace. Whether your `Downloads` folder is buried under months of receipts, PDFs, installers, wallpapers, and screenshots, or you want background auto-sorting for incoming files, ClutterXP handles the job with ironclad safety guarantees:
|
|
25
|
+
|
|
26
|
+
- **Never deletes or overwrites**: Files only move when the destination is safe. If a file with the same name exists, ClutterXP automatically renames the incoming file (e.g., `report (1).pdf`) or skips it. Your existing files are never destroyed.
|
|
27
|
+
- **Only moves what you tell it to**: If a file does not match a configured rule, it stays untouched in its original location. No unexpected moves, no mystery dump directories.
|
|
28
|
+
- **One-click instant undo**: Every operation is logged in an ACID SQLite journal. Run `clutterxp undo` (or click Undo in the GUI) to restore files to their exact original locations.
|
|
29
|
+
- **100% private and offline**: Operates entirely on your local machine. No tracking, no cloud telemetry, and zero network calls.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Table of Contents
|
|
34
|
+
|
|
35
|
+
- [Main Features](#main-features)
|
|
36
|
+
- [Where to Get It](#where-to-get-it)
|
|
37
|
+
- [Quickstart: Desktop App](#quickstart-desktop-app)
|
|
38
|
+
- [Quickstart: Command Line](#quickstart-command-line)
|
|
39
|
+
- [Background Watcher Daemon](#background-watcher-daemon)
|
|
40
|
+
- [Duplicate File Quarantine](#duplicate-file-quarantine)
|
|
41
|
+
- [Customize Your Rules](#customize-your-rules)
|
|
42
|
+
- [Cheat Sheet](#cheat-sheet)
|
|
43
|
+
- [Dependencies](#dependencies)
|
|
44
|
+
- [License](#license)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Main Features
|
|
49
|
+
|
|
50
|
+
- **Modern Minimalist Desktop App**: Clean obsidian-dark interface with one-click presets, visual plan previews, and real-time rule match testing.
|
|
51
|
+
- **Token-Aware Rule Engine**: Intelligent keyword matching that understands camelCase, PascalCase, hyphenated names, and compound extensions (e.g. `.tar.gz`).
|
|
52
|
+
- **Background Watcher**: Monitors designated folders using inotify with built-in settle and debounce to ensure browser downloads finish before moving.
|
|
53
|
+
- **Duplicate Detector & Safe Quarantine**: Multi-stage duplicate detection (size -> hardlinks -> head/tail partial hash -> streaming SHA-256) with safe quarantine isolation.
|
|
54
|
+
- **Instant LIFO Batch Undo**: Complete rollback capability for any batch of moves or quarantine actions.
|
|
55
|
+
- **Dual CLI Aliases**: Use full `clutterxp` or short alias `cxp` interchangeably.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Where to Get It
|
|
60
|
+
|
|
61
|
+
### Binary Installation via PyPI
|
|
62
|
+
|
|
63
|
+
Install ClutterXP using Python 3.10+:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Recommended: install with modern desktop app (GUI) support
|
|
67
|
+
pip install "clutterxp[gui]"
|
|
68
|
+
|
|
69
|
+
# CLI-only lightweight install
|
|
70
|
+
pip install clutterxp
|
|
71
|
+
|
|
72
|
+
# Or on Kali Linux / Debian / Ubuntu via pipx:
|
|
73
|
+
pipx install "clutterxp[gui]"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Quickstart: Desktop App
|
|
79
|
+
|
|
80
|
+
Launch the visual application with:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
clutterxp gui
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The desktop app provides:
|
|
87
|
+
- **Interactive Plan Preview**: Review every planned move with clear status badges before touching any files.
|
|
88
|
+
- **Rule Editor with Presets**: One-click setup for common categories (Invoices, Photos, Installers) plus live matching test as you type.
|
|
89
|
+
- **Duplicate Quarantine**: Safely isolate duplicate downloads without risking accidental deletion.
|
|
90
|
+
- **Batch History & Undo**: Restore any previous batch with a single click.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Quickstart: Command Line
|
|
95
|
+
|
|
96
|
+
Prefer the terminal? Use `clutterxp` or the shorthand `cxp`:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# 1. Create your default starter config
|
|
100
|
+
clutterxp init
|
|
101
|
+
|
|
102
|
+
# 2. Test which rule matches a filename
|
|
103
|
+
clutterxp rules test "invoice_march.pdf"
|
|
104
|
+
|
|
105
|
+
# 3. Preview what would be organized (dry-run, touches nothing)
|
|
106
|
+
clutterxp organize ~/Downloads --dry-run
|
|
107
|
+
|
|
108
|
+
# 4. Organize your Downloads folder
|
|
109
|
+
clutterxp organize ~/Downloads --yes
|
|
110
|
+
|
|
111
|
+
# 5. Changed your mind? Undo the entire batch instantly!
|
|
112
|
+
clutterxp undo --yes
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Background Watcher Daemon
|
|
118
|
+
|
|
119
|
+
Turn on automatic sorting. When a new file is downloaded or moved into a watched folder, ClutterXP waits until it is fully written to disk, then quietly sorts it into place:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
clutterxp watch
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
You can also install it as a systemd user service:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
clutterxp service install
|
|
129
|
+
clutterxp service status
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Duplicate File Quarantine
|
|
135
|
+
|
|
136
|
+
Identify duplicate files taking up storage and safely isolate them:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
clutterxp duplicates scan ~/Downloads
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Customize Your Rules
|
|
145
|
+
|
|
146
|
+
Rules are clean and human-readable. Group by keywords, file extensions, size, or date:
|
|
147
|
+
|
|
148
|
+
- *"Move files containing `invoice` or `receipt` to `~/Documents/Invoices/{year}/{month}`"*
|
|
149
|
+
- *"Move `.png` and `.jpg` with `wallpaper` to `~/Pictures/Wallpapers`"*
|
|
150
|
+
- *"Move `.deb`, `.iso`, `.rpm` to `~/Downloads/Installers`"*
|
|
151
|
+
|
|
152
|
+
Edit rules in the desktop GUI or directly via `clutterxp rules add`.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Cheat Sheet
|
|
157
|
+
|
|
158
|
+
| What you want to do | Command |
|
|
159
|
+
|:---|:---|
|
|
160
|
+
| Open the visual desktop app | `clutterxp gui` |
|
|
161
|
+
| Check version | `clutterxp --version` or `cxp --version` |
|
|
162
|
+
| Create default starter config | `clutterxp init` |
|
|
163
|
+
| Test rule matching on a filename | `clutterxp rules test "invoice_march.pdf"` |
|
|
164
|
+
| Preview organization without moving files | `cxp organize ~/Downloads --dry-run` |
|
|
165
|
+
| Organize a folder | `cxp organize ~/Downloads` |
|
|
166
|
+
| Undo the last batch of moves | `cxp undo` |
|
|
167
|
+
| Watch a folder and sort new files automatically | `cxp watch` |
|
|
168
|
+
| Install background watcher service | `cxp service install` |
|
|
169
|
+
| Check background service status | `cxp service status` |
|
|
170
|
+
| Scan for duplicate files | `cxp duplicates scan ~/Downloads` |
|
|
171
|
+
| Check system health and file integrity | `cxp doctor` |
|
|
172
|
+
| View organization history | `cxp history` |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Dependencies
|
|
177
|
+
|
|
178
|
+
- **Python**: `>= 3.10`
|
|
179
|
+
- **Core CLI**: `typer`, `pydantic`, `ruamel.yaml`, `watchdog`, `platformdirs`
|
|
180
|
+
- **Optional GUI**: `PySide6` (`pip install "clutterxp[gui]"`)
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
[MIT](LICENSE)
|
|
Binary file
|
|
@@ -44,6 +44,13 @@ cxp = "clutterxp.cli.app:main"
|
|
|
44
44
|
[project.gui-scripts]
|
|
45
45
|
clutterxp-gui = "clutterxp.gui.app:main"
|
|
46
46
|
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = "https://github.com/aigo-admin/clutterxp"
|
|
49
|
+
Documentation = "https://github.com/aigo-admin/clutterxp#readme"
|
|
50
|
+
Repository = "https://github.com/aigo-admin/clutterxp.git"
|
|
51
|
+
"Issue Tracker" = "https://github.com/aigo-admin/clutterxp/issues"
|
|
52
|
+
Changelog = "https://github.com/aigo-admin/clutterxp/blob/main/CHANGELOG.md"
|
|
53
|
+
|
|
47
54
|
[tool.hatch.version]
|
|
48
55
|
path = "src/clutterxp/__init__.py"
|
|
49
56
|
|
clutterxp-1.2.0/PKG-INFO
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: clutterxp
|
|
3
|
-
Version: 1.2.0
|
|
4
|
-
Summary: Configurable, safe, lightweight file organizer: rules, preview, undo, watch, duplicates.
|
|
5
|
-
Keywords: automation,cli,downloads,file-organizer,linux
|
|
6
|
-
Classifier: Environment :: Console
|
|
7
|
-
Classifier: Operating System :: POSIX :: Linux
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Topic :: System :: Filesystems
|
|
10
|
-
Classifier: Topic :: Utilities
|
|
11
|
-
Requires-Python: >=3.10
|
|
12
|
-
Requires-Dist: platformdirs>=4.0
|
|
13
|
-
Requires-Dist: pydantic>=2.6
|
|
14
|
-
Requires-Dist: ruamel-yaml-clib>=0.2.12; platform_python_implementation == 'CPython'
|
|
15
|
-
Requires-Dist: ruamel-yaml>=0.18
|
|
16
|
-
Requires-Dist: typer>=0.12
|
|
17
|
-
Requires-Dist: watchdog>=4.0
|
|
18
|
-
Provides-Extra: dev
|
|
19
|
-
Requires-Dist: build>=1.0; extra == 'dev'
|
|
20
|
-
Requires-Dist: hypothesis>=6.100; extra == 'dev'
|
|
21
|
-
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
22
|
-
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
23
|
-
Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
|
|
24
|
-
Requires-Dist: pytest>=8; extra == 'dev'
|
|
25
|
-
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
26
|
-
Provides-Extra: gui
|
|
27
|
-
Requires-Dist: pyside6>=6.6; extra == 'gui'
|
|
28
|
-
Description-Content-Type: text/markdown
|
|
29
|
-
|
|
30
|
-
# ClutterXP
|
|
31
|
-
|
|
32
|
-
> **Tired of a messy Downloads folder?** ClutterXP quietly tidies your files into the right place—on your terms, without ever losing a single file.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
Whether your `Downloads` folder is buried under months of receipts, PDFs, wallpapers, installers, and screenshots, or you just want your desktop kept neat, **ClutterXP** does the heavy lifting for you.
|
|
37
|
-
|
|
38
|
-
Use the **clean visual desktop app** or run quick commands from your terminal.
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## 🛡️ Why you can actually trust it
|
|
43
|
-
|
|
44
|
-
Most file cleanup tools feel risky—what if they delete something important or move a file you didn't want touched? We built ClutterXP with ironclad safety guarantees:
|
|
45
|
-
|
|
46
|
-
- **Never deletes or overwrites**: Files only move if the destination is safe. If a file with the same name already exists, ClutterXP renames the new one (e.g. `report (1).pdf`) or skips it. Your existing files are never replaced or destroyed.
|
|
47
|
-
- **Only moves what you tell it to**: If a file doesn't match a rule you created, it stays exactly where it is. No surprise moves, no mystery "unsorted" dump folders.
|
|
48
|
-
- **One-click instant undo**: Every action is saved in a local journal. If you ever change your mind, `clutterxp undo` (or a single click in the app) puts every file right back where it was originally.
|
|
49
|
-
- **100% private and offline**: Runs completely on your machine. No accounts, no cloud sync, no tracking, and zero internet requests.
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## ⚡ Getting Started
|
|
54
|
-
|
|
55
|
-
### 1. Installation
|
|
56
|
-
|
|
57
|
-
Install ClutterXP with Python (3.10+):
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
# Recommended: install with desktop app (GUI) support
|
|
61
|
-
pip install "clutterxp[gui]"
|
|
62
|
-
|
|
63
|
-
# Or on Kali Linux / Debian using pipx:
|
|
64
|
-
pipx install .
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 2. Choose how you want to use it
|
|
68
|
-
|
|
69
|
-
#### Option A: The Desktop App
|
|
70
|
-
Just run:
|
|
71
|
-
```bash
|
|
72
|
-
clutterxp gui
|
|
73
|
-
```
|
|
74
|
-
You'll get an intuitive dashboard where you can:
|
|
75
|
-
- **Preview moves before they happen** with a clear interactive table.
|
|
76
|
-
- **Set up simple rules** with live matching tests (type a filename and see which rule catches it instantly).
|
|
77
|
-
- **Find duplicate files** and safely quarantine them without risking accidental deletion.
|
|
78
|
-
- **Undo any batch** with a single button.
|
|
79
|
-
|
|
80
|
-
#### Option B: The Terminal (Fast & Scriptable)
|
|
81
|
-
Prefer working from the command line? Use `clutterxp` or the short alias `cxp`:
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
# 1. Create your default starter config
|
|
85
|
-
clutterxp init
|
|
86
|
-
|
|
87
|
-
# 2. Test which rule matches a filename
|
|
88
|
-
clutterxp rules test "invoice_march.pdf"
|
|
89
|
-
|
|
90
|
-
# 3. Preview what would be organized (dry-run, touches nothing)
|
|
91
|
-
clutterxp organize ~/Downloads --dry-run
|
|
92
|
-
|
|
93
|
-
# 4. Organize your Downloads folder
|
|
94
|
-
clutterxp organize ~/Downloads --yes
|
|
95
|
-
|
|
96
|
-
# 5. Changed your mind? Undo the entire batch instantly!
|
|
97
|
-
clutterxp undo --yes
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Features that make life easier
|
|
103
|
-
|
|
104
|
-
### Set it and forget it (Background Watcher)
|
|
105
|
-
Turn on automatic sorting. Whenever a new download finishes, ClutterXP waits until it's completely written to disk, then quietly sorts it into place.
|
|
106
|
-
```bash
|
|
107
|
-
clutterxp watch
|
|
108
|
-
```
|
|
109
|
-
You can even enable it as a system background service:
|
|
110
|
-
```bash
|
|
111
|
-
clutterxp service install
|
|
112
|
-
clutterxp service status
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Find and clean duplicate downloads
|
|
116
|
-
Downloaded the same PDF or installer three times? ClutterXP safely identifies duplicate files taking up storage, shows you where they live, and lets you isolate them safely.
|
|
117
|
-
```bash
|
|
118
|
-
clutterxp duplicates scan ~/Downloads
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Customize your rules in seconds
|
|
122
|
-
Rules are dead simple. Group by keywords, file extensions, size, or age:
|
|
123
|
-
- *"Move anything with `invoice` or `receipt` to `~/Documents/Invoices`"*
|
|
124
|
-
- *"Move `.png` and `.jpg` with `wallpaper` to `~/Pictures/Wallpapers`"*
|
|
125
|
-
- *"Move `.deb`, `.iso`, `.rpm` to `~/Downloads/Installers`"*
|
|
126
|
-
|
|
127
|
-
You can edit them directly in the visual app or via `clutterxp rules add`.
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Cheat Sheet
|
|
132
|
-
|
|
133
|
-
| What you want to do | Command |
|
|
134
|
-
|:---|:---|
|
|
135
|
-
| Open the visual desktop app | `clutterxp gui` |
|
|
136
|
-
| Preview organization without moving files | `cxp organize ~/Downloads --dry-run` |
|
|
137
|
-
| Organize a folder | `cxp organize ~/Downloads` |
|
|
138
|
-
| Undo the last batch of moves | `cxp undo` |
|
|
139
|
-
| Watch a folder and sort new files automatically | `cxp watch` |
|
|
140
|
-
| Install background watcher service | `cxp service install` |
|
|
141
|
-
| Scan for duplicate files | `cxp duplicates scan ~/Downloads` |
|
|
142
|
-
| Check system health and file integrity | `cxp doctor` |
|
|
143
|
-
| View organization history | `cxp history` |
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## License
|
|
148
|
-
|
|
149
|
-
MIT
|