Add plugin helper with agent skill for updating plugins

This commit is contained in:
pleb
2026-06-14 10:26:22 -07:00
parent a9881ebec4
commit caaa4a6558
23 changed files with 1604 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
from __future__ import annotations
import tomllib
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
VALID_STRATEGIES = {"dll-to-plugins", "zip-to-pending", "bsipa-zip", "root-zip", "manual"}
@dataclass(frozen=True)
class Dependency:
id: str
constraint: str | None = None
required: bool = True
@dataclass(frozen=True)
class RegistryPlugin:
id: str
name: str
repo: str | None
asset_patterns: tuple[str, ...] = ()
install_strategy: str = "manual"
category: str | None = None
dependencies: tuple[Dependency, ...] = ()
@dataclass(frozen=True)
class Registry:
plugins: dict[str, RegistryPlugin] = field(default_factory=dict)
def get(self, plugin_id: str) -> RegistryPlugin | None:
return self.plugins.get(plugin_id)
@dataclass(frozen=True)
class LockedPlugin:
id: str
repo: str | None
tag: str | None
asset: str | None
sha256: str | None
install_strategy: str | None = None
reason: str | None = None
@dataclass(frozen=True)
class Lockfile:
beat_saber_version: str
instance: str
plugins: tuple[LockedPlugin, ...]
def _load_toml(path: Path) -> dict[str, Any]:
with path.open("rb") as handle:
return tomllib.load(handle)
def load_registry(path: Path) -> Registry:
if not path.exists():
return Registry()
data = _load_toml(path)
plugins: dict[str, RegistryPlugin] = {}
for item in data.get("plugins", []):
dependencies = tuple(
Dependency(
id=dep["id"],
constraint=dep.get("constraint"),
required=dep.get("required", True),
)
for dep in item.get("dependencies", [])
)
strategy = item.get("install_strategy", "manual")
if strategy not in VALID_STRATEGIES:
raise ValueError(f"{path}: invalid install_strategy for {item['id']}: {strategy}")
plugin = RegistryPlugin(
id=item["id"],
name=item.get("name", item["id"]),
repo=item.get("repo"),
asset_patterns=tuple(item.get("asset_patterns", [])),
install_strategy=strategy,
category=item.get("category"),
dependencies=dependencies,
)
plugins[plugin.id] = plugin
return Registry(plugins)
def load_lockfile(path: Path) -> Lockfile:
data = _load_toml(path)
plugins = tuple(
LockedPlugin(
id=item["id"],
repo=item.get("repo"),
tag=item.get("tag"),
asset=item.get("asset"),
sha256=item.get("sha256"),
install_strategy=item.get("install_strategy"),
reason=item.get("reason"),
)
for item in data.get("plugins", [])
)
return Lockfile(
beat_saber_version=data["beat_saber_version"],
instance=data.get("instance", data["beat_saber_version"]),
plugins=plugins,
)