Commit Graph

716 Commits

Author SHA1 Message Date
e3e5002d35 Stricter duplicate detection: 5 lines, 25 tokens, 0% threshold
- Auto-installs jscpd if missing
- Blocks commit on any duplication detected
- Current repo has 48 clones that need refactoring
2025-12-11 17:33:35 +01:00
dc577473aa Add duplicate code detection to pre-commit hook
Uses jscpd to detect code clones in shell scripts.
Blocks commit if duplication exceeds 5% threshold.
Suggests extracting common code to scripts/lib/common.sh.
2025-12-11 17:31:47 +01:00
348a56906c Add compulsive opening blocker for messaging apps
Limits beeper, signal-desktop, and discord to one launch per hour.
Shows notification when blocked. Tracks state in ~/.local/state/compulsive-block/.

Features:
- install/uninstall commands (handles both files and symlinks)
- status command to view current state
- reset/reset-all to allow reopening within the hour
- Follows existing wrapper pattern from youtube-music-wrapper.sh
2025-12-11 17:28:25 +01:00
b5c6e33c05 feat: scripts for converting mp4 to webm and inverse 2025-12-11 17:10:54 +01:00
7925f0f1f9 Fix focus app detection to use window titles instead of process names
- Changed from pgrep -f (matches any process with 'code' in cmdline) to
  xdotool window detection (only matches visible windows)
- VS Code background services (code-tunnel, etc.) no longer trigger blocking
- Music is only blocked when VS Code window is actually open
- Split detection into FOCUS_APPS_WINDOWS and FOCUS_APPS_PROCESSES arrays
2025-12-07 16:01:14 +01:00
f392ce0d31 Fix youtube-music wrapper to point to .real binary 2025-12-07 14:42:21 +01:00
aab2c1acbc Add instant mode for near-instantaneous music app termination
- New 'instant' mode polls every 0.5 seconds (vs 3s for regular mode)
- Made instant mode the default for the systemd service
- Added youtube-music-wrapper.sh to block launch when focus apps running
- YouTube Music killed within 0.5 seconds of opening
2025-12-07 14:40:42 +01:00
f805be2f0f Revert to SIGKILL (-9) for reliable music app termination 2025-12-07 14:37:20 +01:00
17899e3721 Use gentler SIGTERM instead of SIGKILL for music apps 2025-12-07 14:36:11 +01:00
88a6b5db4a Reduce music parallelism check interval from 10s to 3s 2025-12-07 14:35:04 +01:00
a1407338aa Fix music parallelism log to use user directory instead of /var/log 2025-12-07 14:34:23 +01:00
8800d502ae Fix music parallelism: add youtube-music Electron app detection and use SIGKILL
- Added 'youtube-music' and 'YouTube Music' patterns to detect Electron app
- Added explicit killing of youtube-music process
- Use SIGKILL (-9) to ensure apps are actually terminated
- Fixed log function to not fail on permission errors
2025-12-07 14:31:36 +01:00
774c28b7a7 Add music parallelism prevention script
Prevents multitasking between focus work and music streaming.
When focus apps (VS Code, Steam, Godot, etc.) are detected running
alongside music services (YouTube Music, Spotify, etc.), the music
is automatically stopped.

Features:
- Monitors for focus applications (IDEs, games, creative software)
- Detects music streaming via browser tabs and native apps
- Closes music windows/processes when conflict detected
- Desktop notifications when music is stopped
- Status command to check current state
- Systemd service for background monitoring
2025-12-07 14:27:19 +01:00
7c15b2d3aa Add multi-layer protection to shutdown timer monitor
- Add RefuseManualStop=true to prevent systemctl stop
- Add RestartForceExitStatus to restart even on SIGTERM/SIGKILL
- Add watchdog timer that checks monitor every 60 seconds
- Watchdog also restarts the main timer if stopped
- Tested: manual stop refused, pkill auto-restarts, timer tampering detected
2025-12-07 14:20:05 +01:00
92cc79a972 Add shutdown timer monitor service to prevent disabling
- Remove 'disable' option from setup_midnight_shutdown.sh
- Add shutdown-timer-monitor.sh that watches the timer every 30s
- Re-enables timer automatically if someone tries to disable it
- Monitor service installed alongside the timer
- Makes it significantly harder to bypass the shutdown schedule
- Similar pattern to hosts-file-monitor.service
2025-12-07 14:08:13 +01:00
1f70c21007 Add custom entries protection to hosts install.sh
- Track custom blocked entries in /etc/hosts.custom-entries.state
- Block installation if any previously blocked entries are removed
- No bypass option - manual chattr removal required for changes
- Protects against impulsive unblocking of sites
- State file is also protected with chattr +i
2025-12-07 14:01:41 +01:00
8fcf1c0b07 Add original monolithic Nextcloud setup script
This is the original all-in-one script that was later split into:
- raspberry_pi_flash_sd.sh (SD card flashing)
- raspberry_pi_nextcloud.sh (Nextcloud installation)

