3.3 KiB
Findings
-
Resolved: install state is now keyed by concrete
install_id, and reusable plugin assets live under the shared download cache instead of per-install state. -
Medium-high: dependency handling is intentionally thin.
Dependency.constraintexists in models.py, but planner.py only expands required dependency IDs and does not enforce constraints, conflicts,loadAfter,loadBefore, BeatMods version-id closures, or “provides” relationships. That is the next big unlock for package-manager behavior. -
Medium: the agent skills have a few stale or conflicting operational rules. The manager skill still tells agents to inspect/edit
registry/plugins.tomlin .agents/skills/beatsaber-plugin-manager/SKILL.md, while the project has moved toregistry/plugins/*.toml. The builder skill says PR checkouts go under<state_dir>/buildin .agents/skills/beatsaber-plugin-builder/SKILL.md, whileAGENTS.mdsays GitHub plugin source checkouts should live under~/src/<owner>/<repo>. That will make agents inconsistent.
Skills
I would not collapse the three skills into one. They are conceptually different:
beatsaber-plugin-manager: mutating install/update/bootstrap workflow.beatsaber-plugin-update-auditor: read-mostly audit/report workflow.beatsaber-plugin-builder: source build workflow.
But I would consolidate shared policy into references, then have each skill import that mental model:
references/repo-workflow.md: repo root,.venv,PYTHONPATH=src, dirty worktree rules, validation commands.references/state-and-profiles.md:.state, profiles, install identity, source checkout location.references/artifact-policy.md: GitHub first, BeatMods metadata/fallback, private sources, checksum policy.references/live-validation.md: smoketest and process cleanup.
That removes duplicated drift while preserving good trigger boundaries.
Design Direction
Yes, the script design is useful. The best parts are exactly the right bones for a real package manager: registry, locks, dry-run plans, hash checks, managed install state, bootstrap as its own phase, update audit, and known-good sets.
The next shape I’d aim for is:
packages/registry: identity, source aliases, install strategy, metadata extraction rules.versions/locks: selected package versions/artifacts/evidence for each Beat Saber version.cache/downloads: content-addressed artifacts reusable across installs.installs/<install_id>: installed packages, transactions, bootstrap, known-good generations, backups.- commands like
resolve,fetch,plan,apply,rollback,audit,verify.
Beat Saber plugins are heterogeneous in packaging, but homogeneous enough in runtime shape (Plugins, Libs, IPA/Pending, root BSIPA files) that this can become a nice small package manager. The trick is to normalize artifacts into a planned file tree before touching the game.
Validation: compileall passed, and unittest discover passed: 75 tests, 1 skipped.