ek-ui 0.9.37

ek 生态常驻主界面(egui/eframe):插件即界面——观测页 + 日志页,车头与 UI 同插件
# Gate G2: every plugin that ships a UI face must be mounted by ek-ui.
#
# The 2026-10-29 regression this gate exists for: ek-dm / ek-oms / ek-tq each
# still carried `src/ui_face.rs` (a full plugin window), but ek-ui had deleted the
# mount layer. Nothing failed: the code compiled, tests were green, and the
# plugin UIs were simply unreachable from the menu.
#
# Rule: `ek-<mod>/src/ui_face.rs` with `pub fn render` <=> `src/mount.rs` has a
# `Some(Body::<Variant>(` arm for that module. Missing either side = FAIL.
#
# ASCII-only on purpose (Windows PowerShell 5.1 decodes BOM-less .ps1 as ANSI).
[CmdletBinding()]
param(
    [string]$Root = ''
)

$ErrorActionPreference = 'Stop'
# $PSScriptRoot is not populated yet while param defaults are evaluated under
# `powershell -File`, so resolve the crate root here instead.
if (-not $Root) {
    $here = $PSScriptRoot
    if (-not $here) { $here = Split-Path -Parent $MyInvocation.MyCommand.Path }
    $Root = Split-Path -Parent $here
}

$pairs = @(
    @{ Plugin = 'ek-dm'; Variant = 'Dm' },
    @{ Plugin = 'ek-oms'; Variant = 'Oms' },
    @{ Plugin = 'ek-tq'; Variant = 'Tq' }
)

$mountPath = Join-Path $Root 'src\mount.rs'
if (-not (Test-Path $mountPath)) {
    Write-Host "[G2] FAIL: src/mount.rs missing (module mount table is the only window path)" -ForegroundColor Red
    exit 1
}
$mount = Get-Content -Raw -Path $mountPath
$failed = 0

foreach ($p in $pairs) {
    $face = Join-Path (Split-Path -Parent $Root) ($p.Plugin + '\src\ui_face.rs')
    $hasFace = $false
    if (Test-Path $face) {
        $faceText = Get-Content -Raw -Path $face
        $hasFace = $faceText -match 'pub\s+fn\s+render'
    }
    $mounted = $mount -match ('Some\(Body::' + $p.Variant + '\(')

    if ($hasFace -and -not $mounted) {
        Write-Host ("[G2] FAIL: " + $p.Plugin + " ships ui_face.rs but mount.rs has no Body::" + $p.Variant + " arm (orphan face)") -ForegroundColor Red
        $failed++
    }
    elseif ($mounted -and -not $hasFace) {
        Write-Host ("[G2] FAIL: mount.rs mounts Body::" + $p.Variant + " but " + $p.Plugin + "/src/ui_face.rs has no pub fn render") -ForegroundColor Red
        $failed++
    }
    else {
        Write-Host ("[G2] OK  " + $p.Plugin + " <-> Body::" + $p.Variant) -ForegroundColor Green
    }
}

if ($failed -gt 0) {
    Write-Host ("[G2] orphan plugin faces: " + $failed) -ForegroundColor Red
    exit 1
}
Write-Host "[G2] no orphan plugin faces" -ForegroundColor Green
exit 0