Kept for reference and as an alternative single-script deployment option.
2025-12-05 20:01:53 +01:00
4762281985 Add Raspberry Pi 5 Nextcloud deployment scripts
- raspberry_pi_flash_sd.sh: Flash RPi OS to SD card (local/remote)
  - Auto-discovers SD cards on local or remote systems
  - Configures headless SSH access with auto-generated passwords
  - Supports flashing via remote laptop with SD card reader

- raspberry_pi_nextcloud.sh: Install and configure Nextcloud
  - Automated installation of Nextcloud with Apache, MariaDB, Redis
  - DuckDNS + Let's Encrypt for publicly trusted HTTPS
  - Security hardening: HSTS, cron jobs, default phone region
  - Auto-generated admin credentials stored in config file
  - fix command for security warnings
  - setup-ssl-remote for Let's Encrypt via DuckDNS

Includes shellcheck compliance with appropriate directives.
2025-12-05 20:00:30 +01:00
0e24f62d9a Add gitignore for Raspberry Pi config files with passwords 2025-12-05 19:57:57 +01:00
2eacdc07dc Add greylist support for challenge-required packages
- Create pacman_greylist.txt with virtualbox as initial entry
- Add is_greylisted_package_name() for substring matching
- Add remove_installed_greylisted_packages() to auto-uninstall
- Replace hardcoded VirtualBox check with generic greylist check
- Update installer to copy greylist file
2025-12-04 21:33:29 +01:00
6a34098ad7 music_gen: add segmented generation, Bark vocals, and song mixing
- Add segmented generation with crossfading for long audio (>30s)
- Add Bark integration for speech/vocal generation (--speech flag)
- Add full song generation with vocals over instrumental (--song flag)
- Auto-select MusicGen model size based on available VRAM
- Enforce CUDA for NVIDIA GPUs (no CPU fallback)
- Update README with new features and examples
2025-12-04 21:26:52 +01:00
553593e085 gitignore: add music_gen output folder 2025-12-04 20:59:13 +01:00
0d577e393c music_gen: force CUDA for NVIDIA GPUs, auto-select model by VRAM
- Fail fast if NVIDIA GPU detected but CUDA unavailable (no CPU fallback)
- Auto-select largest model based on VRAM (large=12GB+, medium=8GB+)
- Remove torchaudio dependency (scipy handles audio I/O)
- Use safetensors format to avoid torch.load security issues
2025-12-04 20:57:50 +01:00
39d0405a6b Add local AI music generator using Meta's MusicGen
Features:
- Generate music from text prompts using open-source MusicGen model
- Support for small/medium/large models (500MB to 6.5GB)
- CUDA, Apple Silicon MPS, and CPU support
- Interactive mode with example prompts
- Setup script that handles venv and GPU detection

Usage:
  cd python_pkg/music_gen && ./setup.sh
  python music_generator.py 'upbeat electronic dance music'
2025-12-04 20:43:44 +01:00
d72209a77c pre-commit: add hook to remove empty directories
Automatically finds and removes empty directories (excluding .git)
during pre-commit runs to keep the repo clean.
2025-12-04 20:37:16 +01:00
df38784035 Remove workout_log.json and FFmpeg from git tracking
- Add workout_log.json to root .gitignore
- Remove both files from git index (keep local files)
- FFmpeg was already in .gitignore but still tracked
2025-12-04 20:35:00 +01:00
4c05f520ba fix: repair media-organizer.service and prevent future issues
- Add fix_systemctl.sh to repair corrupted media-organizer.service
- Fix setup_media_organizer.sh to use SUDO_USER instead of whoami
  when running with sudo (prevents User/Group being set to root)

The service was failing due to:
1. Corrupted ExecStart path (line break in the middle)
2. Wrong script path (missing 'utils/' directory)
3. User/Group set to root instead of actual user
2025-12-04 20:31:44 +01:00
526362d665 Fix check_and_enable_services.sh and hosts guard
- Fix startup_monitor check to verify timer instead of service
- Fix pacman hooks filename check (10-unlock-etc-hosts.hook, 90-relock-etc-hosts.hook)
- Add re-verification after fixes to update status correctly
- Set immutable attribute before bind mount in pacman-post-relock-hosts.sh
- Add new check_and_enable_services.sh script for verifying all digital wellbeing services
2025-12-04 15:14:50 +01:00
84bdef75b0 screen_locker: enhance workout logging and UI
- Log full workout data (exercises, sets, reps, weights) instead of just type
- Add workout_log.json to gitignore
- Support variable reps per set using + separator (e.g., 12+12+11+11+12)
- Widen exercise name input field from 30 to 50 characters
2025-12-02 23:22:13 +01:00
930b284899 Add comprehensive tests for screen_locker module (100% coverage)
- Add test_screen_lock.py with 65 tests covering:
  - ScreenLocker initialization (demo/production mode)
  - Workout data validation (running and strength)
  - Log file operations (reading/writing JSON)
  - UI state transitions and timer logic
  - ask_workout_type/running_details/strength_details methods
  - Error handling and TclError exceptions

