Files
plugin-helper/docs/ROADMAP.md
T
2026-06-29 10:56:57 -07:00

104 lines
5.8 KiB
Markdown

# plugin-helper Roadmap
This roadmap tracks ideas that are useful but not part of the first safe CLI slice.
## Current Direction
The initial tool should stay conservative:
- Python owns instance discovery, dry-run plans, activation, install state, uninstall, and `UserData` backups.
- Release assets are selected through registry and lockfile data.
- Prefer upstream GitHub release artifacts for normal plugins. Use BeatMods as
compatibility/dependency metadata, and as an artifact source only for
inaccessible upstream artifacts, BeatMods-only packages, or framework/library
dependencies.
- Mutating operations apply an explicit plan and record exact file hashes.
- Nix packages `plugin-helper`, but does not directly manage the mutable Beat Saber tree.
This works well while Beat Saber is launched from either the local Linux
BSManager install or a mounted Windows BSManager filesystem.
For the near term, the Python state model should treat target roots as distinct
installations even when they share an instance name. Lockfiles can stay keyed by
Beat Saber version, but bootstrap state, generated plans, backups, and
`installed.json` need to stay target-specific.
## Future: Nix-Orchestrated Plugin Sets
Once Beat Saber is running on Linux through Steam Proton, it may make sense to let Nix orchestrate the plugin payload itself.
The core idea:
```text
Nix flake / plugin set
fetch exact GitHub release assets
verify hashes
unpack and normalize Plugins/, Libs/, IPA/Pending/
produce /nix/store/...-beatsaber-plugins-<game-version>/
plugin-helper
run nix build .#pluginSets.<game-version>
compare the resulting tree to the target Beat Saber instance
create a normal dry-run plan
copy or link files into the instance
record activation state
```
In that model, the plugin folder effectively gets a reproducible lock:
- `flake.lock` pins Nix inputs.
- A plugin-set definition pins plugin repositories, tags, release assets, and hashes.
- The generated Nix output is a canonical, immutable plugin tree for one Beat Saber version.
- `plugin-helper` remains the safety layer around activation and rollback.
## Why Wait For Proton
For the current dual-boot Windows path, a pure Nix-store plugin tree is awkward:
- Windows cannot use `/nix/store` paths directly.
- Linux symlinks inside a mounted Windows filesystem may not behave the way native Windows Beat Saber expects.
- Some plugins may create or expect colocated mutable files.
When running through Proton on Linux, Nix-store outputs and symlink activation become much more practical. Even then, `copy` mode should remain available for plugins that expect writable colocated files.
## Activation Modes
A future Nix-backed planner should support at least these activation modes:
- `copy`: materialize files into the Beat Saber instance. Best compatibility, including mounted Windows trees.
- `symlink`: link plugin files from the Nix output. Best reproducibility and cleanup on Linux/Proton.
- `materialize`: link immutable files where safe and copy known-mutable files.
All modes should still produce the same kind of explicit plan before applying.
## Proposed Milestones
1. Keep the Python safety harness stable: scan, plan, apply, uninstall, and backups.
2. Model BSIPA bootstrap as a first-class install phase, preferring upstream GitHub release artifacts while preserving BeatMods `zipHash`/version metadata when used for verification or fallback.
3. Resolve BeatMods dependency closures by mod-version id for verified mods before ordinary batch planning, but keep artifact sourcing GitHub-preferred.
4. Model one real plugin end to end with the current TOML lockfile and local asset planning.
5. Add a Nix function that fetches and unpacks one locked plugin asset into a normalized tree.
6. Generate a full plugin-set derivation for one Beat Saber version.
7. Teach `plugin-helper plan` to compare a Nix output tree against an instance.
8. Add `--activation-mode copy|symlink|materialize`.
9. Move compatibility and dependency metadata toward shared data that both Python and Nix can consume.
## Warning Follow-Ups From 1.44.1 Bootstrap
The first 1.44.1 BSIPA/SongCore smoketest worked, but it produced warnings worth tracking separately from install success:
- BSML, SiraUtil, and SongCore have older target game-version metadata even though BeatMods verifies the selected releases for 1.44.1. Decide whether plugin-helper should treat BeatMods verification as a compatibility override.
- The first bootstrap used BeatMods CDN artifacts for speed. BSIPA, BSML, and SiraUtil have now been matched to byte-identical upstream GitHub release assets. SongCore remains a BeatMods CDN fallback because the BeatMods preferred repo `Kylemc1413/SongCore` currently exposes no matching 3.16.0 GitHub release asset.
- BSML reports missing Windows fonts under Proton. This is likely cosmetic, but may affect Unicode text rendering in mod UI.
- SongCore warns that `Beat Saber_Data/CustomWIPLevels/Cache` has no `Info.dat`. Either create the expected cache directory shape or classify this warning as harmless.
- SongCore could not read the audio rate for the built-in `Magic.wav` custom level and approximated duration from map length. Check whether this is a bundled-song oddity or a broader audio metadata issue.
- The smoketest launcher can leave Beat Saber running after timeout. Prefer explicit teardown and consider a helper command that starts, watches logs, and kills the process tree deterministically.
## Open Questions
- Should the human-edited source of truth be TOML, Nix, or TOML that generates Nix?
- How should plugin-specific unpack rules be represented without making Nix expressions too noisy?
- Which plugin files are known to need mutability after install?
- Should the Nix output include BSIPA itself, or continue assuming BSIPA is provided by the game instance manager?
- How should updates be proposed: Python querying GitHub, Nix update scripts, or both?