mirror of
https://github.com/kuhyx/steam-backlog-enforcer.git
synced 2026-11-11 12:27:33 +01:00
The serve rework was sitting untracked: a /proc-based port guard, the start-or-defer decision, and a stale-bundle rebuild. It had no tests, and it changed cmd_serve(_config, state) to cmd_serve(argv) without updating the one test that called it, so the suite was red and coverage was 251 lines short. Tests, all against fakes: - _fake_proc builds a synthetic /proc. _NET_TCP is derived from _PROC at import time, so patch_proc redirects both; patching _PROC alone would have had these tests parse the host's real process table. - _serve_guard is split across two test files to stay under the 250-line cap. os is replaced wholesale in every termination test, so no signal can reach a real process even if the guard's self-protection were removed. - _web_build mocks subprocess entirely and redirects every path constant into tmp_path. _no_subprocess now blocks _web_build.subprocess.run too: an unguarded test would fire a real `npm run build`, rewriting web/dist and perturbing frontend_is_stale() for every later test in the run. Source changes, both required rather than incidental: - _serve_guard's wildcard match was a `# noqa: S104` on a "0.0.0.0" literal, which the no-noqa hook rejects outright. It is now the all-zero hex column /proc actually prints, so the dotted-quad literal never appears. - main/__init__.py's serve dispatch arm was itself uncovered; it now has a test asserting the raw argv passes through unparsed. Also drops the document.hidden guard from useBudgetPoll: it skipped the very first load, so the budget panel sat on "Reading budget state…" forever in a background tab, which is every tab under browser automation. Verified: 1712 python tests, 100% branch coverage; 128 vitest, 100%. The guard's /proc parser was checked read-only against a real listener on :8000 and resolved the same pid as `ss`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKFzwzwRU1JD7SFLHtQBsz |
||
|---|---|---|
| .github/workflows | ||
| docs/explanations | ||
| pacman-hooks | ||
| prompts | ||
| scripts | ||
| steam_backlog_enforcer | ||
| web | ||
| .gitignore | ||
| .mcp.json | ||
| .pre-commit-config.yaml | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| install.sh | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
| run.sh | ||
| steam-backlog-enforcer.service | ||
| TODO-file-length-250.md | ||
Steam Backlog Enforcer
Forces you to 100% complete one Steam game at a time before moving on.
Features
- Achievement tracking: Picks the next game by shortest HLTB completionist time
- Store blocking: Blocks
store.steampowered.comvia/etc/hosts - Game uninstalling: Removes all installed games except the assigned one
- Process enforcement: Kills unauthorized game processes
- Tampering detection: Detects achievement unlocks on non-assigned games
- HLTB integration: Estimates completion time with persistent cache
Setup
python -m python_pkg.steam_backlog_enforcer.main setup
Commands
| Command | Description |
|---|---|
scan |
Scan library, fetch HLTB data, assign game |
check |
Check if assigned game is complete |
status |
Show current assignment and blocking |
list |
List incomplete games from snapshot |
skip |
Skip the currently assigned game |
enforce |
Run enforcer (block, uninstall, kill) |
unblock |
Remove store blocking |
reset |
Reset all state |
installed |
List currently installed Steam games |
uninstall |
Interactively uninstall non-assigned games |
setup |
First-time configuration |
Enforce mode
sudo python -m python_pkg.steam_backlog_enforcer.main enforce
This will:
- Block Steam store in
/etc/hosts - Uninstall all games except the assigned one
- Continuously kill any unauthorized game processes
Game Uninstall
Directly removes appmanifest files and game directories from ~/.local/share/Steam/steamapps/.
Preserves Proton versions and Steam Linux Runtime.
python -m python_pkg.steam_backlog_enforcer.main uninstall
MCP server (Claude Code integration)
The enforcer exposes an MCP server (steam_backlog_enforcer._mcp) so Claude Code
and its subagents can query the backlog and drive it through typed tools.
- Read tools:
get_dataset,get_status,get_stats,list_backlog. - Gated write tools:
pick_manual,block_gaming— each defaults to a dry-run preview; passconfirm=trueto actually apply. These write tools must never be added to a permission allowlist (a subagent could otherwise bypass the human confirmation).
The mcp SDK is an optional dependency (pip install -e '.[mcp]'), kept out of
the CLI/systemd system-python path. One-time setup of the dedicated venv that
Claude Code spawns:
./scripts/setup_mcp.sh
Registration lives in the checked-in .mcp.json (project scope).
Restart Claude Code in this repo and approve the project MCP-server prompt for it
to load. Verify with claude mcp list.