- Add type annotation to workout_data in screen_lock.py

Coverage: 273 statements, 38 branches - 100%
2025-12-02 23:13:36 +01:00
1652c24c1e Add comprehensive tests for stockfish_analysis (100% coverage)
- Create test_analyze_chess_game.py with 90 tests covering all functions
- Add tests for PGN extraction, score conversion, move classification
- Add tests for engine configuration, memory detection, analysis
- Add pragma: no branch for unreachable code paths
- Update pyproject.toml with coverage exclusions
- All pre-commit hooks pass (ruff, mypy, pylint, bandit)
2025-12-02 22:58:06 +01:00
0ce938fec4 Fix test discovery and coverage for python_pkg modules
- Update pytest testpaths: PYTHON -> python_pkg (PYTHON was empty)
- Add missing __init__.py to: stockfish_analysis, screen_locker, extract_links
- Now coverage correctly reports 0% for untested modules:
  - screen_locker/screen_lock.py (279 stmts, 0% coverage)
  - stockfish_analysis/analyze_chess_game.py (327 stmts, 0% coverage)
2025-12-02 22:33:34 +01:00
2518528c86 Expand copilot-instructions with C engine and python_pkg details
- Add C engine build/usage commands and key files
- Document stockfish_analysis, keyboard_coop, mock_server, screen_locker
- List other standalone scripts
2025-12-02 22:18:40 +01:00
945bfce6a5 Add .github/copilot-instructions.md for AI coding agents
Documents:
- Project architecture and cross-language integration
- 100% test coverage requirement and testing commands
- Pre-commit workflow and tool configuration
- Code conventions and test patterns
- Key files and per-file lint ignores
2025-12-02 22:15:22 +01:00
a560341a03 Optimize tests and simplify coverage config
- Optimize slow tests (3.5s -> 0.4s):
  - Mock threading.Thread instead of spawning real threads
  - Use PropertyMock instead of generator-based exception
- Simplify coverage config:
  - Set source to '.' to check all Python files
  - Remove exclude_lines (no special exclusions needed)
2025-12-02 22:12:50 +01:00
87b2602318 Set coverage fail_under=100 and add python_pkg/lichess_bot to sources
- Add python_pkg/lichess_bot to coverage sources
- Set fail_under=100 to enforce 100% test coverage
2025-12-02 22:09:16 +01:00
94fef50913 Achieve 100% test coverage for lichess_bot/main.py
- Refactor loops to use explicit next()/StopIteration for coverage
- Add tests for _collect_analysis_lines with empty and full iterators
- Add tests for _process_game_events_loop with multiple game events
- Add tests for _run_event_loop with limited and unlimited iterations
- Add test for process_analysis_output with error exit but no stderr
- Add test for process_game_finish with invalid data type
- All 85 tests pass with 100% line and branch coverage
2025-12-02 22:03:16 +01:00
38fe3ef53e Add comprehensive tests for lichess_bot main.py and lichess_api.py
- Fix test_process_game_event_game_end to properly mock engine
- Fix test_handle_game tests to mock _run_analysis_subprocess to prevent hanging
- Fix test_process_game_start_event to mock analysis subprocess
- Add test_process_game_event_game_end_after_move to cover game end status path
- Add test_process_game_event_color_unknown_on_gamefull to cover gameFull with spectator
- Add tests for lichess_api.py covering spectator case and join_game_stream edge cases
- Fix mypy type errors with Event and GameThreads type aliases

Coverage:
- lichess_api.py: 100% (was 98%)
- main.py: 99% (branch partials for loop exits only)
2025-12-02 21:53:15 +01:00
90c065eb1d Achieve 100% coverage for lichess_api.py
- Add test for spectator case (neither white nor black)
- Add test for non-gameFull events before gameFull
- Add test for stream ending without gameFull event
2025-12-01 20:46:09 +01:00
3ef256973f feat(tests): add comprehensive tests for lichess_bot engine and API
- Add test_engine.py with 100% coverage for engine.py
  - Tests for Engine class initialization
  - Tests for choose_move with various scenarios
  - Tests for best move parsing and validation
  - Tests for checkmate and stalemate detection

