--- name: beatsaber-plugin-manager description: Install or update a Beat Saber plugin in the plugin-helper repo by using the local helper workflow. Use when the user asks to add, install, update, bump, lock, bootstrap BSIPA, or manage a Beat Saber plugin release for a BSManager instance. Prefer upstream GitHub release artifacts for normal plugins; use BeatMods primarily as compatibility/dependency metadata, with CDN artifacts only for inaccessible upstream assets, BeatMods-only packages, or framework/library dependencies. --- # Beat Saber Plugin Installer Use the repository's own `plugin-helper` commands to manage plugins for BSManager instances whenever the helper supports the operation. Before acting, read the shared policy references: - [repo-workflow.md](../references/repo-workflow.md) for repo root, `.venv`, `PYTHONPATH=src`, dirty worktree handling, and validation commands. - [state-and-profiles.md](../references/state-and-profiles.md) for `.state`, profiles, install identity, instance selection, and checkout locations. - [artifact-policy.md](../references/artifact-policy.md) for GitHub/BeatMods/private-source/checksum/bootstrap policy. - [live-validation.md](../references/live-validation.md) for smoke tests, logs, and process cleanup. ## Workflow 1. Confirm the workspace is the `plugin-helper` repo. ```bash test -f pyproject.toml && test -d src/plugin_helper && test -d registry && test -d locks ``` 2. Read the local helper behavior before changing files. Inspect at least: ```bash sed -n '1,220p' README.md sed -n '1,260p' src/plugin_helper/cli.py sed -n '1,260p' src/plugin_helper/planner.py sed -n '1,220p' src/plugin_helper/models.py sed -n '1,220p' registry/plugins.toml sed -n '1,220p' locks/.lock.toml sed -n '1,220p' docs/SMOKETEST.md ``` 3. Determine the instance. Prefer the instance the user names. If omitted, use the latest available BSInstance unless the current task context clearly points at another instance: ```bash PYTHONPATH=src .venv/bin/python -m plugin_helper instances ``` 4. Resolve the release source. For BeatMods bootstrap or verified packages, query BeatMods with a browser-like user agent: ```bash PYTHONPATH=src .venv/bin/python - <<'PY' import json, urllib.request from plugin_helper.beatmods import by_version_id, normalize_mods game_version = "" url = f"https://beatmods.com/api/mods?status=verified&gameVersion={game_version}&gameName=BeatSaber&platform=steampc" req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 plugin-helper"}) with urllib.request.urlopen(req, timeout=20) as response: data = json.load(response) mods = normalize_mods(data) mods_by_version_id = by_version_id(mods) print(json.dumps( [ { "name": mod.name, "modId": mod.mod_id, "gitUrl": mod.git_url, "category": mod.category, "versionId": mod.version_id, "modVersion": mod.mod_version, "zipHash": mod.zip_hash, "dependencies": mod.dependencies, "dependencyNames": [ mods_by_version_id[dep].name for dep in mod.dependencies if dep in mods_by_version_id ], } for mod in mods ], indent=2, )[:20000]) PY ``` Follow the artifact policy for GitHub-first sourcing, BeatMods exceptions, and dependency closure. BeatMods CDN URLs are: ```text https://beatmods.com/cdn/mod/.zip ``` For GitHub URLs, resolve the release from the user-provided repository or release URL only. Derive `/` and optional `` from the URL. Query the GitHub API directly for metadata: ```bash curl -sS https://api.github.com/repos///releases curl -sS https://api.github.com/repos///releases/tags/ ``` Pick the asset that matches the Beat Saber instance/version. Prefer an exact versioned asset such as `1.40.8.zip` over broad or source archives. If multiple plausible assets remain, ask the user. 5. Inspect the asset before selecting an install strategy. Download to the helper state directory: ```bash mkdir -p .state/instances//downloads/ curl -L --fail -o .state/instances//downloads// "" sha256sum .state/instances//downloads// ``` Match the checksum against GitHub's `digest` when available. Inspect zip contents: ```bash unzip -l .state/instances//downloads// ``` Use the install strategy guide in the artifact policy. 6. Update the registry and lockfile. Add or update exactly one `[[plugins]]` entry in `registry/plugins.toml` with: ```toml [[plugins]] id = "" name = "" repo = "/" asset_patterns = [""] install_strategy = "" category = "" ``` Add or update the matching `[[plugins]]` entry in `locks/.lock.toml` with: ```toml [[plugins]] id = "" repo = "/" tag = "" asset = "" sha256 = "" ``` Preserve unrelated registry and lockfile content. Do not invent dependency versions unless they are explicitly stated by the provided release notes or existing local metadata. 7. Use the helper to validate, plan, and apply. Always pass `--state-dir .state` so the helper uses the repo-local downloaded asset: ```bash PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state check --instance PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state plan --instance --plugin PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state apply ``` Before applying, read or summarize the generated plan enough to confirm it changes only the intended plugin files. 8. Verify the result. Confirm the installed file hashes match the plan or archive members: ```bash PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state state --instance PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state check --instance PYTHONPATH=src .venv/bin/python -m compileall -q src tests PYTHONPATH=src .venv/bin/python -m unittest discover -s tests ``` For live Beat Saber validation, follow the live-validation reference. Also record when a BeatMods CDN artifact was used so it can be migrated to upstream GitHub later if possible. 9. Final response. Include: - release URL/tag/asset used - files changed in the repo and helper state - live instance files changed - backup path created by the helper - validation commands and results ## Mistake Recovery If you installed from the wrong release or repo during the current task: 1. Restore affected live files from the helper backup created by that mistaken apply. 2. Remove mistaken downloaded assets and mistaken plan files from `.state`. 3. Correct the registry and lockfile to the user-provided release URL. 4. Rerun `check`, `plan`, and `apply` with `--state-dir .state`. 5. Keep or report only the backup relevant to the final correct apply unless the user asks for full audit history.