Document plugin helper agent workflow

This commit is contained in:
pleb
2026-06-28 14:35:21 -07:00
parent f085bbb802
commit 17bd736e59
3 changed files with 270 additions and 6 deletions
@@ -1,15 +1,19 @@
---
name: install-beatsaber-plugin
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, or manage a Beat Saber plugin release for a BSManager instance. The user must provide an explicit GitHub release URL in the prompt; if no release URL is present, ask for one and do not infer, search for, or substitute a different repository.
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.
---
# Install Beat Saber Plugin
Use the repository's own `plugin-helper` commands to manage plugins for BSManager instances. Do not manually copy release files into the game instance except to undo your own mistaken install before rerunning the helper.
Use the repository's own `plugin-helper` commands to manage plugins for BSManager instances whenever the helper supports the operation. Do not manually copy release files into the game instance except:
- to bootstrap BSIPA/core packages before the helper has a first-class bootstrap command
- to undo your own mistaken install before rerunning the helper
## Hard Guardrail
Require an explicit GitHub release URL from the user's prompt before selecting any release or repository.
For ordinary GitHub-hosted plugins, require an explicit GitHub release URL from
the user's prompt before selecting any release or repository.
- If the prompt does not contain a GitHub release URL, stop and ask the user for it.
- Do not search the web to discover a repository or "correct" release URL.
@@ -17,6 +21,17 @@ Require an explicit GitHub release URL from the user's prompt before selecting a
- If the provided URL is a general releases page, use that repo's release API and choose the latest non-draft, non-prerelease release unless the user asks for a specific tag/version.
- If the provided URL is a tag URL, use that exact tag.
Exception: if the user explicitly asks to bootstrap a Beat Saber version or
install verified mods without providing GitHub URLs, use BeatMods metadata to
identify compatible versions and dependency closure. Still prefer upstream
GitHub release artifacts when BeatMods exposes a `gitUrl` and a matching
release/asset can be found. Use BeatMods CDN artifacts only when the upstream
artifact is inaccessible, no matching upstream release asset exists, the package
is effectively BeatMods-only, or the package is a framework/library dependency
such as .NET assemblies. Record the artifact source plus BeatMods `modVersion`,
version id, `zipHash`, dependencies, and supported game version in the repo
notes/lock data.
Accepted URL shapes include:
```text
@@ -44,6 +59,7 @@ https://github.com/<owner>/<repo>/releases/download/<tag>/<asset>
sed -n '1,220p' src/plugin_helper/models.py
sed -n '1,220p' registry/plugins.toml
sed -n '1,220p' locks/<instance>.lock.toml
sed -n '1,220p' docs/SMOKETEST.md
```
3. Determine the instance.
@@ -54,9 +70,42 @@ https://github.com/<owner>/<repo>/releases/download/<tag>/<asset>
PYTHONPATH=src python -m plugin_helper instances
```
4. Resolve the release from the user-provided URL only.
4. Resolve the release source.
For GitHub URLs, derive `<owner>/<repo>` and optional `<tag>` from the URL. Query the GitHub API directly for metadata:
For BeatMods bootstrap or verified packages, query BeatMods with a browser-like user agent:
```bash
python - <<'PY'
import json, urllib.request
game_version = "<instance>"
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 = data["mods"] if isinstance(data, dict) and "mods" in data else data
print(json.dumps(mods, indent=2)[:20000])
PY
```
BeatMods dependency entries are mod-version ids. Resolve the selected mod's
dependency closure before downloading. For each resolved package, prefer its
upstream `gitUrl` release artifacts when a matching release asset exists.
Fall back to BeatMods CDN only for inaccessible/missing upstream assets,
BeatMods-only packages, or framework/library dependencies. CDN URLs are:
```text
https://beatmods.com/cdn/mod/<zipHash>.zip
```
For BSIPA bootstrap, expect the archive to contain root-relative `IPA/` and
`IPA.exe` files whether sourced from GitHub or BeatMods. Extract it into the
instance root and run `IPA.exe -n` under the same Proton environment used by
the smoketest. This creates/copies the root `winhttp.dll` and root `Libs/`
substrate that IPA needs.
For GitHub URLs, resolve the release from the user-provided URL only.
Derive `<owner>/<repo>` and optional `<tag>` from the URL. Query the GitHub API directly for metadata:
```bash
curl -sS https://api.github.com/repos/<owner>/<repo>/releases
@@ -85,7 +134,7 @@ https://github.com/<owner>/<repo>/releases/download/<tag>/<asset>
- `dll-to-plugins`: asset is a single `.dll` that belongs in `Plugins/`.
- `bsipa-zip`: zip top-level paths are only `IPA/`, `Libs/`, or `Plugins/`.
- `root-zip`: zip contains valid game-root paths outside the BSIPA top-level set.
- `root-zip`: zip contains valid game-root paths outside the BSIPA top-level set. Use this for BSIPA/bootstrap archives because `IPA.exe`, `IPA.runtimeconfig*.json`, and root `winhttp.dll` are game-root files.
- `zip-to-pending`: only when the release is intended for `IPA/Pending/`.
- `manual`: do not use for installable releases.
@@ -140,6 +189,28 @@ https://github.com/<owner>/<repo>/releases/download/<tag>/<asset>
Use `PYTHONPATH=src`; plain `python -m unittest` may fail in this source-layout repo.
For live Beat Saber validation, follow `docs/SMOKETEST.md`. Do not rely on
`timeout` to kill the full game process tree. Prefer the documented
foreground Proton launch with a background watchdog that sleeps for the smoke
window, then terminates Beat Saber by process name. Confirm `Logs/_latest.log`
has the expected IPA/plugin lines. If the game remains open after the
watchdog cleanup, say so and ask the user to close it manually rather than
leaving the turn with Beat Saber running.
For BSIPA/SongCore bootstrap, expected successful log lines include:
```text
Game version <version>
Loading plugins from Plugins and found <n>
Beat Saber IPA (BSIPA): <version>
SongCore (SongCore): <version>
```
Warnings about older mod target game-version metadata can be acceptable when
BeatMods verified that exact package for the target Beat Saber version, but
record them in the tracker or roadmap. Also record when a BeatMods CDN
artifact was used so it can be migrated to upstream GitHub later if possible.
9. Final response.
Include: