perf+fix: muse status — eliminate rglob descent, stat cache, single repo.json read
Bugs fixed: - status --short --branch: branch_only was never checked in short mode, causing the full file list to be printed instead of returning early. Fixed by moving the branch_only guard after both the porcelain and short/default header output. - _read_repo_id: no encoding, no error handling (KeyError / FileNotFoundError / JSONDecodeError all unhandled). Replaced with _read_repo_meta() which reads repo.json once with encoding="utf-8" and degrades gracefully on any failure. - registry._read_domain: missing encoding="utf-8" on repo.json read. Fixed. - repo.json read 3x per muse status: _read_repo_id, resolve_plugin, read_domain each triggered an independent read. Now status reads repo.json exactly once via _read_repo_meta(), passes domain to the new resolve_plugin_by_domain(), and reuses the domain string for SnapshotManifest. Total reads: 1. - sys.stdout.isatty() called once per output line (N syscalls). Now computed once before the output loop and captured in a _color() closure. - any([added, modified, deleted]) created an unnecessary list. Changed to the idiomatic `added or modified or deleted`.
Performance: - walk_workdir (snapshot.py): replaced sorted(workdir.rglob("*")) with os.walk + in-place dirnames pruning. Hidden directories (.venv/, .muse/, .git/, node_modules/) are now pruned before os.walk descends into them. Previously rglob visited every file inside those directories — on a Python project with a virtualenv this was tens of thousands of wasted syscalls. os.lstat replaces the separate is_symlink() + is_file() pair (one syscall instead of two per file). - code/plugin.py snapshot(): same rglob → os.walk fix. Also integrates StatCache: files unchanged since the last walk are not re-hashed. Previously every muse status re-computed SHA-256 for every tracked file from scratch. The code plugin also prunes _ALWAYS_IGNORE_DIRS at the dirnames level so __pycache__, node_modules, dist, build etc. are never entered. - midi/plugin.py snapshot(): same os.walk + StatCache integration. - scaffold/plugin.py snapshot(): same os.walk + StatCache integration; also replaces p.read_bytes() + inline sha256 (loads entire file into memory) with the StatCache's chunked 64 KiB reader.
Registry: - Added resolve_plugin_by_domain(domain) — looks up the plugin by domain string without reading the filesystem, for callers that have already read repo.json.
Tests: - Two patches in test_cli_plugin_dispatch.py updated from resolve_plugin to resolve_plugin_by_domain to match the renamed import in status.py.
No comments yet. Be the first to start the discussion.