Files
pebrel/mobile/tools/package_windows_preview.py
Kuddev bf2ed9af9b feat(mobile): integrate remote terminal, SSH and reader workflows (#343)
Integrate the Android client with native desktop pairing, remote terminal and SSH/SFTP sessions, keyboard controls, file reading and Agent conversations. Preserve authenticated connection ownership and per-device input permissions.

Validation: all ten required GitHub checks passed, including five native test platforms and both macOS release workspace checks.
2026-09-29 20:09:00 +08:00

76 lines
3.5 KiB
Python

"""Bundle a freshly built GPUI desktop with native mobile pairing instructions."""
import argparse
import hashlib
import json
from pathlib import Path, PurePosixPath
import re
import subprocess
import zipfile
def safe_name(name: str) -> str:
name = name.replace("\\", "/")
path = PurePosixPath(name)
if path.is_absolute() or ".." in path.parts or ":" in name:
raise ValueError(f"Unsafe package path: {name}")
return name
def package(desktop: Path, output: Path, commit: str) -> Path:
root = Path(__file__).resolve().parents[2]
if not re.fullmatch(r"[a-f0-9]{40}", commit):
raise ValueError("An exact source commit is required")
actual = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=root, text=True).strip()
if actual != commit:
raise ValueError("Requested commit differs from the checked-out source")
output.mkdir(parents=True, exist_ok=True)
destination = output / f"Pebrel-Windows-x64-mobile-preview-{commit[:7]}.zip"
with desktop.open("rb") as source_file:
desktop_digest = hashlib.file_digest(source_file, "sha256").hexdigest()
record = {
"source_commit": commit,
"desktop_package_sha256": desktop_digest,
"mode": "package_only",
"tests": "See the matching CI run for targeted check results; real-device and visual acceptance remain manual",
"files": {},
}
with zipfile.ZipFile(destination, "x", compression=zipfile.ZIP_DEFLATED) as target:
def add(name: str, data: bytes) -> None:
name = safe_name(name)
if name in record["files"]:
raise ValueError(f"Duplicate package entry: {name}")
target.writestr(name, data)
record["files"][name] = hashlib.sha256(data).hexdigest()
with zipfile.ZipFile(desktop) as source:
for entry in source.infolist():
if not entry.is_dir():
add(entry.filename, source.read(entry))
for required in ("pebrel.exe", "runtime/pebrel-hook.exe", "runtime/conpty.dll", "runtime/OpenConsole.exe"):
if required not in record["files"]:
raise ValueError(f"Missing desktop runtime: {required}")
# Native Settings replaces the external Node/browser pairing launcher.
for name in ("Start-Pebrel-Preview.cmd", "START-NATIVE-LAN.md", "SETTINGS-PREVIEW-0.4.9.md", "RELAY-PREVIEW-0.4.10.md"):
data = (root / "mobile/desktop" / name).read_bytes()
if name.endswith(".cmd"):
data = data.replace(b"\r\n", b"\n").replace(b"\n", b"\r\n")
add(name, data)
add("SOURCE_COMMIT", (commit + "\n").encode())
metadata = json.dumps(record, ensure_ascii=False, indent=2) + "\n"
target.writestr("BUILD.json", metadata)
digest = hashlib.sha256(destination.read_bytes()).hexdigest()
(output / "SHA256SUMS").write_text(f"{digest} {destination.name}\n", encoding="utf-8")
(output / "SOURCE_COMMIT").write_text(commit + "\n", encoding="utf-8")
(output / "BUILD.json").write_text(metadata, encoding="utf-8")
print(json.dumps({"package": str(destination), "sha256": digest, "source_commit": commit}))
return destination
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--desktop", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--commit", required=True)
arguments = parser.parse_args()
package(arguments.desktop, arguments.output, arguments.commit)