Files
plugin-helper/.agents/skills/beatsaber-plugin-manager/SKILL.md
T
2026-07-10 08:42:55 -07:00

7.4 KiB

name, description
name description
beatsaber-plugin-manager 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:

Workflow

  1. Confirm the workspace is the plugin-helper repo.

    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:

    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/<instance>.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:

    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:

    PYTHONPATH=src .venv/bin/python - <<'PY'
    import json, urllib.request
    from plugin_helper.beatmods import by_version_id, normalize_mods
    
    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 = 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:

    https://beatmods.com/cdn/mod/<zipHash>.zip
    

For GitHub URLs, resolve the release from the user-provided repository or release URL only.

Derive <owner>/<repo> and optional <tag> from the URL. Query the GitHub API directly for metadata:

curl -sS https://api.github.com/repos/<owner>/<repo>/releases
curl -sS https://api.github.com/repos/<owner>/<repo>/releases/tags/<tag>

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.

  1. Inspect the asset before selecting an install strategy.

    Download to the helper state directory:

    mkdir -p .state/instances/<instance>/downloads/<plugin-id>
    curl -L --fail -o .state/instances/<instance>/downloads/<plugin-id>/<asset-name> "<browser_download_url>"
    sha256sum .state/instances/<instance>/downloads/<plugin-id>/<asset-name>
    

    Match the checksum against GitHub's digest when available. Inspect zip contents:

    unzip -l .state/instances/<instance>/downloads/<plugin-id>/<asset-name>
    

    Use the install strategy guide in the artifact policy.

  2. Update the registry and lockfile.

    Add or update exactly one [[plugins]] entry in registry/plugins.toml with:

    [[plugins]]
    id = "<stable-plugin-id>"
    name = "<human name>"
    repo = "<owner>/<repo>"
    asset_patterns = ["<asset-name-or-pattern>"]
    install_strategy = "<strategy>"
    category = "<category-if-obvious>"
    

    Add or update the matching [[plugins]] entry in locks/<instance>.lock.toml with:

    [[plugins]]
    id = "<stable-plugin-id>"
    repo = "<owner>/<repo>"
    tag = "<tag>"
    asset = "<asset-name>"
    sha256 = "<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.

  3. Use the helper to validate, plan, and apply.

    Always pass --state-dir .state so the helper uses the repo-local downloaded asset:

    PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state check --instance <instance>
    PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state plan --instance <instance> --plugin <plugin-id>
    PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state apply <generated-plan-path>
    

    Before applying, read or summarize the generated plan enough to confirm it changes only the intended plugin files.

  4. Verify the result.

    Confirm the installed file hashes match the plan or archive members:

    PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state state --instance <instance>
    PYTHONPATH=src .venv/bin/python -m plugin_helper --state-dir .state check --instance <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.

  5. 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.