2026-07-13 16:34:09 +08:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
2026-08-11 20:09:33 +08:00
|
|
|
import json
|
2026-07-13 16:34:09 +08:00
|
|
|
import os
|
|
|
|
|
import platform
|
|
|
|
|
import stat
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
|
|
|
|
|
|
|
|
|
2026-08-11 20:09:33 +08:00
|
|
|
def _load_platforms() -> dict[str, tuple[str, str]]:
|
|
|
|
|
"""Load and validate the platform manifest inside an isolated wheel build."""
|
|
|
|
|
path = Path(__file__).with_name("platforms.json")
|
|
|
|
|
try:
|
|
|
|
|
payload = json.loads(path.read_text())
|
|
|
|
|
except (OSError, json.JSONDecodeError) as error:
|
|
|
|
|
raise RuntimeError(f"could not read runtime platform manifest from {path}") from error
|
|
|
|
|
if not isinstance(payload, dict) or not payload:
|
|
|
|
|
raise RuntimeError(f"{path} must contain a non-empty platform object")
|
|
|
|
|
platforms: dict[str, tuple[str, str]] = {}
|
|
|
|
|
for name, raw in payload.items():
|
|
|
|
|
if (
|
|
|
|
|
not isinstance(name, str)
|
|
|
|
|
or not isinstance(raw, dict)
|
|
|
|
|
or set(raw) != {"tag", "executable"}
|
|
|
|
|
or not isinstance(raw["tag"], str)
|
|
|
|
|
or not isinstance(raw["executable"], str)
|
|
|
|
|
):
|
|
|
|
|
raise RuntimeError(f"{path} platform entries must contain string tag and executable fields")
|
|
|
|
|
platforms[name] = (raw["tag"], raw["executable"])
|
|
|
|
|
return platforms
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_PLATFORMS = _load_platforms()
|
2026-07-13 16:34:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def _host_platform_tag() -> str:
|
|
|
|
|
machine = platform.machine().lower()
|
|
|
|
|
arch = "arm64" if machine in {"arm64", "aarch64"} else "x64" if machine in {"x86_64", "amd64"} else machine
|
|
|
|
|
system = platform.system().lower()
|
feat(python-runtime): package the Windows x64 dsh executable
Add node24-win-x64 as the only supported Windows runtime target and publish it as a py3-none-win_amd64 wheel containing the conventional dsh and ripgrep .exe payload names. Keep Windows ARM64 rejected explicitly so Python cannot claim a carrier that CI and release automation do not build.
Teach the pkg builder to require a native x64 Windows host, validate both node-pty ConPTY addons, copy @vscode's win32 ripgrep executable, and recognize pkg's .exe output. Extend runtime resolution, wheel staging, payload validation, and the preset closure check so the Windows-specific PowerShell plugins and sidecars fail loud when omitted.
The sidecar resolver now maps a packaged main.exe to main-rg.exe; focused TypeScript and Python tests cover that name, the win_amd64 manifest, x64-only host selection, complete wheel payload, ConPTY inventory, and platform-conditioned plugin closure.
2026-08-23 15:39:18 +08:00
|
|
|
key = (
|
|
|
|
|
f"macos-{arch}"
|
|
|
|
|
if system == "darwin"
|
|
|
|
|
else f"linux-{arch}"
|
|
|
|
|
if system == "linux"
|
|
|
|
|
else f"win-{arch}"
|
|
|
|
|
if system == "windows"
|
|
|
|
|
else system
|
|
|
|
|
)
|
2026-07-13 16:34:09 +08:00
|
|
|
try:
|
|
|
|
|
return _PLATFORMS[key][0]
|
|
|
|
|
except KeyError as exc:
|
|
|
|
|
raise RuntimeError(f"unsupported deepseek-harness-runtime-bin build platform: {key}") from exc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RuntimeBuildHook(BuildHookInterface):
|
|
|
|
|
"""Assign the native wheel tag and reject incomplete or mixed-platform payloads."""
|
|
|
|
|
|
|
|
|
|
def initialize(self, version: str, build_data: dict[str, object]) -> None:
|
|
|
|
|
if version == "editable":
|
|
|
|
|
return
|
|
|
|
|
if self.target_name == "sdist":
|
|
|
|
|
raise RuntimeError(
|
|
|
|
|
"deepseek-harness-runtime-bin is wheel-only; build and publish platform wheels only."
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
platform_tag = os.environ.get("DSH_RUNTIME_PLATFORM_TAG") or _host_platform_tag()
|
2026-07-30 01:09:54 +08:00
|
|
|
matches = [value for value in _PLATFORMS.values() if value[0] == platform_tag]
|
2026-07-13 16:34:09 +08:00
|
|
|
if len(matches) != 1:
|
|
|
|
|
supported = ", ".join(value[0] for value in _PLATFORMS.values())
|
|
|
|
|
raise RuntimeError(
|
|
|
|
|
f"unsupported DSH_RUNTIME_PLATFORM_TAG {platform_tag!r}; expected one of {supported}"
|
|
|
|
|
)
|
2026-07-30 01:09:54 +08:00
|
|
|
expected_executable = matches[0][1]
|
2026-07-13 16:34:09 +08:00
|
|
|
runtime_dir = Path(self.root) / "src" / "deepseek_harness_runtime" / "runtime"
|
feat(python-runtime): package the dsh CLI and profile assets
Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
2026-08-23 14:56:02 +08:00
|
|
|
runtime_files = sorted(
|
|
|
|
|
runtime_dir.glob("deepseek-harness-sdk-runtime-*") if runtime_dir.is_dir() else []
|
|
|
|
|
)
|
feat(python-runtime): package the Windows x64 dsh executable
Add node24-win-x64 as the only supported Windows runtime target and publish it as a py3-none-win_amd64 wheel containing the conventional dsh and ripgrep .exe payload names. Keep Windows ARM64 rejected explicitly so Python cannot claim a carrier that CI and release automation do not build.
Teach the pkg builder to require a native x64 Windows host, validate both node-pty ConPTY addons, copy @vscode's win32 ripgrep executable, and recognize pkg's .exe output. Extend runtime resolution, wheel staging, payload validation, and the preset closure check so the Windows-specific PowerShell plugins and sidecars fail loud when omitted.
The sidecar resolver now maps a packaged main.exe to main-rg.exe; focused TypeScript and Python tests cover that name, the win_amd64 manifest, x64-only host selection, complete wheel payload, ConPTY inventory, and platform-conditioned plugin closure.
2026-08-23 15:39:18 +08:00
|
|
|
expected_files = (
|
|
|
|
|
[expected_executable, f"{expected_executable.removesuffix('.exe')}-rg.exe"]
|
|
|
|
|
if expected_executable.endswith(".exe")
|
|
|
|
|
else [expected_executable, f"{expected_executable}-rg"]
|
|
|
|
|
)
|
2026-07-30 01:09:54 +08:00
|
|
|
if "-macos-" in expected_executable:
|
2026-07-30 01:29:18 +08:00
|
|
|
expected_files.append(f"{expected_executable}-spawn-helper")
|
feat(python-runtime): package the Windows x64 dsh executable
Add node24-win-x64 as the only supported Windows runtime target and publish it as a py3-none-win_amd64 wheel containing the conventional dsh and ripgrep .exe payload names. Keep Windows ARM64 rejected explicitly so Python cannot claim a carrier that CI and release automation do not build.
Teach the pkg builder to require a native x64 Windows host, validate both node-pty ConPTY addons, copy @vscode's win32 ripgrep executable, and recognize pkg's .exe output. Extend runtime resolution, wheel staging, payload validation, and the preset closure check so the Windows-specific PowerShell plugins and sidecars fail loud when omitted.
The sidecar resolver now maps a packaged main.exe to main-rg.exe; focused TypeScript and Python tests cover that name, the win_amd64 manifest, x64-only host selection, complete wheel payload, ConPTY inventory, and platform-conditioned plugin closure.
2026-08-23 15:39:18 +08:00
|
|
|
expected_files.sort()
|
2026-07-30 01:09:54 +08:00
|
|
|
found_files = [path.name for path in runtime_files]
|
|
|
|
|
if found_files != expected_files:
|
2026-07-13 16:34:09 +08:00
|
|
|
raise RuntimeError(
|
2026-07-30 01:09:54 +08:00
|
|
|
f"runtime wheel {platform_tag} payload must be {expected_files}; found {found_files}"
|
2026-07-13 16:34:09 +08:00
|
|
|
)
|
2026-07-30 01:09:54 +08:00
|
|
|
for executable in runtime_files:
|
feat(python-runtime): package the Windows x64 dsh executable
Add node24-win-x64 as the only supported Windows runtime target and publish it as a py3-none-win_amd64 wheel containing the conventional dsh and ripgrep .exe payload names. Keep Windows ARM64 rejected explicitly so Python cannot claim a carrier that CI and release automation do not build.
Teach the pkg builder to require a native x64 Windows host, validate both node-pty ConPTY addons, copy @vscode's win32 ripgrep executable, and recognize pkg's .exe output. Extend runtime resolution, wheel staging, payload validation, and the preset closure check so the Windows-specific PowerShell plugins and sidecars fail loud when omitted.
The sidecar resolver now maps a packaged main.exe to main-rg.exe; focused TypeScript and Python tests cover that name, the win_amd64 manifest, x64-only host selection, complete wheel payload, ConPTY inventory, and platform-conditioned plugin closure.
2026-08-23 15:39:18 +08:00
|
|
|
if platform_tag != "win_amd64" and executable.stat().st_mode & stat.S_IXUSR == 0:
|
2026-07-29 14:12:27 +08:00
|
|
|
raise RuntimeError(f"runtime executable is not executable: {executable}")
|
2026-07-13 16:34:09 +08:00
|
|
|
build_data["pure_python"] = False
|
|
|
|
|
build_data["infer_tag"] = False
|
|
|
|
|
build_data["tag"] = f"py3-none-{platform_tag}"
|