- Add test_lichess_api.py with 98% coverage for lichess_api.py
  - Tests for API initialization and request handling
  - Tests for stream_events with proper infinite loop handling
  - Tests for challenge accept/decline
  - Tests for game streaming and move submission
  - Tests for rate limit handling and retry logic

- Remove unreachable return statement in lichess_api.make_move

Coverage: engine.py 17% -> 100%, lichess_api.py 0% -> 98%
2025-12-01 20:41:51 +01:00
1f20f727d0 refactor(randomize_numbers): use list comprehension to achieve 100% coverage
Replaced for loop with implicit continue with a list comprehension
using walrus operator. This avoids the coverage.py limitation with
partial branch detection on for loop continue statements.

Coverage: 99% -> 100%
2025-12-01 20:19:02 +01:00
57233aa8d5 refactor(keyboard_coop): remove dead/unreachable code
- Remove unreachable force-submit check (line 351): available_letters
  always contains the clicked letter after add(letter)
- Remove unreachable hover color branch (lines 398-404): the available
  check at line 396 catches all available letters first
- Remove unused KEY_HOVER_COLOR constant
- Remove unused mouse_pos variable in _draw_keyboard
- Update test from hover to unavailable key color test

Coverage: 97% -> 100%
2025-12-01 20:15:40 +01:00
4e64c3deef feat(tests): improve keyboard_coop test coverage to 97%
- Add test for JSONDecodeError fallback dictionary loading
- Add test for game initialization (__init__)
- Add tests for handle_click on letter, enter button, and reset button
- Add tests for drawing methods (_draw_text_line, _draw_button, _draw_keyboard, _draw_ui)
- Add extensive tests for game loop (run) covering:
  - QUIT event handling
  - Mouse click events
  - ENTER key submission
  - R key reset
  - Letter key presses
  - Right click ignored
  - Special key ignored
  - Unknown event type ignored

Coverage improved from 58% to 97%. Remaining uncovered lines are:
- Line 351: Unreachable defensive code (force submit when no moves)
- Lines 398-404: Unreachable dead code (hover color branch)
2025-12-01 20:10:41 +01:00
92e15e8909 Improve lichess_bot utils.py test coverage to 100%
- Add tests for _version_file_path environment override
- Add tests for missing and invalid version files
- Add tests for write failure error handling
2025-12-01 20:02:05 +01:00
7acb114fe4 Improve test coverage for multiple modules
- scrape_website: 98% -> 100% (test download returning false)
- tag_divider: 44% -> 100% (test folder creation, image processing)
- extract_links: 61% -> 100% (test main() function directly)
- keyboard_coop: 22% -> 58% (test game logic methods)
2025-12-01 19:59:11 +01:00
5ef944abc9 Add tests for multiple python_pkg modules
- download_cats: Test generate_cats functionality (100% coverage)
- keyboard_coop: Test keyboard_listener with mocked pynput (22% coverage)
- mock_server: Test mitmproxy request interceptor (100% coverage)
- random_jpg: Test JPEG generation with mocked Pillow (100% coverage)
- randomize_numbers: Test random_digits functions (99% coverage)
- scrape_website: Test scrape_comics with mocked requests (98% coverage)
- split: Test text splitting utilities (100% coverage)
- tag_divider: Test tag_divider with mock filesystem (44% coverage)
- extract_links: Add HTML fixture for tests
2025-12-01 19:49:44 +01:00
a3956d856b refactor: clean up pyproject.toml - remove defaults and redundant configs 2025-12-01 16:33:42 +01:00
d24b005809 fix: remove all pylint disable comments and enable all meta checks 2025-12-01 16:22:03 +01:00
81d6dd5315 fix: enable all pylint checks by wrapping scripts in main()
- Remove too-few-public-methods and invalid-name from disabled checks
- Wrap module-level code in main() functions:
  - generate_jpeg.py
  - random_digits.py
  - generate_cats.py
  - scrape_comics.py
- Rename download_image -> _download_image (private function)

Pylint score: 10.00/10 with all checks enabled
2025-12-01 16:15:03 +01:00
0e73b27d50 fix: address all pylint warnings
- R0914 (too many locals): Extract helper functions in generate_jpeg.py,
  engine.py, lichess_api.py, main.py
- R0902 (too many instance attributes): Use dataclasses in keyboard_coop
- W0621 (redefined outer name): Rename parameters/variables to avoid shadowing
- W0201 (attribute outside init): Initialize all attrs in __init__
- R1705 (no-else-return): Remove unnecessary else after return
- C1805 (implicit booleaness): Use implicit boolean checks
- R1732 (consider-using-with): Use context manager for subprocess.Popen
- E0401 (import-error): Add pylint disable for optional deps (selenium, mitmproxy)
- Clean up pyproject.toml: update comments, remove redundant settings

Pylint score: 10.00/10
2025-12-01 16:11:15 +01:00