"""Assemble immutable Rust 3 plugin candidates from reviewed local inputs. Only the small, dependency-free Go adapter is rebuilt. This script never runs Cargo, npm, a Cua session, a device tool, an installer, or a network download. """ import argparse import hashlib import io import json import os import platform import re import stat import struct import subprocess import sys import zipfile from pathlib import Path, PurePosixPath from urllib.parse import quote ROOT = Path(__file__).resolve().parents[1] CUA = ROOT / "plugins/cua-driver" REVIEW = ROOT / "plugins/task-review" DEVICE_TEST = ROOT / "plugins/artemis-device-test" BASE_VERSION = "0.38.0+artemis.1" CUA_VERSION = "0.38.0+artemis.2" REVIEW_VERSION = "1.1.1" DEVICE_TEST_VERSION = "0.5.0+artemis.7" DEFAULT_RELEASE_TAG = "rust3-plugin-preview-20261101" HOST_RANGE = ">=3.0.0,<4.0.0" BASE_SHA256 = "c007da16d58c4165a1a344113e650e68bd92a69ad3ce4ca8285818c5426dc0f4" RELEASES = "https://git.playones.com/chenmingxuan/Artemis-Plugins/releases/download" BASE_URL = ( f"{RELEASES}/cua-driver-v{BASE_VERSION}/cua-driver-{BASE_VERSION}-windows-amd64.zip" ) RUNTIME = ( "cua-driver.exe", "cua-driver-uia.exe", "cua_driver_sdk.dll", "cua-cursor-theme.exe", ) ZIP_DATE = (2026, 11, 1, 0, 0, 0) def sha256(data): return hashlib.sha256(data).hexdigest() def encoded(value): return (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode("utf-8") def read_json(path): return json.loads(path.read_text(encoding="utf-8-sig")) def require(condition, message): if not condition: raise ValueError(message) def file_bytes(path): require( path.is_file() and not path.is_symlink(), f"Missing or linked input: {path.name}", ) return path.read_bytes() def x64(data, name): require(len(data) >= 64 and data[:2] == b"MZ", f"Not a PE binary: {name}") offset = struct.unpack_from("