"""Build a self-contained Windows plugin from a hash-pinned Cua release.""" import argparse import hashlib import json import os import re import subprocess import urllib.request import zipfile from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SOURCE = ROOT / "plugins/cua-driver" UPSTREAM_VERSION = "0.36.0" COMMIT = "6d6c734c127025fb39ad5d585a10382808b39dc1" DIGEST = "f8c47024b626f4e0e70f8428d2998df39e4879110c5722a29d5fd03e367353ad" URL = "https://github.com/trycua/cua/releases/download/cua-driver-rs-v0.36.0/cua-driver-rs-0.36.0-windows-x86_64-binary.zip" def main(): parser = argparse.ArgumentParser(__doc__) parser.add_argument("upstream_zip", type=Path) parser.add_argument("--go", default="go") parser.add_argument("--output", type=Path, default=ROOT / "artifacts") args = parser.parse_args() version = json.loads((SOURCE / "plugin.json").read_text("utf-8"))["version"] if version.split("+", 1)[0] != UPSTREAM_VERSION: raise ValueError("Plugin version must match the pinned Cua Driver version") match = re.search( r'const adapterVersion = "([^"]+)"', (SOURCE / "main.go").read_text("utf-8") ) if not match or match[1] != version: raise ValueError("Adapter MCP version must match plugin.json") if hashlib.sha256(args.upstream_zip.read_bytes()).hexdigest() != DIGEST: raise ValueError("Cua release archive hash mismatch") output = args.output.resolve() output.mkdir(parents=True, exist_ok=True) adapter = output / "artemis-cua-adapter.exe" env = { **os.environ, "CGO_ENABLED": "0", "GOOS": "windows", "GOARCH": "amd64", "GOTOOLCHAIN": "local", } for command in ( [args.go, "test", "./..."], [ args.go, "build", "-trimpath", "-buildvcs=false", "-ldflags=-s -w", "-o", str(adapter), ".", ], ): subprocess.run(command, cwd=SOURCE, env=env, check=True, timeout=180) license_file = SOURCE / "LICENSE.upstream" if not license_file.exists(): with urllib.request.urlopen( f"https://raw.githubusercontent.com/trycua/cua/{COMMIT}/LICENSE.md", timeout=30, ) as response: license_file.write_bytes(response.read()) target = output / f"cua-driver-{version}-windows-amd64.zip" with ( zipfile.ZipFile(target, "w", zipfile.ZIP_DEFLATED) as dest, zipfile.ZipFile(args.upstream_zip) as upstream, ): for name in ( "plugin.json", "SKILL.md", "LICENSE.upstream", "RELEASE.md", "VERIFICATION.md", ): dest.write(SOURCE / name, name) for source in sorted(SOURCE.glob("*.go")): dest.write(source, f"source/{source.name}") for name in ("go.mod", "tools.json"): dest.write(SOURCE / name, f"source/{name}") dest.write(adapter, "bin/artemis-cua-adapter.exe") for name in upstream.namelist(): # Only the release's executable runtime; no global installer/hooks. if Path(name).name in { "cua-driver.exe", "cua-driver-uia.exe", "cua-cursor-theme.exe", "cua_driver_sdk.dll", }: dest.writestr(f"bin/{Path(name).name}", upstream.read(name)) dest.writestr( "provenance.json", json.dumps( { "source_commit": COMMIT, "upstream_version": UPSTREAM_VERSION, "plugin_version": version, "adapter_revision": 2, "prerelease": True, "url": URL, "sha256": DIGEST, }, indent=2, ), ) print( json.dumps( { "archive": str(target), "sha256": hashlib.sha256(target.read_bytes()).hexdigest(), } ) ) if __name__ == "__main__": main()