# Contributing to XUI

## Requirements

Native builds require Windows 10 version 1703 or later, CMake 3.24 or later, and Visual Studio 2022 or 2026 (including Preview/Insiders).
Install the C++ desktop workload and a Windows SDK.
For ARM64 builds, include the ARM64 C++ tools.
The Windows backend requires a 64-bit build.

C# samples require the .NET 10 SDK. Rust samples require the Rust MSVC toolchain.
The VS Code syntax package requires Node.js and npm.
Binding generation uses Python.

Run the commands from the repository root in Visual Studio Developer PowerShell.
The commands use a separate build directory, so they do not replace another build's executables.

## Build the native code

```powershell
$arch = if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq "Arm64") { "ARM64" } else { "x64" }
$rid = if ($arch -eq "ARM64") { "win-arm64" } else { "win-x64" }
$build = "build\$arch"
. .\scripts\Release.Common.ps1
$cmake = Get-XuiCMake
& $cmake -S . -B $build -G (Get-XuiGenerator) -A $arch -DBUILD_TESTING=ON
& $cmake --build $build --config Release --parallel 4
```

The architecture selection avoids x64 emulation on ARM64 Windows.
Use the same architecture for `xui.dll` and each application that loads it.
Close executables from this build directory before relinking them.
Native builds enable syntax highlighting from the checked-in `dep` package by default.
See [repository-local packages](#repository-local-packages) for package updates and [LSH configuration](#lsh-highlighting-in-xui-applications) for the opt-out.

The helpers discover prerelease installations and prefer Visual Studio 2022 when both versions are installed, preserving existing 2022 build directories. Use a fresh build directory when switching generators. To use CMake and CTest from the selected Visual Studio in subsequent commands:

```powershell
. .\scripts\Release.Common.ps1
$tools = Split-Path (Get-XuiCMake)
$env:PATH = "$tools;$env:PATH"
```

Then run the native build commands.
Run `.\tests\build-toolchain.ps1` to check Visual Studio discovery, CMake, and x64/ARM64 compiler environments.

## Native samples

### Application-discovered regressions

With `XUI_DESKTOP_TESTS=ON`, build the artwork, navigation, and inline overlay fixtures:

```powershell
cmake --build $build --config Release --target xui xui_image_tests xui_navigation_view_tests xui_navigation_window_tests xui_inline_overlay_window_tests xui_abi_features_tests
ctest --test-dir $build -C Release -R "^xui_(navigation_view|scrolled_navigation_chevron|item_command_anchor|inline_overlay_window|abi_features)_tests$" --output-on-failure -j 1
& ".\$build\Release\xui_image_tests.exe" --row-sync-only
& ".\$build\Release\xui_image_tests.exe" "$build\row-artwork-fixtures"
dotnet run --project bindings\dotnet\GeneratorTests -c Release
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --item-actions
```

The overlay fixture captures only its own window.
It requires opaque panel pixels above collection rows in both themes.
The navigation fixtures send native pointer messages and reject stale row commands after source replacement.
The artwork fixture checks resident pixels before another decoder completion.
The managed fixture checks inline action delivery and explicit callback errors.

After the native build, run a sample:

```powershell
& ".\$build\Release\xui_demo.exe" "C:\Windows"
& ".\$build\Release\xui_gallery.exe"
& ".\$build\Release\xui_task_manager.exe"
& ".\$build\Release\xui_images.exe" "C:\Pictures"
```

The explorer opens the current directory without a folder argument.
The thumbnail sample shows a folder field without an argument.
The [sample references](../index.md#samples) describe shortcuts, behavior, and limits.

### Gallery

To build only the galleries, use:

```powershell
cmake --build $build --config Release --target xui_gallery xui_winui_gallery
& ".\$build\Release\xui_gallery.exe" --page combo
& ".\$build\Release\xui_gallery.exe" --winui-catalog
& ".\$build\Release\xui_winui_gallery.exe"
```

The last command opens the compact WinUI-style experiment.
Both galleries accept `--light`, `--high-contrast`, and `--system-titlebar`.
The ordinary gallery also accepts `--winui` for the compact experiment.
The complete catalog has a live Classic/WinUI switch.

The gallery separates the live controls from their reference content:

- `demo\gallery.cpp` composes the pages and shares the selected language across their code tabs.
- `demo\gallery_catalog.hpp` supplies navigation metadata and C++ excerpts.
- `demo\gallery_reference.hpp` supplies usage guidance, exercises, limits, documentation paths, and the other language excerpts.
- `demo\gallery_urls.hpp` maps documentation paths to handbook URLs. `gallery_links.hpp` opens links.

Keep the reference entries in catalog order.
Use current public APIs in each excerpt.
For unsupported operations, describe the binding limit instead of inventing a wrapper.
Documentation paths must name existing pages under `docs\specs`.

To check gallery content and the language tabs, run:

```powershell
cmake --build $build --config Release --target xui_gallery xui_gallery_catalog_tests xui_gallery_smoke
ctest --test-dir $build -C Release -R "^xui_gallery_catalog_tests$" --output-on-failure
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --reference-only
```

The last command opens a desktop window.
It checks shared language selection, native code text, copy actions, handbook URLs, and navigation links without opening a browser.

### Floating C# card

After building the native runtime, run the floating card and its interactive-window smoke check:

```powershell
dotnet run --project bindings\dotnet\FloatingCard\FloatingCard.csproj -c Release
dotnet run --project bindings\dotnet\FloatingCard\FloatingCard.csproj -c Release -- --smoke
dotnet run --project bindings\dotnet\FloatingCard\FloatingCard.csproj -c Release -- --acrylic --smoke
dotnet run --project bindings\dotnet\FloatingCard\FloatingCard.csproj -c Release -- --composition --smoke
```

The `--smoke` run paints a visible layered frame, checks transparent hit testing, caption dragging, native text delivery, and closes without user input.
With `--acrylic`, it checks the non-layered Desktop Acrylic card instead of transparent hit testing.
Close earlier card instances first: they are topmost and centered, so they can intercept the smoke check's hit tests.
For native pixel-alpha and resize coverage, enable desktop tests with `cmake -S . -B $build -DXUI_DESKTOP_TESTS=ON`, build `xui_transparent_window_tests`, and run `ctest --test-dir $build -C Release -R "^xui_transparent_window_tests$" --output-on-failure`.
For Mica, acrylic, and in-app acrylic coverage, build `xui_backdrop_window_tests` and run `ctest --test-dir $build -C Release -R "^xui_backdrop_window_tests$" --output-on-failure` on an unlocked Windows 11 desktop.
Pass an output directory to `xui_backdrop_window_tests.exe` to keep its owned-window captures for visual review.
`xui_abi_features_tests.exe --backdrop` checks the C ABI contract without the other ABI suites.
`xui_composition_window_tests` covers the experimental composition presentation on an unlocked desktop.
Pass a section such as `--overlays`, `--device-loss`, `--panels`, or `--runtime-hosts`, and optionally an output directory for captures. Run it from a writable directory: `--runtime-hosts` writes fixture and profile folders there. Configure with WebView2 enabled (see the `XUI_ENABLE_WEBVIEW2` configure command below) to include web content in that section.
To measure composition against classic presentation (and optionally a baseline build of the same probe), build `xui_composition_probe` and run `.\tests\measure-composition.ps1 -Baseline <baseline probe path> -Output build\composition-measurements`.
It opens windows above the desktop, animates a background window, and samples system GPU counters, so leave the desktop unlocked and otherwise idle.
For the C# lifecycle tests, run `dotnet run --project bindings\dotnet\Tests\Tests.csproj -c Release -- --window-native`.

### Swap chain sample

Build and run the DirectComposition sample:

```powershell
cmake --build $build --config Release --target xui_swap_chain_sample
& ".\$build\Release\xui_swap_chain_sample.exe"
```

The sample displays a rainbow triangle that rotates around its Y axis, with perspective, beside ordinary XUI controls.
The Pause button stops rotation. Hidden panels stop frame delivery.
The Show overlay button opens a popup with a native text input above the live triangle.
The triangle keeps its proportions after a resize or DPI change.
`--handle` selects the composition-handle path. `--warp` selects software rendering.
`--acrylic` uses the experimental composition presentation and draws the triangle with a transparent background over a desktop acrylic card.
`--smoke` closes the sample after 60 presented frames.
The smoke run opens the overlay at frame 15 and closes it at frame 45 without changing producer geometry.
The [swap chain contract](../contracts/swap-chain-panel.md) describes the renderer boundary and Windows Terminal integration limits.

Build and run the native regression fixture:

```powershell
cmake --build $build --config Release --target xui_swap_chain_panel_tests
ctest --test-dir $build -C Release -R "^xui_swap_chain_panel_tests$" --output-on-failure
```

The fixture requires a Windows desktop with DirectComposition and Windows Graphics Capture.
It inspects real compositor frames, not `WM_PRINT` output.

Build and run the live-overlay acceptance fixture:

```powershell
cmake --build $build --config Release --target xui_swap_chain_overlay_tests
ctest --test-dir $build -C Release -R "^xui_swap_chain_overlay_tests$" --output-on-failure
```

This fixture requires popup pixels above two live producers, without changes to their geometry or visibility.
It captures only its own window and requires the foreground window to stay unchanged.
It has no capture-disabled mode.

### Native foreground acceptance

The menu geometry check does not activate its host or inject keyboard or mouse input:

```powershell
cmake -S . -B $build -DXUI_DESKTOP_TESTS=ON
cmake --build $build --config Release --target xui_menu_tests
ctest --test-dir $build -C Release -R "^xui_menu_geometry_tests$" --output-on-failure
```

This check covers rounded regions, border pixels, high contrast, DPI scaling, resize, repaint, and resource cleanup.
The separate `xui_menu_tests` check requires an uninterrupted foreground window for native keyboard and accessibility behavior.

Run the fixed batch without clicking, typing, or switching desktop windows:

```powershell
cmake --build $build --config Release --target xui_split_animation_tests xui_control_tests xui_style_layouts_tests xui_foundation_tests xui_swap_chain_panel_tests xui_swap_chain_overlay_tests xui_swap_chain_abi_tests xui_swap_chain_input_tests xui_swap_chain_popup_input_tests xui_content_host_window_tests xui_split_axis_window_tests xui_explorer_tests
ctest --test-dir $build -C Release -R "^xui_(split_animation|control|style_layouts|foundation|swap_chain_panel|swap_chain_overlay|swap_chain_abi|swap_chain_input|swap_chain_popup_input|content_host_window|split_axis_window|explorer)_tests$" --output-on-failure
```

Four fixtures use a thread-local CBT observer: swap-chain panels, live overlays, popup input/lifetime, and native ContentHost replacement.
They reject focus or activation requests on the observed UI thread, including transient requests between existing assertions.
They also reject sampled foreground changes and diagnostic buffer overflow.
The observer never blocks an operation or injects input.
Its diagnostics contain operation names, numeric HWNDs, process IDs, and timestamps, not external window titles or content.

If a fixture fails, preserve `Testing\Temporary\LastTest.log` before another CTest run.
Read the operation and HWND records before attributing the failure to XUI or external desktop activity.
An unchanged foreground at a later assertion does not cancel an observed focus request.
A later passing run does not explain an earlier failure.

### Use XUI in a C++ application

Link the executable to `xui_windows`.
Include `demo\xui.rc`, or supply an equivalent common-controls v6 and per-monitor-DPI manifest.
For MSVC builds that use this resource, set `/MANIFEST:NO`.
The following CMake example assumes `xui` is a subdirectory beside your `main.cpp`:

```cmake
cmake_minimum_required(VERSION 3.24)
project(MyApp LANGUAGES C CXX RC)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
add_subdirectory(xui)
add_executable(my_app WIN32 main.cpp xui/demo/xui.rc)
target_link_libraries(my_app PRIVATE xui_windows)
target_compile_options(my_app PRIVATE /utf-8 /EHsc)
target_link_options(my_app PRIVATE /MANIFEST:NO)
```

The [application reference](../contracts/application.md) describes thread ownership, callbacks, layout, and error handling.

### C ABI application setup

The [C guide](../learn/languages/c.md) contains a complete `main.c`.
Link it to the `xui` DLL target, not the C++ `xui_windows` target.
This CMake example assumes the XUI checkout is a subdirectory beside `main.c`:

```cmake
cmake_minimum_required(VERSION 3.24)
project(MyCApp LANGUAGES C CXX RC)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
add_subdirectory(xui)
add_executable(my_c_app main.c xui/demo/xui.rc)
target_link_libraries(my_c_app PRIVATE xui)
target_compile_options(my_c_app PRIVATE /utf-8 /W4)
target_link_options(my_c_app PRIVATE /MANIFEST:NO)
add_custom_command(TARGET my_c_app POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "$<TARGET_FILE:xui>" "$<TARGET_FILE_DIR:my_c_app>"
    VERBATIM)
```

CMake uses the C compiler for `main.c` and the C++ compiler for the native XUI implementation.
The target supplies the include directory and import library.
The resource embeds the common-controls v6 and per-monitor-DPI manifest.
The post-build command places the matching DLL beside the console executable.
For a separately built DLL, supply its `xui.lib`, the `include` directory, and the same manifest instead.
Keep the C executable and native library on the same architecture.

## Reveal animation checks

After the native configuration, run the focused reveal checks:

```powershell
cmake -S . -B $build -DXUI_DESKTOP_TESTS=ON
cmake --build $build --config Release --target xui_reveal_tests xui_reveal_window_tests xui_split_animation_tests xui_tab_animation_tests xui_tab_animation_window_tests xui_expander_animation_tests xui_expander_animation_window_tests xui_progress_animation_tests xui_progress_animation_window_tests xui_document_animation_window_tests --parallel 1
ctest --test-dir $build -C Release -R "^xui_(reveal(_window)?|split_animation|tab_animation(_window)?|expander_animation(_window)?|progress_animation(_window)?|document_animation_window)_tests$" --output-on-failure -j 1
```

The window fixture requires a Windows desktop and owned-window graphics capture.
It reads the system motion preference without changing it.
It covers fixed and expanding layout, all entry edges, native input, nested scroll content, resize, and synthetic DPI messages.
It reports update-and-paint intervals and root-layout counts for a small bounded fixture.
Timing output is diagnostic, not a frame-rate acceptance threshold.
The [test notes](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/testing.md#reveal-animation-checks) describe its coverage and limits.

The collection presentation foundation has separate model and native fixtures:

```powershell
cmake --build $build --config Release --target xui_collection_presentation_tests xui_collection_presentation_window_tests --parallel 1
ctest --test-dir $build -C Release -R "^xui_collection_presentation(_window)?_tests$" --output-on-failure -j 1
```

The native fixture also requires `XUI_DESKTOP_TESTS=ON` and runs serially.
These fixtures exercise internal presentation geometry. They do not enable NavigationView animation.

For the opt-in navigation producer and gallery, run:

```powershell
cmake --build $build --config Release --target xui_navigation_animation_tests xui_navigation_animation_window_tests xui_gallery xui_gallery_smoke --parallel 1
ctest --test-dir $build -C Release -R "^xui_(navigation_animation(_window)?_tests|navigation_motion_gallery_smoke)$" --output-on-failure -j 1
dotnet run --project bindings\dotnet\Tests -- --navigation-animation
cargo test --manifest-path bindings\rust\Cargo.toml -p xui navigation_animation_contract
```

The window and gallery registrations require `XUI_DESKTOP_TESTS=ON`.

For the replayable animation gallery, run:

```powershell
cmake --build $build --config Release --target xui_gallery xui_gallery_smoke --parallel 1
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --animations-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --feedback-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --popup-motion-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --progress-motion-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --content-motion-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --page-motion-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --page-motion-winui
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --tab-motion-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --document-motion-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --document-motion-winui
& ".\$build\Release\xui_gallery.exe" --page animations
```

For bounded concurrent-motion observations, use the native stress fixture:

```powershell
cmake --build $build --config Release --target xui_animation_stress_window_tests --parallel 1
& ".\$build\Release\xui_animation_stress_window_tests.exe"
```

The fixture compares fixed and expanding Reveal with concurrent Progress updates and retained native editors.
Its CPU observations include the test observer and native rendering, not only the animation scheduler.
Run it separately from other desktop tests.

The gallery check covers duration choices, reversal, layout modes, retained native input, panes, and timer shutdown.
The feedback check covers field validation, caret and undo retention, and one live announcement per message state.
The progress check covers immediate logical values, retargeting, mode changes, and idle settlement of determinate transitions.
The foundation check covers the separate indeterminate bar/ring timer and its visibility, lifetime, and reduced-motion policy.
The content-state check covers real native editor movement, focus return, retained undo, a fixed slot, and immediate mode.
The page checks cover directional native movement, immediate input ownership, retained selection and undo, rapid switching, and immediate mode.
The managed runtime fixtures use `--reveal`, `--split-animation`, `--tab-animation`, `--expander-animation`, and `--progress-animation` in the binding test runner.
FileExplorer `--smoke` covers the actual navigation, tab, pane, and Find composition.
FileExplorer `--view-switch-smoke` checks stationary view switches, native ownership, retained selection and scrolling, and the absence of an animation timer.
The earlier `--view-entry-smoke` flag is an alias for this check.
FileExplorer `--views-smoke` isolates the view menu, icon galleries, List, compact Tree rows, lazy child loading, Find, selection, tab state, and cancellation.
FileExplorer `--partition-smoke` covers the partition flyout, all views, lazy Tree children, rapid changes, and tab, pane, and window inheritance.
The flyout checks cover menu keyboard input, command icons, checked state, and dismissal.
Run `dotnet run --project bindings\dotnet\Tests -c Release -- --features` for feature bindings, including compact menu creation and command icons.
FileExplorer `--pane-animation-smoke` isolates split entry and reports observer timing and native clock delivery.
These modes create temporary fixtures and close their own window.

For animation delivery during sustained posted updates, run:

```powershell
cmake --build $build --config Release --target xui_animation_queue_window_tests
ctest --test-dir $build -C Release -R "^xui_animation_queue_window_tests$" --output-on-failure -j 1
```

The desktop fixture covers both application entry points, intermediate painting, terminal settlement, immediate mode, and idle work.
It also closes one active window while another window continues its own animation and posted updates.
Its child-timer case checks native timer delivery during posted traffic.
Its shutdown case posts a nonzero quit code after a real animation update and requires normal loop exit.
The traffic observer does not force animation clocks or paints.

## C# and declarative samples

After the native build, run a sample:

```powershell
dotnet run --project bindings\dotnet\DeclarativeSample -r $rid
```

Sample builds copy this checkout's `build\<architecture>\Release\xui.dll` into their output.
Publish copies the same DLL into its output.
The default sample architecture matches the host Windows architecture.
`-r win-x64` or `-r win-arm64` selects another architecture.
`XuiNativeConfiguration=Debug` selects a Debug native build.
`XuiNativeDir` selects an explicit native output directory.
A missing DLL stops the build with a diagnostic and native build commands.
No XUI entry in `PATH` is necessary.

For the development loop, use:

```powershell
dotnet watch --project bindings\dotnet\DeclarativeSample --non-interactive "-p:RuntimeIdentifier=$rid"
```

Edit `bindings\dotnet\DeclarativeSample\Counter.xui`.
Supported property and handler edits preserve state.
Structural edits require window replacement or process restart and reset transient state.
The [language guide](../contracts/xui-language.md) describes project integration and reload behavior.

For restart-on-save without in-place hot reload, add `--no-hot-reload` to the watch command.
If you change the compiler, stop the watcher before rebuilding it.
Windows can keep the analyzer assembly open while the watcher runs.

Use `bindings\dotnet\Minesweeper` instead of `DeclarativeSample` to run the game.
Use `bindings\dotnet\Sample` for the handwritten C# sample.
Run the generated executable or use `dotnet run`.
Direct `dotnet Sample.dll` execution does not apply the apphost's native-control manifest.

### XUI Designer

After the native build, run the designer:

```powershell
dotnet run --project bindings\dotnet\Designer -c Release -r $rid
```

To open an existing trusted component, append its path:

```powershell
dotnet run --project bindings\dotnet\Designer -c Release -r $rid -- "C:\Projects\Demo\Counter.xui"
```

The designer uses the same native DLL selection as the other C# samples.
Its runtime includes the XUI generator and the SDK Roslyn assemblies.
It does not support NativeAOT, trimming, or single-file publishing.
The [designer guide](../samples/designer.md) describes preview limits, shortcuts, file behavior, and recovery drafts.

Run the compiler tests without a native DLL:

```powershell
dotnet run --project bindings\dotnet\Designer.Tests -c Release
dotnet run --project bindings\dotnet\Designer.TemplateTests -c Release
dotnet run --project bindings\dotnet\Designer.DocumentTests -c Release
dotnet run --project bindings\dotnet\Designer.DiagnosticsTests -c Release
```

The template tests compile every built-in example and reject compiler warnings.
The template sources are under `bindings\dotnet\Designer\Templates`, with the counter example in `Starter.xui`.
The document tests cover atomic saves, disk conflicts, UTF-8 input, and recovery snapshots without a native DLL.
The diagnostics tests cover native paragraph offsets, Unicode selection, stale revisions, and locations from the real compiler.

Run the source hierarchy and visual edit tests without a native DLL:

```powershell
dotnet run --project bindings\dotnet\Designer.SourceTests -c Release
```

This suite checks exact UTF-16 ranges, source preservation, stale revisions, container rules, and generated compilation.
Dimension codec checks cover numeric syntax, culture independence, exact tuple preservation, input limits, and expression and comment refusals.
It also checks opt-in element mapping with the existing managed generator fakes, without native DLL calls.
Diagnostic checks cover exact expression columns and the actual preview compiler output.
The [source API contract](../samples/designer.md#source-editing-api) describes edit proposals and editor integration.

After the native build, run the generated RangeInput and Progress checks:

```powershell
dotnet run --project bindings\dotnet\ValueControls.Tests -c Release -r $rid
```

The fixture uses the actual `.xui` generator and this checkout's native DLL.
It checks construction order, numeric updates, callbacks, defaults, invalid values, and opt-in element mapping.
It also opens a bounded native window and closes it through the window dispatcher.

After the native build, run the desktop smoke test:

```powershell
dotnet run --project bindings\dotnet\Designer.Preview.Tests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer -c Release -r $rid -- --smoke
dotnet run --project bindings\dotnet\Designer.RecoveryTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.GroupingTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.TextModeTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.NavigationTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.SearchTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.ViewportTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.CommandTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.IndentationTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer -c Release -r $rid -- --builder-smoke
dotnet run --project bindings\dotnet\Designer -c Release -r $rid -- --file-smoke
dotnet run --project bindings\dotnet\Designer -c Release -r $rid -- --selection-smoke
dotnet run --project bindings\dotnet\Designer.LayoutTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.WorkspaceTests -c Release -r $rid
dotnet run --project bindings\dotnet\Designer.DiscardTests -c Release -r $rid
cmake --build $build --config Release --target xui_content_host_window_tests
& ".\$build\Release\xui_content_host_window_tests.exe"
cmake --build $build --config Release --target xui_abi_features_tests
& ".\$build\Release\xui_abi_features_tests.exe" --activation
```

The preview regression opens one window with native editor and preview content.
It covers repeated replacement, bounded handles, candidate rollback, source versions, scoped callback errors, and editor identity, selection, and undo.
It also checks that replacement does not change foreground activation.
The smoke test opens the designer with its embedded preview.
It covers native layout, compiler diagnostics, preview construction errors, recovery after those errors, and file operations.
It also checks retained native control IDs and authored state after formatting-only edits and undo, theme changes without recompilation, and deliberate state reset on explicit Render.
The recovery UI test uses isolated drafts and a real native `ContentDialog`.
It covers draft selection, recovery copies, dirty-source protection, confirmed deletion, corrupt metadata, and file races.
The grouping UI test uses the production hierarchy and inspector with native source editing.
It covers wrap buttons, root replacement, unwrap refusals, hierarchy shortcuts, and native undo.
The navigation UI test covers diagnostic buttons, F8 routing, exact native selections, stale source, and replaced diagnostic text.
It also covers the native Go to dialog in Classic and WinUI, Unicode boundaries, Enter/Escape, revision guards, cancellation, and undo.
The source-search UI test covers literal matching, native selection, current-source offsets, keyboard routing, and undo preservation.
It also covers Unicode word boundaries, single and bulk replacement, no-op edits, native undo and redo, and atomic length-limit errors.
The viewport UI test covers preset and custom dimensions, invalid input, vertical scrolling, and retained preview state.
It also covers the anchored size flyout, Reset cropping, requested versus actual dimensions, native Escape, and a narrow preview pane.
The workspace UI test covers the Add control flyout in both styles, native query input, focus restoration, source guards, cancellation, and disposal.
It also checks reveal-before-focus commands for auto-hidden hierarchy and properties panes without opening them during background parsing or source selection.
The layout UI test checks toolbar spacing at the default width and at 980 DIP.
It also checks independent pane pinning, manual overlay opening, left/right geometry, native field occlusion, outside-focus dismissal,
pane-owned popups, native-editor Escape, and retained HWNDs, queries, drafts, source selection, and undo across both styles and all three themes.
Adaptive presentation geometry and ABI validation are covered by `xui_style_layouts_tests` and `xui_abi_features_tests`.
`GeneratorTests` covers the two-child markup constructor and retained reactive presentation.
Run native UI suites sequentially because they share desktop focus.
The command UI test uses the native CommandSurface in Classic and WinUI.
It covers native query input, Enter, Escape, focus, disabled commands, changed availability, duplicate invocation, cancellation, and source undo.
The source-indentation UI test covers Enter, leading-whitespace and selected-line Tab/Shift+Tab, native undo, selection mapping, focus, and atomic length-limit errors.
It also covers line comments in both visual styles, selected-line boundaries, Unicode, blank lines, mixed prefixes, read-only source, and atomic length refusals.
Source-line duplication coverage includes both styles, exact text and selections, trailing empty lines, Unicode, one-action undo/redo, focus routing, and length limits.
Source-line movement coverage includes both styles, multiline selections, final and empty lines, Unicode, maximum-length source, boundary refusals, and native undo/redo.
Source-line deletion coverage includes both styles, selection boundaries, final separators, Unicode, maximum-length source, read-only refusals, focus routing, and native undo/redo.
The selection smoke uses actual native preview clicks in the full application.
It covers Find, authored-handler suppression, version guards, source and hierarchy selection, native undo, and explicit stale-preview refusal.
It also covers outline feedback for the selected control and immediate invalidation after a source revision.
Source replacement also exercises hierarchy updates, preview compilation, and one-action undo through the complete application.
Selected-text search checks cover native query contents, source-only shortcuts, current selections, matching options, Unicode, line boundaries, query limits, and undo in both styles.
The application selection smoke checks palette actions, disabled empty selections, hierarchy synchronization, and retained live preview state.
Viewport checks cover exact Compact dimensions, retained preview versions and state, native picking, and a return to Fit.
Command checks cover shortcut routing, pointer-mode exit, native dismissal, discard protection, and focus inside the scrollable inspector.
Structural command checks cover duplicate, delete, movement, each wrapper, and unwrap through the native palette.
They check live preview text, arranged order, selected nodes, disabled root actions, and exact source undo.
Relative selection checks cover parent, first-child, sibling, and root commands through the native palette without replacing the live preview.
Go to checks cover the header action, command palette, source-only shortcut, exact caret, hierarchy synchronization, and retained preview state.
The text-mode UI test covers decoded string editing, exact no-op preservation, mode conversion, native undo, encoded-length errors, and named property resets.
It also focuses 64 populated fields in a scroll view in both styles, including first-time WinUI clear-button creation and repeated focus.
These checks preserve native selection, select-all behavior, and scroll reveal when the native peer list grows.
It also covers native width/height fields, dimension drafts, invalid conversion, size resets, focus, and stale-source rejection.
Boolean checks cover native toggles in both visual styles, raw drafts, exact no-ops, compilation, undo/redo, reset, and stale-source rejection.
The selection smoke checks exact native preview sizes after a dimension edit and its source undo.
It also checks the actual native enabled state after a boolean edit, and restoration through source undo.
Inset checks cover uniform and four-sided values, draft conversion, numeric limits, native fields, focus, reset, stale source, and undo in both styles.
Draft reversion checks cover raw and structured modes, invalid fields, retained filters, unset properties, expression refusals, busy/stale guards, and unchanged source undo.
The application selection smoke checks its command-palette entry, disabled expression actions, and unchanged preview dimensions.
The source suite checks exact formatting, cultures, rejected syntax, source limits, and compiled inset changes across control kinds.
The application selection smoke checks the actual native label height after a padding edit and source undo.
Color codec checks cover RGB24 literals, exact no-ops, whitespace, rejected expressions, source limits, and compilation across color properties.
Native color checks cover channels, invalid-input recovery, opaque alpha, Escape/cancel, draft updates, stale source/selection/drafts, disposal, and source undo in both styles.
The application selection smoke checks palette dispatch, unchanged preview ownership before Apply, and native foreground values after Apply and undo.
Comment checks cover palette and shortcut routing, native preview removal/restoration, and separate undo operations through the complete source pipeline.

The builder smoke covers hierarchy selection, literal edits, palette insertion, structure commands, native undo and redo, and stale-edit rejection.
Palette checks cover name and description search, empty results, retained selection, filtered insertion, and source undo.
It also covers read-only expressions and recovery from invalid source without replacing the native document.
The file smoke uses an isolated recovery directory and the complete application.
It covers automatic drafts, the native recovery picker, disk conflicts, persistent file errors, and native edits after an invalid file opens.
It also covers real native Open and Save As results, cancellation, file shortcuts, explicit discard approval, and stale chooser results.
The layout smoke uses the production `.xui` layouts without the runtime compiler or preview host.
It covers pane bounds, pane order, native selection, and source preservation across theme changes.
The workspace suite runs the same builder smoke against production controllers without the preview host.
It also covers hierarchy search in both visual styles, native queries, match navigation, collapsed ancestors, revision guards, invalid source, and undo preservation.
Property search checks cover native queries, authored-only results, stable choice keys, retained raw and structured drafts, expressions, source revisions, and undo.
Property source checks cover exact UTF-16 and multiline selections, literals, expressions, references, event-handler names, retained drafts, refusals, and native undo.
They also edit a revealed expression and compile a subsequent property change in both styles.
The application selection smoke checks property-search focus, native query bounds, and unchanged preview geometry while a draft remains active.
It also checks property-source command availability, exact source selection, and retained native preview identity.
Sibling insertion checks cover before/after buttons, filtered templates, nested parents, Grid cells, structural refusals, native undo/redo, and cancellation by source typing.
Structural availability checks compare shared capabilities with native buttons for variable-child parents, fixed-child parents, roots, and movement boundaries.
They also cover busy/stale states, Grid duplication, and native undo in both styles.
Relative selection workspace checks cover nested parents, collapsed ancestors, boundaries, UTF-16 ranges, focus, filters, and one notification per selection.
They check exact-snapshot mismatches, pending edits, invalid source, disposal, recovery, and retained source undo in both styles.
Hierarchy expansion checks cover native descendant rows, retained nested expansion, partial cancellation, selection/source invalidation, disposal, property drafts, and undo in both styles.
The application selection smoke checks expansion/collapse commands, disabled leaf actions, and retained source selection and preview state.
Empty-cell checks cover native Grid coordinates, nested target selection, read-only discovery, explicit refusals, busy/stale guards, and insertion undo in both styles.
The source suite covers occupancy combinations, spans, large track arrays, unknown tracks, invalid placement, revisions, cancellation, and compiled insertion.
It compiles source transformations but does not execute authored preview code.
The application selection smoke checks sibling insertion against native preview text, arranged order, and restoration through source undo.
It also inserts a native preview control into a discovered Grid cell and checks separate undo operations.
The discard UI test covers native cancel and undo preservation, deferred approval, and rejection of stale source or revision snapshots.

The following opt-in diagnostic currently fails for programmatic owner closure during a native chooser in the complete designer:

```powershell
dotnet run --project bindings\dotnet\Designer -c Release -r $rid -- --file-close-smoke
```

It retains separate startup and cancellation deadlines, native HWND teardown checks, and rejection of late UI callbacks.
Its fallback Cancel action ends the failed fixture. That action does not count as successful programmatic cancellation.
The activation test checks the separate public window contract for foreground activation and initial keyboard focus.
`XUI_DESKTOP_TESTS=ON` also registers the activation test with CTest.

### C# file explorer

The explorer uses the same automatic DLL copy as the other samples:

```powershell
dotnet build bindings\dotnet\FileExplorer -c Release -r $rid
& ".\bindings\dotnet\FileExplorer\bin\Release\net10.0\$rid\FileExplorer.exe" "D:\Documents"
```

If the explorer closes unexpectedly, capture its error output and process exit code:

```powershell
$exe = (Resolve-Path "bindings\dotnet\FileExplorer\bin\Release\net10.0\$rid\FileExplorer.exe").Path
$errorLog = Join-Path $env:TEMP "xui-file-explorer-error.log"
$process = Start-Process -FilePath $exe -ArgumentList "`"$PWD`"" -PassThru -Wait -RedirectStandardError $errorLog
Get-Content $errorLog
$process.ExitCode
```

PowerShell can return immediately after it starts a GUI executable.
`$LASTEXITCODE` alone does not prove that the explorer finished successfully.
The command above waits until the explorer closes and preserves managed error details.

For markup changes, use restart-on-save:

```powershell
dotnet watch --project bindings\dotnet\FileExplorer --no-hot-reload --non-interactive "-p:RuntimeIdentifier=$rid"
```

The explorer disables in-place reload because its controllers own asynchronous work and native event subscriptions.
A restart resets transient pane state. Bookmarks and recents retain their normal persistence behavior.
The DLL must include the visual-style API in `xui_layout.h`.
File clipboard and drag-and-drop commands also require the file-transfer APIs from this checkout.
The New tab buttons require the tab-action APIs from this checkout.
An older `xui.dll` does not provide these APIs.

The focused address-bar smoke covers compact geometry, chevrons, trailing-space activation, palette shortcuts, folder dropdowns, cancellation, ancestor navigation, and pane isolation:

```powershell
$exe = (Resolve-Path "bindings\dotnet\FileExplorer\bin\Release\net10.0\$rid\FileExplorer.exe").Path
$process = Start-Process -FilePath $exe -ArgumentList "--address-smoke" -PassThru -Wait
$process.ExitCode
dotnet run --project bindings\dotnet\FileExplorer.Tests -c Release
```

The complete `--smoke` run includes these address-bar checks.
The address-bar checks also cover shared declarative styles, unchanged-path identity, and the 64-segment limit.
The model suite covers drive roots, UNC shares, extended paths, Unicode names, and deep paths without network access.

The directory-change smoke deletes disposable fixture files and folders through Windows Shell.
It covers the Delete key in every file view, context-action deletion, native text input, and automatic updates in both panes.
It also covers external renames, external deletion, retained Columns paths, navigation, and hidden-pane recovery.
The smoke checks multi-selection retention and cancellation after a selection change.
Windows can show its normal deletion confirmation dialog.

```powershell
$process = Start-Process -FilePath $exe -ArgumentList "--directory-changes-smoke" -PassThru -Wait
if ($process.ExitCode -ne 0) { throw "Explorer directory changes smoke failed." }
dotnet run --project bindings\dotnet\FileExplorer.Tests -c Release
```

The model suite covers filesystem notifications, watcher disposal, and column snapshot updates.

The customization checks cover key sequences, shortcut conflicts, import errors, legacy state, and native editor shortcut ownership:

```powershell
dotnet run --project bindings\dotnet\FileExplorer.Tests -c Release
$exe = (Resolve-Path "bindings\dotnet\FileExplorer\bin\Release\net10.0\$rid\FileExplorer.exe").Path
$process = Start-Process -FilePath $exe -ArgumentList "--customization-smoke" -PassThru -Wait
if ($process.ExitCode -ne 0) { throw "Explorer customization smoke failed." }
```

The desktop check applies settings to both panes and opens the searchable settings editor.
It clicks native toolbar buttons after customization and checks palette ownership, repeated theme changes, navigation toggles, and settings resets.
It also clicks settings page buttons and checks global search, retained drafts, conditional reset visibility, stable field widths, and command icons.
Queued toolbar commands must retain their pane and check availability again before execution.
The smoke uses isolated state and does not change the normal saved settings.

The native palette appearance check covers separate shortcut keycaps with and without font customization:

```powershell
& ".\$build\Release\xui_collections_window_tests.exe" --palette-only
if ($LASTEXITCODE -ne 0) { throw "Palette appearance check failed." }
```

It captures only its own nonactivating windows.
The checks cover empty shortcuts, aliases, key sequences, custom fonts, selection, disabled commands, narrow widths, themes, and DPI scales.

The settings opening check measures the first opening and seven repeated openings with both panes open:

```powershell
$process = Start-Process -FilePath $exe -ArgumentList "--settings-open-smoke" -PassThru -Wait `
    -RedirectStandardOutput "settings-open.out" -RedirectStandardError "settings-open.err"
Get-Content "settings-open.out"
Get-Content "settings-open.err"
if ($process.ExitCode -ne 0) { throw "Explorer settings opening smoke failed." }
```

Run this check without concurrent desktop tests or a debugger.
The popup must be visible, arranged, and ready for native input before each sample completes.
The check reports handler time and handler time plus pending native painting.
The handler budget is 250 ms for the warm median and 500 ms for the first opening and maximum.
With native painting, these budgets are 350 ms and 650 ms.
The General page must add fewer than 180 native child windows.
The check also covers draft retention, deferred page inputs, global search, dismissal cleanup, and reopening after all pages were visited.
These measurements exclude compositor presentation latency.
The native deferred-reveal check covers ownership, typography, focus, undo state, hidden content replacement, and popup cleanup:

```powershell
& ".\$build\Release\xui_reveal_window_tests.exe" --deferred-only
if ($LASTEXITCODE -ne 0) { throw "Deferred reveal check failed." }
```

The settings scroll check measures global search across all settings pages with both panes open:

```powershell
$process = Start-Process -FilePath $exe -ArgumentList "--settings-scroll-smoke" -PassThru -Wait `
    -RedirectStandardOutput "settings-scroll.out" -RedirectStandardError "settings-scroll.err"
Get-Content "settings-scroll.out"
Get-Content "settings-scroll.err"
if ($process.ExitCode -ne 0) { throw "Explorer settings scroll smoke failed." }
```

Run this check without a debugger or concurrent performance tests.
Use normal line-based Windows wheel scrolling.
The check uses isolated state, eight warmup messages, and forty measured wheel messages.
It requires actual movement and checks round-trip geometry, native editor identity, focus, unsaved drafts, search, and a subsequent settings update.
The wheel-handler budgets are 16 ms median and 32 ms p95.
The combined wheel-handler and native-paint budgets are 32 ms median and 64 ms p95.
The combined measurement flushes pending paint messages before each sample ends.
Neither measurement includes compositor presentation latency or measures display frame rate.
The output also includes the row count and the native child-window count for the entire Explorer window.

The context-action check opens the search popup against real Shell metadata.
It covers the native editor, captured paths, canonical favorites, hidden app actions, and stale selection cancellation.
It does not run real Shell commands.

```powershell
$process = Start-Process -FilePath $exe -ArgumentList "--context-actions-smoke" -PassThru -Wait
if ($process.ExitCode -ne 0) { throw "Explorer context actions smoke failed." }
```

`xui_shell_menu_tests` separately checks command invocation with a fixture COM provider.
Its snapshot checks cover canonical verbs, original command IDs, cancellation, and stale handle rejection.

The focused preview smoke covers metadata, native text, images, cancellation, and preview windows after their Explorer window closes.
It also checks date preferences after declarative metadata becomes visible and after preferences change:

```powershell
$process = Start-Process -FilePath $exe -ArgumentList "--preview-smoke" -PassThru -Wait
$process.ExitCode
```

The complete `--smoke` run includes the same preview checks.

#### Shell menu prefetch experiment

The native probe uses the same asynchronous Shell worker as the C# explorer.
It discovers commands without displaying a menu or invoking a Shell verb.
It does not change directory navigation.
Each probe process starts with a fresh worker. Windows and external Shell services can retain their caches between processes.

Build the probe:

```powershell
cmake --build $build --config Release --target xui_shell_menu_tests --parallel 4
$probe = ".\$build\Release\xui_shell_menu_tests.exe"
$target = ".\bindings\dotnet\FileExplorer\Models"
$warmup = ".\bindings\dotnet\FileExplorer"
```

Run the control and the completed-prefetch case in separate processes:

```powershell
& $probe $target --prefetch-probe - 0
& $probe $target --prefetch-probe $warmup 0
```

The arguments are `TARGET --prefetch-probe WARMUP_OR_DASH DELAY_MS`.
A dash disables prefetch. The delay accepts integers from 0 through 60000.
The probe waits for prefetch completion and handler release before the delay starts.
It then discovers the target twice, with fresh handlers for each request.
This is the best case for hidden prefetch cost, not a measurement of a click during unfinished prefetch.

For the idle-timeout comparison, use `11000` for both commands.
The worker exits after ten idle seconds.
For other target types, use `.\build\ARM64\CMakeCache.txt` or `.\assets\branding\generated\zoey-32.png`.
Replace `ARM64` with the configured architecture.
For a text warmup, use `.\CMakeLists.txt`.
Repeat each pair in alternating order to reduce order effects.

The CSV output reports `phase`, `ready_ms`, `cleanup_ms`, `entries`, and `foreground_changed`.
The phases are `prefetch`, `target-first`, and `target-repeat`.
Ready time includes worker startup, provider construction, and top-level metadata discovery.
Cleanup time includes the metadata snapshot and cancellation through handler release.
Polling adds scheduler-dependent overhead. These times do not measure menu painting or C# navigation.
The foreground flag reports a change between samples, not its cause or the absence of transient activation.
Discovery errors, missing paths, invalid delays, and waits beyond the deadline produce a nonzero exit code.
Installed Shell extensions determine the results. This probe is not a fixed latency gate.

The [experiment notes](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/shell-menu-discovery.md#prefetch-experiment-september-19-2026) record the initial measurements and limitations.

#### Try prefetch inside FileExplorer

Build the matching DLL and explorer:

```powershell
cmake --build $build --config Release --target xui --parallel 4
dotnet build bindings\dotnet\FileExplorer -c Release -r $rid "-p:XuiNativeDir=$PWD\$build\Release"
$exe = ".\bindings\dotnet\FileExplorer\bin\Release\net10.0\$rid\FileExplorer.exe"
```

Run the experiment:

```powershell
& $exe "$PWD" --prefetch-shell-menus
```

The title includes `[menu prefetch]`.
Each successful directory navigation requests one hidden menu for that directory.
The request runs outside the UI thread and retains no menu commands.
New navigation, tab changes, pane closure, and window closure cancel obsolete work.
Interactive menu requests take priority, but an extension already inside COM can delay them.
Discovery failures and skipped requests produce Windows debugger diagnostics.
This mode does not guarantee faster menus.

For the control, run the same executable without the flag:

```powershell
& $exe "$PWD"
```

For a navigation smoke with prefetch enabled, run:

```powershell
$process = Start-Process -FilePath $exe -ArgumentList "--address-smoke", "--prefetch-shell-menus" -PassThru -Wait
$process.ExitCode
```

### NativeAOT and deployment

```powershell
dotnet publish bindings\dotnet\DeclarativeSample -c Release -r $rid -p:PublishAot=true
```

NativeAOT requires the matching Visual Studio native tools.
Publish restores the matching compiler packages.
Release output excludes the compiler and development reload host.

Static C++ applications need only their executable and Windows system components.
C ABI, Rust, and NativeAOT applications also need `xui.dll` beside the executable.
Framework-dependent C# applications need their managed files and the matching .NET runtime.
PDB files are optional diagnostics.

## Rust

The repository's Cargo configuration defaults to ARM64 and the static CRT.
For x64, explicitly select `x86_64-pc-windows-msvc`.
Use a Visual Studio developer shell for the target architecture.

```powershell
$target = if ($arch -eq "ARM64") { "aarch64-pc-windows-msvc" } else { "x86_64-pc-windows-msvc" }
$env:XUI_LIB_DIR = (Resolve-Path "$build\Release").Path
Push-Location bindings\rust
cargo build --workspace --release --target $target
Copy-Item "$env:XUI_LIB_DIR\xui.dll" ".\target\$target\release\deps\"
cargo test --workspace --release --target $target
cargo clippy --workspace --all-targets --release --target $target -- -D warnings
cargo fmt --all --check
Copy-Item "$env:XUI_LIB_DIR\xui.dll" ".\target\$target\release\"
& ".\target\$target\release\xui-sample.exe"
Pop-Location
```

`XUI_LIB_DIR` selects the directory with `xui.lib`.
The [binding reference](../contracts/bindings.md) describes ownership and callback errors.

## Release packages

The [package guide](../contracts/packages.md) describes consumption and deployment.
Release builds require both x64 and ARM64 C++ tools and Rust targets.
Each GitHub runner builds its own architecture.
The Designer requires a .NET SDK that matches its target architecture because it bundles the SDK's Roslyn assemblies.
For local builds, select the matching SDK through `PATH` before each architecture command. An x64-only .NET SDK cannot publish the ARM64 Designer; use an ARM64 host with an ARM64 .NET 10 SDK for that release:

```powershell
.\scripts\Build-Release.ps1 -Version 0.1.0 -Architecture x64 -StageDirectory build\release-stage
.\scripts\Build-Release.ps1 -Version 0.1.0 -Architecture ARM64 -StageDirectory build\release-stage
.\scripts\New-ReleaseAssets.ps1 -Version 0.1.0 -StageDirectory build\release-stage -OutputDirectory build\release-assets
.\tests\packages.ps1 -Version 0.1.0 -AssetDirectory build\release-assets -Architecture $arch
.\tests\templates.ps1 -Version 0.1.0 -AssetDirectory build\release-assets -Architecture $arch
.\tests\release-samples.ps1 -Version 0.1.0 -AssetDirectory build\release-assets
.\tests\release-designer.ps1 -Version 0.1.0 -AssetDirectory build\release-assets -Architecture $arch
.\tests\release-workflow.ps1
.\tests\release-packaging-unit.ps1
.\tests\native-copy.ps1 -Architecture $arch
```

NativeAOT release publishes and Rust/MSBuild consumers enter the selected Visual Studio developer environment automatically, including the installer directory needed by `vcvars` on machines without `vswhere` in `PATH`.
The MSBuild consumer fixture uses that installation's default platform toolset instead of a fixed `v143` toolset.
This keeps the consumer linker compatible with the release static libraries on Visual Studio 2022 and 2026.

Use a fresh staging directory for each release build.
The scripts preserve existing staging directories and stop instead of mixing old and new outputs.
The scripts find CMake and Visual Studio tools automatically.
Static package libraries disable link-time optimization to avoid compiler-version coupling from `/GL` objects.
NuGet and Cargo versions come from the supplied version. Package scripts do not edit tracked version files.
Compiler-only fixtures can set `XuiCopyNativeRuntime=false`.
Application builds must not use that escape hatch.

The workflow runs for tag pushes under `release/`.
It accepts only `release/Major.minor.rev`, with three numeric components and no leading zeroes.
It builds both architectures, the release samples, the Designer, both NuGet packages, and both Cargo crates.
The sample assets are `Xui.Samples.<version>.win-x64.zip` and `Xui.Samples.<version>.win-arm64.zip`.
Each archive contains native dependencies and size-optimized NativeAOT deployments without .NET debug symbols.
No separate .NET installation is necessary.
TaskCard remains available as tutorial source but does not ship in these archives.
`IsXuiReleaseSample=false` excludes a project from releases without excluding it from local native-copy checks.

The Designer assets are `Xui.Designer.<version>.win-x64.zip` and `Xui.Designer.<version>.win-arm64.zip`.
The Designer stays outside the NativeAOT sample inventory.
`scripts\Build-DesignerRelease.ps1` publishes self-contained, untrimmed, multi-file output with the runtime compiler and no debug symbols.
`Build-Release.ps1` stages that output under `designer\<rid>`, separately from `samples\<rid>`.
The Designer archives include the .NET runtime, licenses, notices, and file manifests.
The release workflow runs the extracted `Designer.exe --smoke` on each architecture before it creates the draft.
That check uses the bundled runtime and compiler without an SDK or XUI entry in `PATH`.

The workflow creates a draft release and attaches the assets and SHA-256 checksums.
It does not publish to NuGet.org or crates.io.
It refuses to replace assets on an already published GitHub release.

The script uploads one asset at a time.
It retries a failed upload up to four times, with delays of 5, 10, 20, and 40 seconds.
Each retry replaces any partial asset with the same name.
Successful uploads do not repeat during these retries.
If all five attempts fail, the script stops with the asset path and exit code.
A later run can replace the assets on the existing draft.

To request a release, push a tag from the intended commit:

```powershell
git tag release/0.1.0
git push origin release/0.1.0
```

Before publication, review the draft assets and generated notes.
XUI uses the root MIT license.
Both NuGet packages, both Cargo crates, and all sample and Designer ZIPs include that license.

### Project template package

`templates\xui` contains the application source and `.template.config\template.json`.
`packaging\Xui.Templates.nuspec` defines the template package.
`scripts\Pack-Templates.ps1` sets the generated `Xui` reference to the package version in a staging directory.
It does not edit the tracked template source or require a native build.

```powershell
.\scripts\Pack-Templates.ps1 -Version 0.1.0 -OutputDirectory build\template-assets
.\tests\templates.ps1
```

The standalone test packs, installs, generates, and uninstalls the template in an isolated template directory.
It checks package contents, version substitution, project names, current-directory generation, and preservation of C# preprocessor directives.
The test does not change the user's installed templates or package sources.
The `Project template` workflow runs this test for template changes.

With `-AssetDirectory`, the test also builds generated projects against the matching `Xui` release package.
These checks cover Debug hot reload, the explicit opt-out, Release output, and publish output.
The release workflow runs this mode for x64 and ARM64 before draft creation.
`-FrameworkSource` selects an alternate feed for Microsoft framework packages.

The C# template disables template-engine condition processing with `cnd` directives.
Without those directives, `dotnet new` removes the `XUI_HOT_RELOAD` branches before compilation.
Keep those directives in the template source.
They do not appear in generated applications.

The release assets include `Xui.Templates.<version>.nupkg` and its checksum.
Registry publication remains a maintainer action.
Before distribution through a registry, publish the matching `Xui` package to the same configured source.
The [template guide](../contracts/packages.md#create-a-project-with-dotnet-new) contains installation and application commands.

## Tests

### Native regression checks

The ordinary [Framework workflow](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/.github/workflows/framework.yml) runs on every PR
(without template/path filters), pushes to `main`, and manual dispatch.
Its Windows x64 MSVC job requires Python, .NET 10, Cargo, rustfmt, the bundled LSH
package/runtime, and a working native schema exporter. Missing requirements fail the job.
It is a correctness/allocation gate, not a desktop or timing acceptance run.
Repository branch protection must require **Windows headless core and contracts**;
adding the workflow alone does not change GitHub branch protection.

Run the same gate locally from the repository root in PowerShell 7:

```powershell
.\tests\framework-pr.ps1
# Equivalent individual workflow steps, sharing the same output:
.\tests\framework-pr.ps1 -Suite Native
.\tests\framework-pr.ps1 -Suite Bindings
```

Use `-BuildDirectory build\another-gate` for isolated outputs. The validated ordinary
runner is Windows x64; `-Architecture ARM64` is available for matching local toolchains
but is not an ordinary CI matrix promise. No Linux portability is implied.
The script uses the existing Visual Studio/CMake discovery helpers.
It explicitly selects the Rust target rather than inheriting the checkout's ARM64 Cargo default.
`Bindings` requires the matching `Native` outputs; it cannot silently become compiler-only.

MSVC Release builds with `XUI_ENABLE_IPO=ON` retain `/GL` and use **full `/LTCG`**,
not `/LTCG:incremental`. The root CMake link option maps to Visual Studio's
`<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>`.
The native gate checks actual `/GL` compilation and full-LTCG DLL/native-fixture link commands.
This avoids reusing stale code-generation caches across public virtual-interface edits;
IPO is not disabled. Ordinary configure/build commands must remain correct across those edits,
without developers manually evicting `.ipdb`/`.iobj` files.
When diagnosing a toolchain/build-mode mismatch, inspect the generated project and the
actual `link.command.1.tlog` under the target's Release intermediate directory: require
`/LTCG`, reject `/LTCG:incremental`, and confirm the compile command still contains `/GL`.
MSBuild may still emit an `/LTCGOUT` path; its presence alone does not enable incremental LTCG.
Use fresh, separately identified output directories for baseline/candidate acceptance regardless.
The [stage-2 ledger](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/architecture-review-2026-10-21.md#stage-2-evidence-october-21-2026)
records the observed transition, retained failed artifacts and mitigation evidence.

`xui_headless_tests` builds the headless CTest prerequisites, including `xui.dll`,
the style exporter, LSH, and the noninteractive runner. The runner starts CTest and the
binding/compiler commands on a private, non-visible Windows window station, with a bounded
child-process lifetime. It fails if that isolation cannot be established.
The [test inventory](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/testing.md#ordinary-framework-pr-gate) enumerates the selected
model, ABI, compiler, generated-contract, managed, and Rust coverage and exclusions.
Do not replace it with `-LE desktop`: absence of a label is not evidence of suitability.

To inspect the actual native selection after configuration:

```powershell
ctest --test-dir build\framework-pr -C Release -L "^headless$" --show-only=json-v1
ctest --test-dir build\framework-pr -C Release -L "^headless$" --no-tests=error --output-on-failure -j 1
```

The second command runs in the caller's session; use the gate script for the demonstrated
noninteractive execution. CI retains `headless-inventory.json`, JUnit `headless.xml`,
CTest logs, and configuration diagnostics. CTest failures, empty selections, compiler
failures, generated-file drift, and missing native exports must remain nonzero failures.
`python bindings\generate_features.py --check` and the native style `--check` do not rewrite outputs.
`tests\framework-gates.py --native-executable <absolute exporter path>` exercises stale
C#/Rust outputs, native schema mismatch, and a missing exporter in disposable copies.

`XUI_DESKTOP_TESTS=OFF` now omits all desktop registrations, including previously
unconditional swap-chain, ContentHost/inspection, editor, dialog, pixel, menu, and host fixtures.
The separate `system`-labelled Task Manager process-sampling fixture is not part of the PR
selection. Desktop executables remain buildable with the option OFF.
Enable the serial desktop registrations in a separate build:

```powershell
cmake -S . -B $build -DXUI_DESKTOP_TESTS=ON
cmake --build $build --config Release --parallel 4
ctest --test-dir $build -C Release -L "^desktop$" --no-tests=error --output-on-failure -j 1
```

Use an unlocked, interactive Windows desktop with working foreground/focus ownership,
matching DPI/monitor state, required fonts, and the expected Windows/GPU capabilities.
Graphics-capture tests need Windows Graphics Capture/DirectComposition and valid owned-window capture;
backdrop tests need Windows 11. Native editing acceptance needs installed **and enabled**
IME/TSF keyboards, physical composition/candidate coverage, clipboard/undo/selection, and UIA
providers/events plus manual screen-reader coverage as applicable.
A console session named `Default`, successful API calls, or a remotely accessible machine
does not prove those prerequisites. Ordinary hosted headless CI is not that acceptance environment.
Never weaken focus/pixel assertions, disable capture, or translate missing prerequisites into a pass.
Preserve failing logs and classify unresolved baseline failures separately from candidate failures.
Do not run builds, desktop suites, and measurements concurrently.

For a focused native change, select the relevant tests:

```powershell
ctest --test-dir $build -C Release -R "xui_(explorer|split_window)" --output-on-failure
ctest --test-dir $build -C Release -R "xui_abi" --output-on-failure
ctest --test-dir $build -C Release -R "xui_winui" --output-on-failure
ctest --test-dir $build -C Release -R "xui_miller" --output-on-failure
```

### Collection-family host checks

The ordinary gate includes `xui_family_accessibility_tests` and
`xui_family_accessibility_retirement_tests`: typed retained-provider/token/role contracts
and ten source/full-source/nonempty-selection release cases. The retirement test uses
another thread's bounded `try_lock`, not same-owner mutex behavior. Unknown selectors
and incomplete coverage fail explicitly. Both tests are required by name, with at
least 49 headless and two lifetime registrations; the core minimum remains 37.

Build the native probe and focused collection fixtures in a separate Release directory:

```powershell
cmake --build $build --config Release --target xui_collection_host_probe xui_collections_window_tests xui_grid_window_tests xui_collection_presentation_window_tests xui_scroll_tests
& ".\$build\Release\xui_collection_host_probe.exe"
& ".\$build\Release\xui_collections_window_tests.exe" --case 1 96
& ".\$build\Release\xui_grid_window_tests.exe"
```

The probe measures actual Window synchronization/publication/painting for one million
collection rows, 100,000 grid rows and 10,000 legacy rows. It checks unchanged editor
text/font/selection on scroll-only updates, a coalesced one-message update queue,
bounded nonempty selections, stable four peers/five child HWNDs/one target, and teardown.
Its controlled partial materialization failure attaches a collection before the grid
source throws, then requires explicit failure and complete native/renderer retirement.
Each process performs 32,768 scroll synchronizations, 8,192 selection publications,
8,192 source publications and 256 actual painted frames. It verifies exact final
offsets/selected keys, every selection callback and both source identity transitions,
and emits source-work counters and deterministic checksums. Owning-thread CPU includes
the raw kernel/user `GetThreadTimes` inputs; the runner validates these against derived
CPU, exact phase counts, actual work and resource bounds before accepting a sample.
It is not physical input/IME/Narrator latency evidence. Other desktop fixtures retain
their own foreground, pixel and UIA requirements and must not be silently skipped.

For an immutable pre-refactor source export/build and a fresh candidate build, compile
the **same current probe** against both libraries without modifying either build:

```powershell
$evidence = @{
    BaselineSource = "build\stage3a-baseline-source"
    BaselineBuild = "build\stage3a-baseline-final"
    CandidateBuild = $build
    EvidenceDirectory = "build\collection-host-comparison"
}
.\tests\collection-host-evidence.ps1 -Mode Build @evidence
# Reserve a quiet block with other users/coordinators first; no competing builds/tests/UI.
.\tests\collection-host-evidence.ps1 -Mode Measure @evidence -Warmups 2 -Samples 7
```

This x64 MSVC procedure retains exact `/O2 /MT /GL` compile and full `/LTCG` link
responses, compiler versions, source/library/executable hashes, every warmup/recorded
process and raw logs, including UTC start/completion endpoints. Revision order is
counterbalanced each round; `-CandidateFirst` reverses the initial order for a pre-agreed
independent block. A completed process beyond the 90-second elapsed budget also fails
even when its wait reports success. Measured-work mismatches stop immediately after
preserving parsed/raw data; do not restart or silently exclude failed samples.
Report phase wall and owning-thread CPU separately, exact work and allocations, distributions, retained
resources, and persistent regressions; do not call model throughput or paint wait time
application input latency. The [3a ledger](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/stage3a-collection-host.md) records
the immediate merged-stage-2 baseline and the unchanged failing desktop cases.

### Performance regression checks

#### Baseline/candidate acceptance protocol

Before a refactor, preserve separately built baseline and candidate artifacts identified by
**full commit IDs**, not just branch names. Record dirty state (must be clean for accepted
comparisons), generator, compiler/SDK/.NET/Rust versions, architecture, Release/Debug,
IPO and feature options (`XUI_REQUIRE_LSH`, WebView2, desktop registration), and binary hashes.
Keep equivalent toolchains/options and workload inputs; record intentional differences.
Record Windows build, CPU/RAM, GPU/driver, power plan, DPI/monitors, desktop/foreground state,
IME/provider availability, background processes, and any interference.

Build both revisions and finish correctness suites **before** measuring.
When changing optimizer/link settings, retain the real-default comparison and add a
separate baseline built with matching actual flags. IPO=ON alone does not equate
`/LTCG:incremental` and full `/LTCG`. Inspect and retain actual compile/link commands;
write matched outputs separately without modifying the preserved baseline source/artifacts.
Do not attribute an optimizer-mode comparison solely to the source refactor.
Coordinate a machine-wide quiet interval: no builds, other suites, competing measurements,
debugger, or unrelated desktop interaction. Do not reuse a mutable output directory.
For each workload, run at least two discarded warmups per revision and seven recorded runs
per revision; alternate baseline/candidate order, including which revision runs first.
Increase the sample count when dispersion obscures a decision. Existing fixture-internal
sampling does not replace repeated process-level comparisons.
For example, with two prebuilt x64 Release directories:

```powershell
$versions = @{ baseline = $baselineRelease; candidate = $candidateRelease }
$workloads = @("xui_layout_performance_tests", "xui_performance_tests", "xui_image_tests")
New-Item -ItemType Directory -Force $evidence | Out-Null
foreach ($workload in $workloads) {
    foreach ($revision in @("baseline", "candidate")) {
        1..2 | ForEach-Object {
            & (Join-Path $versions[$revision] "$workload.exe") --benchmark | Out-Null
            if ($LASTEXITCODE -ne 0) { throw "Warmup failed: $revision $workload" }
        }
    }
    foreach ($sample in 1..7) {
        $order = if ($sample % 2) { @("baseline", "candidate") } else { @("candidate", "baseline") }
        foreach ($revision in $order) {
            & (Join-Path $versions[$revision] "$workload.exe") --benchmark `
                1> (Join-Path $evidence "$workload-$sample-$revision.out") `
                2> (Join-Path $evidence "$workload-$sample-$revision.err")
            if ($LASTEXITCODE -ne 0) { throw "Sample failed: $revision $workload $sample" }
        }
    }
}
```

`$baselineRelease`, `$candidateRelease`, and `$evidence` must be explicit, distinct absolute
paths. Save the environment/commit/workload record beside these raw samples. Keep exit codes,
order, timestamps, errors, and invariant counts, not only successful timing lines.
Summarize medians and tails where the fixture reports them, dispersion/uncertainty,
**absolute deltas with units** and relative deltas for latency, CPU, and private memory.
A reproducible regression **greater than 5%** on default-path latency, CPU work, or private
memory fails acceptance unless explicitly approved with a documented reason.
Small/noisy denominators require absolute deltas and more evidence, not a percentage-only claim.
Noisy, incomparable, missing, or failed runs are **unresolved/blocking**, never a pass.
Record results and approved exceptions in dated maintainer evidence, not the root README.

Use the existing fixtures rather than inventing a universal benchmark:

| Surface | Fixtures and evidence |
| --- | --- |
| Owned model traversal | `xui_owned_children_tests` checks exact direct identity/order and zero allocations; `xui_owned_children_probe` measures 2,000 complete walks of 8,737 nested nodes, including inactive pages and closed Reveal/composite content. See the paired probe procedure below. |
| Layout/core/large sources | `xui_layout_performance_tests --benchmark` (10,000-frame Stack/Grid cases, styled/unstyled); `xui_performance_tests --benchmark` (60/100k/1m legacy rows); `xui_collections_tests --benchmark` (projection, selection, source lookups). |
| Image identity/reconciliation | `xui_image_tests --benchmark` (8/64/512 preloaded rows); `--row-sync-only` enforces allocations without decode/windows. Full image/window fixtures separately cover decode, upload, stale delivery and cancellation. |
| Local property/style edits | `xui_styling_window_tests --benchmark`, repeating with `--styled-first`; retain CPU, p50/p95, HWND/target/paint counts and unchanged editor identity. `--lifetime-only` covers repeated style changes and cleanup. |
| Native text/retained scroll | `xui_scroll_tests --retained-only`, `xui_native_integration_tests`, `xui_window_tests`; verify focus/caret/IME/selection/undo/clipboard, placement and HWND/provider identity, not just elapsed time. |
| Content replacement/lifetime | `xui_content_host_window_tests`, `xui_content_inspection_window_tests`, `xui_application_abi_tests`, `xui_multiwindow_tests`, managed `Tests --headless`/`--window-native`/`--multiwindow`, and Rust `--lib`/application integration tests. Keep model-only and realized-desktop evidence distinct. |

#### Owned-child traversal probe

Build `xui_owned_children_probe` in the candidate's Release configuration.
Its output must report exactly 8,737 nodes, 17,474,000 visits and zero walk allocations;
checksum/count failures return nonzero. Checked `GetThreadTimes` snapshots surround that
same loop, excluding tree construction; raw kernel/user 100-nanosecond values and their
`thread_cpu_ms` delta report CPU separately from wall time.
It also records tree-construction allocated bytes,
process private bytes before/after the walks and Element/Control/SplitView sizes.
There are no HWNDs or source-backed rows in this workload.

`xui_owned_children_tests` with no arguments runs all family/policy/lifetime checks and the
walk; its explicit `--benchmark` mode runs only the exact-work/allocation walk and says so.
`xui_content_host_window_tests --model-only` never shows/runs a window; `--owned-only`
additionally runs the focused native lazy/replacement/active-collection contracts.
No arguments runs that fixture's full desktop suite. Both fixtures reject unknown,
empty or extra selectors with exit 2 before doing work.
To compare with a pre-contract revision, compile the **candidate probe source** against
the preserved baseline's headers and prebuilt `xui_core.lib`, defining
`XUI_BASELINE_OWNED_CHILDREN`. This test-only adapter uses the old Stack/Control/direct-slot
discovery without adding validation sets or allocating per walk; candidate code uses the
new virtual contract. Both execute the same constructed tree, exact node count and checksum.
Use the same compiler, architecture, CRT, Release optimization and IPO/LTCG settings.
Write the baseline probe executable/object/PDB into a new candidate/session artifact
directory, never into the readonly baseline checkout. Record the baseline library/header
commit, probe-source commit, commands and all binary hashes beside the samples.
Run the two executables with no arguments using the warmup/alternating process protocol above.
This comparison measures ownership-discovery CPU work, not application latency or a
whole-window speedup. Process startup/allocator granularity requires absolute private-byte
deltas as well as percentages. Existing layout, collection and row-image workloads remain
independent regression guards; native input/UIA and hosted realization require separate evidence.

Require zero steady-state layout/row-reconciliation allocations where already asserted,
bounded retained memory after warmup/settling and repeated cycles, and recorded peer/control
sizes where storage changes. Count HWNDs, render targets, idle paints/wakeups, topology/native/UIA
sync work, and editor/provider identity changes for affected surfaces. Unchanged controls may
not gain HWNDs, targets or idle activity; virtual sources may not gain per-item visuals.
Keep source lookups viewport-bounded, text/image caches bounded, row admission at 512 and its
pending queue at 48, and collection selection within its 4,096-term bound.
Exercise scroll, theme/style changes, lazy open/close, popup/modal cycles, replacement, close,
callback failure, cancellation, and stale delivery. A 5% tolerance cannot excuse an invariant
violation, lost native input/UIA events, unbounded retention, or silent errors.

For each later architecture PR, link the applicable pre-refactor functional baseline and
new comparison artifacts. A headless correctness pass or a build/CI-only change is **not**
a runtime speedup or complete native/performance acceptance.

Build the layout, collection, row-image, and text-cache fixtures:

```powershell
cmake --build $build --config Release --target xui_layout_performance_tests xui_collections_tests xui_collection_presentation_tests xui_image_tests xui_style_layouts_tests xui_style_collections_tests xui_style_grid_tests xui_style_basic_render_tests xui_style_navigation_render_tests
ctest --test-dir $build -C Release -R "^xui_(layout_performance|collections|collection_presentation|row_image_performance|style_layouts|style_collections|style_grid)_tests$" --output-on-failure
& ".\$build\Release\xui_style_basic_render_tests.exe"
& ".\$build\Release\xui_style_navigation_render_tests.exe"
```

The basic render fixture also checks clockwise pane-tab text, parent-transform restoration,
and outlined/filled pushpin pixels in both visual styles.

The layout fixture requires zero steady-state Stack scratch allocations and zero Grid track-buffer allocations.
It also covers reentrant layout, exceptions, changed constraints, child growth, styled alignment, and the 256-track Grid limit.
The collection fixtures cover projection boundaries, source lookup counts, identity, collapse, exceptions, and grid geometry.
They also require allocation-free grid focus changes and a single result allocation for nonempty selection enumeration over sources of at most 256 rows.
The row-image fixture runs `xui_image_tests --row-sync-only` without windows, fixture files, or image I/O.
It requires zero temporary allocations when reconciling settled images and checks identity, duplicates, input order, removal, and the 512-row limit.
The rendering fixtures cover text-cache identity, ownership, allocation counts, cache limits, and pixels.
The rendering fixtures create their own Windows rendering surfaces.

After other builds and tests stop, run the microbenchmarks:

```powershell
& ".\$build\Release\xui_style_basic_render_tests.exe" --benchmark
& ".\$build\Release\xui_collections_tests.exe" --benchmark
& ".\$build\Release\xui_layout_performance_tests.exe" --benchmark
& ".\$build\Release\xui_image_tests.exe" --benchmark
```

The text benchmark reports median lookup time for small and full caches.
It also reports the size of each retained cache entry.
The collection benchmark reports selection and projection workloads with source lookup counts, allocation counts, and cumulative requested bytes.
The layout benchmark reports changing-size measurement/arrangement pairs for styled and unstyled Stack and Grid layouts.
The row-image benchmark reconciles 8, 64, and 512 preloaded synthetic image rows in rotating input order.
It excludes input-vector/string construction and output capacity growth; it performs no image decode or GPU upload.
Benchmark mode permits historical baselines to report allocation counts that exceed the current regression budgets; run without `--benchmark` to enforce those budgets.
These results describe individual workloads, not application frame time or retained process memory.
The [maintainer report](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/testing.md#framework-performance-pass-september-19-2026) records the measurement scope.
The [October allocation pass](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/testing.md#layout-and-selection-allocation-pass-october-1-2026) records Grid and selection comparisons.
The [row-image reconciliation pass](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/testing.md#row-image-reconciliation-pass-october-1-2026) records lookup comparisons and native image coverage.

### Native presentation checks

For scroll-frame changes, build and run the presentation fixtures:

```powershell
cmake --build $build --config Release --target xui_flicker_tests xui_scroll_tests xui_native_integration_tests
ctest --test-dir $build -C Release -R "^xui_((winui_)?(scroll_frame|flicker)|scroll|native_integration)_tests$" --output-on-failure
```

These fixtures require `XUI_DESKTOP_TESTS=ON` and an interactive desktop.
The existing flicker fixtures also require an unobscured window.
The scroll-frame fixtures use owned-window capture without cursor pixels.
The scroll-frame fixtures save diagnostic BMP files under `scroll-frames` or `winui-scroll-frames` in the build directory after a pixel mismatch.

### Binding and compiler checks

Compiler and model checks do not need a native window:

```powershell
dotnet run --project bindings\dotnet\GeneratorTests -c Release
.\bindings\dotnet\GeneratorTests\BuildTests.ps1
dotnet run --project bindings\dotnet\FileExplorer.Tests -c Release
dotnet run --project bindings\dotnet\Minesweeper.Tests -c Release
```

For declarative UI integration, build the probe and use matching architecture arguments:

```powershell
cmake --build $build --config Release --target xui xui_language_probe
.\tests\xui-language.ps1 -NativeDirectory "$build\Release" -RuntimeIdentifier $rid
.\tests\minesweeper.ps1 -NativeDirectory "$build\Release" -RuntimeIdentifier $rid
$exe = (Resolve-Path "bindings\dotnet\FileExplorer\bin\Release\net10.0\$rid\FileExplorer.exe").Path
$process = Start-Process -FilePath $exe -ArgumentList "--smoke" -PassThru -Wait
if ($process.ExitCode -ne 0) { throw "Explorer smoke failed with exit code $($process.ExitCode)." }
```

Build the C# explorer before its smoke run.
These scripts use isolated fixtures. The explorer smoke does not write the normal state file.
The [test reference](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/testing.md) describes coverage and measurement protocols.
Physical IME, mixed-monitor transitions, and screen-reader speech still require manual coverage.

### Tab tear-out and merge

Run the native gesture fixture and the Explorer model checks:

```powershell
cmake --build $build --config Release --target xui xui_tab_drag_window_tests xui_tab_window_tests
& ".\$build\Release\xui_tab_drag_window_tests.exe"
& ".\$build\Release\xui_tab_window_tests.exe" --drag-indicator
dotnet run --project bindings\dotnet\FileExplorer.Tests -c Release
```

The native fixture uses a deterministic driver at the caption-down boundary.
It does not synthesize pointer input or move the real cursor.
If another window covers the target, the fixture checks occlusion rejection instead of target acceptance.
Its output reports that condition.
Dedicated hover cases use temporary topmost fixture windows without activation.
They check native hide and show transitions, reversible transfer, transparent overlays, and remainder Z-order.
The Explorer smoke checks model transfer through the managed drag handler.
`xui_tab_drag_window_tests.exe --single-tab` selects the single-tab native hover cases.
`FileExplorer.exe --smoke-hover` includes single-tab merges into a window with multiple tabs, cancellation, and deferred source retirement.

For physical drag coverage, press Ctrl+N in FileExplorer to create another window in the same application.
Drag tabs within a strip, outside the window, and onto the other window.
Before release, check that the target contains the dragged tab and the detached window is hidden.
Without release, drag away from the target and then onto it again.
Check that the detached window appears above the previous target.
Check that the remainder never appears above the detached window.
Repeat with the secondary pane, a single tab, a full target pane, and a maximized source.
During a detached drag, press Escape.
Check the folder history, Find text, selection, scroll position, and Columns state after each transfer.
Repeat across monitors with different DPI values.
The target marker must disappear after release, cancellation, or target closure.

### Toggles and progress

Run the model, native animation, pixel, and gallery checks sequentially:

```powershell
cmake --build $build --config Release --target xui xui_foundation_tests xui_foundation_window_tests xui_styling_window_tests xui_abi_features_tests xui_gallery xui_gallery_smoke
ctest --test-dir $build -C Release -R '^xui_(foundation_tests|foundation_window_tests|switch_ring_pixels)$' --output-on-failure
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --controls-only
& ".\$build\Release\xui_abi_features_tests.exe" --toggle-controls
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --toggle-controls
dotnet run --project bindings\dotnet\GeneratorTests -c Release
dotnet run --project bindings\dotnet\Designer.SourceTests -c Release
```

The pixel check covers switch geometry and circular progress in Classic, WinUI, and high contrast.
The window check covers keyboard input, UIA, animation, hidden controls, disabled ancestors, detached content, and minimized windows.
It respects the Windows animation preference without changing that preference.
The gallery check covers the `toggle-switch`, `toggle-button`, `progress-ring`, and `progress` pages.
With `XUI_DESKTOP_TESTS=ON`, CTest also registers this gallery check as `xui_winui_controls_gallery_smoke`.

### Choices, links, badges, and menus

Run the focused native and gallery checks sequentially:

```powershell
cmake --build $build --config Release --target xui xui_next_controls_tests xui_menu_bar_tests xui_next_controls_window_tests xui_menu_bar_window_tests xui_styling_window_tests xui_abi_features_tests xui_gallery xui_gallery_smoke xui_gallery_catalog_tests
ctest --test-dir $build -C Release -R '^xui_(next_controls_tests|menu_bar_tests|next_controls_window_tests|menu_bar_window_tests|next_controls_pixels)$' --output-on-failure
& ".\$build\Release\xui_gallery_catalog_tests.exe"
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --parity-only
& ".\$build\Release\xui_gallery_smoke.exe" ".\$build\Release\xui_gallery.exe" --parity-classic
& ".\$build\Release\xui_abi_features_tests.exe" --parity-controls
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --parity-controls
$env:PATH = (Resolve-Path "$build\Release").Path + ";" + $env:PATH
cargo test --manifest-path bindings\rust\Cargo.toml -p xui parity_controls -- --test-threads=1
```

The gallery checks cover CheckBox, HyperlinkButton, SelectorBar, InfoBadge, and MenuBar in WinUI and Classic styles.
They cover mixed checkbox state, disabled input, link callbacks, exclusive selection, badge updates, and menu commands.
The hyperlink example does not open a browser.
The menu example does not write files or change the clipboard.

### Independent windows

Run these desktop checks sequentially:

```powershell
cmake --build $build --config Release --target xui xui_multiwindow_tests xui_application_abi_tests
& ".\$build\Release\xui_multiwindow_tests.exe"
& ".\$build\Release\xui_application_abi_tests.exe"
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --multiwindow
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --window-icons
$env:PATH = (Resolve-Path "$build\Release").Path + ";" + $env:PATH
cargo test --manifest-path bindings\rust\Cargo.toml -p xui --test application -- --test-threads=1
```

The Rust integration executable embeds a common-controls v6 and per-monitor-DPI manifest.
The ABI check covers close callbacks, batched cancellation, retained errors, and worker posts concurrent with dispatcher destruction.
The managed check covers strong roots, deferred disposal, canceled posts, callback errors, and legacy sequential runs.
The Explorer smoke also closes Explorer before its text, image, and folder previews.
It checks real ownerless HWNDs, native text copying, image reuse, resize, and captured-target Open after opener disposal.
Smoke mode records Open targets instead of starting associated applications.
Manual coverage still includes cross-monitor DPI changes, taskbar grouping, physical IME, and screen-reader output.

### Content pointer inspection

Build and run the native inspection fixture and managed preview lifecycle suite:

```powershell
cmake --build $build --config Release --target xui xui_content_inspection_window_tests
ctest --test-dir $build -C Release -R '^xui_content_inspection_window_tests$' --output-on-failure
dotnet run --project bindings\dotnet\Designer.Preview.Tests -c Release -r $rid
```

The native fixture uses real HWND routes and registered retained nodes.
It covers clipping, editor state, explicit refusals, deferred delivery, and repeated replacement.
The managed suite adds ABI validation, source-version checks, observer retirement, and collectible assembly checks.
The [inspection contract](../contracts/bindings.md#content-pointer-picking) lists unsupported surfaces.
Physical IME, touch/pen hardware, and screen-reader speech require manual checks.

### Non-occluding selection outlines

Build the outline fixture:

```powershell
cmake --build $build --config Release --target xui xui_content_highlight_window_tests
```

Run geometry checks without desktop access:

```powershell
ctest --test-dir $build -C Release -R '^xui_content_highlight_geometry_tests$' --output-on-failure
```

With an available desktop, run the renderer and managed lifecycle checks:

```powershell
ctest --test-dir $build -C Release -R '^xui_content_highlight_window_tests$' --output-on-failure
dotnet run --project bindings\dotnet\Designer.Preview.Tests -c Release -r $rid
```

Do not run concurrent focus-sensitive desktop fixtures.
The native fixture checks original-perimeter pixels, native occlusion refusal, unchanged regions and input, and repeated retirement.
The [outline contract](../contracts/bindings.md#non-occluding-content-outlines) defines the conservative supported subset.

### Native file dialogs

Build and run the focused dialog checks:

```powershell
cmake --build $build --config Release --target xui_file_dialog_tests xui_file_dialog_native_tests xui_file_dialog_window_tests xui_file_dialog_abi_tests
ctest --test-dir $build -C Release -R "^xui_file_dialog_.*tests$" --output-on-failure
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --file-dialogs
```

These desktop fixtures open real owned Windows Shell dialogs and cancel them through bounded, owner-specific probes.
They cover Open and Save paths, Unicode, default extensions, invalid options, thread access, callback failures, and content-scope guards.
The native window fixture covers focus return, composition rejection, owner closure, and owner deletion during the modal loop.
The Save fixtures select unique absent destinations and assert that no file was created.
Each native window fixture uses `demo\xui.rc` and `/MANIFEST:NO`. The managed fixture uses the matching apphost manifest.
The probes use a local temporary directory to avoid unrelated Shell startup delays from remembered locations.

### Stack preferred sizing

Run the core and native Stack layout regressions:

```powershell
cmake --build $build --config Release --target xui_core_tests xui_stack_layout_window_tests
ctest --test-dir $build -C Release -R "^xui_(core_tests|stack_layout_window_tests)$" --output-on-failure
```

The core fixture covers both axes, nested flex allocation, natural sizing, explicit preferences, automatic overrides, padding, and size limits.
The native fixture uses the matching manifest and real RichEdit peers.
It checks nonzero source geometry, retained focus and HWND identity, preference changes, and native undo and redo after layout.

### Transparent label backgrounds

With `XUI_DESKTOP_TESTS=ON`, run the label background regression:

```powershell
cmake --build $build --config Release --target xui_style_layouts_window_tests
ctest --test-dir $build -C Release -R "^xui_label_background_window_tests$" --output-on-failure
```

The fixture captures only its owned window.
It checks transparent labels and TextInput captions in both themes and visual styles.
It also checks explicit fills, border-only styles, style removal, caption typography, native selection, and the editor's accessible name.

### Document range editing

Build and run the focused document checks:

```powershell
cmake --build $build --config Release --target xui xui_document_editing_tests xui_document_editing_window_tests xui_document_editing_abi_tests xui_documents_tests
ctest --test-dir $build -C Release -R '^xui_(document_editing.*|documents_tests)$' --output-on-failure
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --document-editing
```

The native fixture uses real RichEdit controls and the common-controls v6 manifest.
It covers exact native text, selection, undo, redo, callback counts, rejected edits, owner deletion, and the maximum document length.
Its composition checks use native composition messages. Physical IME interaction remains a manual check.
The ABI fixture covers strict UTF-8 spans, explicit errors, thread affinity, and unchanged failure outputs.
The C# fixture also covers the native `TreeView.Select` action.

### Control styling

Build and run the focused style checks:

```powershell
cmake --build $build --config Release --target xui xui_styling_tests xui_styling_window_tests xui_abi_features_tests
ctest --test-dir $build -C Release -R '^xui_(styling_tests|styling_window_tests|styling_lifetime_window_tests|abi_features_tests)$' --output-on-failure
dotnet run --project bindings\dotnet\Tests -c Release -r $rid -- --styling
dotnet run --project bindings\dotnet\GeneratorTests -c Release
.\bindings\dotnet\GeneratorTests\BuildTests.ps1
```

The presentation test requires `XUI_DESKTOP_TESTS=ON` for CTest registration.
It checks actual Direct2D pixels, native editor identity, resource retention, and idle paints.
The separate lifetime fixture runs replacement, clearing, theme, retained-editor,
and resource-teardown checks without the unrelated focus-adapter matrix.

For button focus geometry, run the pixel-only check:

```powershell
cmake --build $build --config Release --target xui_styling_window_tests
ctest --test-dir $build -C Release -R '^xui_button_focus_pixels$' --output-on-failure
```

This check uses a hidden Direct2D software target and does not require foreground focus.
It compares square, rounded, and pill outlines at 96, 144, and 192 DPI.
It covers local values, focused state rules, inherited part styles, unchanged defaults, Classic, and high contrast.
The compact gallery contains the corresponding **Keyboard focus shapes** specimens.
These pixel checks do not establish live keyboard-focus or native WinUI parity.

With `XUI_DESKTOP_TESTS=ON`, run the separate nonactivating adapter checks:

```powershell
ctest --test-dir $build -C Release -R '^xui_(button_focus|choice_focus|selector_focus|expander_interaction)_window_tests$' --output-on-failure -j 1
```

The button fixture checks external focus pixels through the window renderer for local values, named styles, unstyled buttons, and rounded hyperlinks.
It also checks all four focus edges and blur cleanup for default, square, and pill MenuBar headings.
`xui_menu_bar_tests` covers heading margins, measurement, hidden headings, narrow bounds, and authored root padding.
`xui_menu_bar_window_tests` covers the native keyboard and popup lifecycle in both visual styles.
The choice fixture checks the wider focus margin for binary Toggle, CheckBox, and rounded CheckBox.
Radio coverage includes selected-row placement, focused-state corners, selection movement, and unchanged unfocused pixels.
The selector fixture checks native focus strokes, square and pill corners, selection movement, ancestor clipping, and outline removal.
It also measures the centered sixteen-DIP selection marker in light and dark themes.
Its background checks cover transparent roots, selected and hovered items, and authored root and item fills.
The Expander fixture checks disclosure directions, hover and press fills, and cancelled-press cleanup.
The button fixture also checks ancestor clipping. The button and choice fixtures check outline removal.
All four fixtures preserve the same control composition and check unchanged native editor peers, text, and selection.
They set model focus after a fixture-local keyboard message, without foreground activation.
These checks do not establish live keyboard navigation.
The original `--button-focus-window-only` executable selector runs all four groups together.
The full styling suite also retains their combined coverage.
`xui_next_controls_pixels` also checks WinUI hyperlink text, subtle interaction fills, and disabled alpha at 96, 144, and 192 DPI.
Its checked-disabled Button checks cover native brush alpha, foreground, and border removal through default, legacy, and named-part painting paths.
Its navigation focus checks cover default and styled rows, group headers, square and rounded corners, oversized radii, viewport clips, and three DPI values.
The navigation checks also preserve Classic and high-contrast outlines.
That suite includes checkbox focus margins and resolved corner radii at the same DPI values.
It also compares default and rounded-root checkbox states against the shared WinUI indicator renderer.
Rounded surface checks cover continuous equal-width borders and square joins between rounded header and body surfaces.
Focus checks also cover top-only and bottom-only rounded outlines without a stroke across the clipping boundary.
`xui_switch_ring_pixels` covers WinUI switch thumb geometry and state brushes at three DPI values, plus authored switch and ProgressRing paint.
It also checks switch focus targets, corner radii, authored padding and alignment, and cached text geometry.

For the switch focus adapter, run the separate nonactivating fixture:

```powershell
cmake --build $build --config Release --target xui_style_layouts_window_tests
ctest --test-dir $build -C Release -R '^xui_switch_focus_window_tests$' --output-on-failure
```

This fixture checks external strokes, content-sized focus, ancestor clips, outline removal, retained peers, and text-layout reuse.
It uses model focus after a fixture-local keyboard message, not live keyboard navigation.

For closed ComboBox focus, run the two nonactivating fixtures:

```powershell
cmake --build $build --config Release --target xui_style_layouts_window_tests
ctest --test-dir $build -C Release -R '^xui_combo_focus(_layers)?_window_tests$' --output-on-failure -j 1
```

The main fixture checks the external highlight, accent marker, header exclusion, ancestor clips, disabled state, popup-open suppression, and blur cleanup.
It covers both styles and all three themes, with retained native editor identity, draft text, and peers.
The layer fixture checks popups, adaptive overlays, and adaptive overlays inside popups.
Both fixtures use model focus after a local keyboard message, not live keyboard navigation.
Their checks run through `Window::post` outside the native input callback.
The additional-control pixel suite checks highlight geometry and marker placement at 96, 144, and 192 DPI.
Its independent reference includes translucent fills, two-DIP strokes, and the fixed native highlight radius around different field radii.

For Slider-style RangeInput focus, run the nonactivating adapter:

```powershell
cmake --build $build --config Release --target xui_style_layouts_window_tests
ctest --test-dir $build -C Release -R '^xui_range_focus_window_tests$' --output-on-failure
```

This fixture checks horizontal and reversed vertical controls, root padding, ancestor clips, keyboard modality, disabled state, and blur cleanup.
The 100-by-100 vertical specimen also checks the leading WinUI track position, independently of the geometry helper.
Endpoint checks cover the full rail, the two-DIP thumb outset, viewport clipping, and removal of old pixels after value changes.
It preserves values, drag state, and native peers across both styles and all three themes.
Brush checks cover the solid outer thumb, translucent tracks over different backgrounds, disabled colors, and authored thumb restoration.
Root-only styles must preserve the default thumb appearance.
The additional-control pixel suite checks the separate horizontal and vertical focus margins at three DPI values.
It also covers very short focus targets, where an inner stroke cannot fit.

For authored field focus corners, run the nonactivating adapter and the pixel suite:

```powershell
cmake --build $build --config Release --target xui_style_fields_window_tests xui_styling_window_tests
ctest --test-dir $build -C Release -R '^xui_(field_focus_window_tests|next_controls_pixels)$' --output-on-failure -j 1
```

The adapter checks TextInput, MultilineText, RichText, PasswordInput, NumericInput, and editable ComboBox in light and dark themes.
Owned-window captures check rounded corners, visible focus edges, and outline removal after focus moves.
The adapter also checks TextInput native identity, text, selection, and undo.
It uses `Window::focus`, not live keyboard navigation.
The pixel suite covers absent, square, rounded, and oversized radii at 96, 144, and 192 DPI.
It also checks short fields and the unchanged Classic and high-contrast outlines.

For expanded WinUI surfaces, run the separate nonactivating fixture:

```powershell
cmake --build $build --config Release --target xui_style_layouts_window_tests
ctest --test-dir $build -C Release -R '^xui_expander_surface_window_tests$' --output-on-failure
```

This fixture compares default, text-only, and rounded-header Expanders in collapsed and expanded states.
It covers light, dark, high contrast, authored body styles, and retained peer identity.
Keyboard-modality checks cover rounded header focus and square lower focus corners after expansion.
They also cover external strokes, ancestor clipping, and complete frame restoration after blur.
These checks use model focus, not live keyboard navigation.

For the Toggle pilot, run these additional focused checks:

```powershell
cmake --build $build --config Release --target xui xui_control_tests xui_control_styling_tests xui_styling_window_tests xui_abi_c_test xui_abi_features_tests
ctest --test-dir $build -C Release -R '^xui_(control_tests|control_styling_tests|abi_c_test|abi_features_tests)$' --output-on-failure
& ".\$build\Release\xui_styling_window_tests.exe" --toggle-only
cargo test --manifest-path bindings\rust\Cargo.toml -p xui control_styling::tests -- --test-threads=1
```

The Rust test binary requires the matching native library and import library.
The Toggle presentation checks use native input, UIA, and owned-window rendering.
The `--toggle-only` option excludes the historical Button benchmarks and lifetime cycles.
Managed compiler and definition checks do not require an updated native library:

```powershell
dotnet run --project bindings\dotnet\GeneratorTests -c Release
dotnet run --project bindings\dotnet\Tests -c Release -- --styling-definitions
cargo check --manifest-path bindings\rust\Cargo.toml --workspace --tests
```

Use `xui_styling_window_tests.exe --trace-resources` to investigate transient USER-object failures.
Do not increase resource limits to hide an unexplained failure.

After all builds and other desktop tests finish, run the separate styled workload:

```powershell
& ".\$build\Release\xui_styling_window_tests.exe" --benchmark
```

The benchmark reports styled and unstyled CPU time, latency, and resource counts.
It does not replace a pristine baseline comparison.
Record repeated samples, medians, absolute deltas, and interference.
Do not report noisy results as performance acceptance.

`tests\button_style_probe.cpp` also compiles against the pre-style headers.
Use the same ARM64 or x64 Release library and compiler flags for both comparison executables.
For an ARM64 developer shell:

```powershell
cl /nologo /std:c++20 /O2 /EHsc /MT /Iinclude tests\button_style_probe.cpp `
    /Fo"$build\button-probe.obj" /Fe"$build\button-probe.exe" "$build\Release\xui_core.lib" psapi.lib /link /LTCG
& ".\$build\button-probe.exe"
```

Preserve the pristine executable before rebuilding.
Alternate pristine and changed runs without simultaneous builds or desktop tests.
The [styling evidence](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/control-styling.md) describes the initial samples and their limitations.

For a complete paired comparison, prepare both versions before reserving a quiet interval:

```powershell
.\tests\measure-button-styling.ps1 `
    -BaselineDirectory "$build\baseline-build\Release" `
    -ChangedDirectory "$build\Release" `
    -BaselineProbe "$build\button-baseline.exe" `
    -ChangedProbe "$build\button-final.exe" `
    -BaselineCollections "$build\baseline\xui_performance_tests.exe" `
    -OutputDirectory "$build\counterbalanced-comparison" -WindowPairs 6
```

The script performs no native builds or dependency restoration.
It alternates execution order, requires foreground ownership, and records detected interference.
It reports incomplete batches explicitly.
Its eight-minute deadline prevents another phase from starting after the agreed interval.
Individual test executables retain their own timeout guards.

### Binding generation and compatibility

After a feature-header or manifest change, regenerate the declarations:

```powershell
python bindings\generate_features.py
```

Normal `.xui` builds and managed style construction use checked-in catalogs.
They do not load the native DLL to discover schemas.
After a native schema change, build the exporter in the selected native build directory:

```powershell
cmake --build $build --config Release --target xui_style_catalog
python bindings\generate_control_styles.py --native-executable "$build\Release\xui_style_catalog.exe"
python bindings\generate_control_styles.py --native-executable "$build\Release\xui_style_catalog.exe" --check
dotnet run --project bindings\dotnet\GeneratorTests -c Release
```

The executable exports exact schemas and limits through the public C ABI.
Python does not load the target DLL into its own process.
Thus, an ARM64 exporter does not require an ARM64 Python installation.
The exporter also compiles exhaustive C/C++ identifier assertions.

The portable generator tests compare the snapshot against managed and compiler catalogs.
They exercise real managed definition validation with a native-load guard.
If Python is available, CTest registers the read-only `xui_control_style_catalog_parity` check.
That check compares the current DLL snapshot and all generated catalog files.

To regenerate from the checked-in snapshot without native execution, run:

```powershell
python bindings\generate_control_styles.py
python bindings\generate_control_styles.py --check
```

The ARM64 integration scripts discover the installed Visual Studio CMake and ARM64 C++ tools, including prerelease installations.
`binding-features.ps1` also publishes with `--no-restore`.
Before its first run, restore both managed projects for the required publish modes:

```powershell
foreach ($project in @("Tests", "Sample")) {
    dotnet restore "bindings\dotnet\$project" -r win-arm64 -p:PublishAot=true
}
.\tests\binding-features.ps1 -BuildDirectory $build
```

Use this script with an ARM64 native build and the installed ARM64 Rust toolchain.
It stores logs and deployment copies in the selected build's `bindings-validation` directory.
The `Sample-fdd`, `Sample-aot`, and `rust` subdirectories contain runnable clients with `--features` support.

The historical baseline script uses `build\arm64`:

```powershell
.\tests\phase4.ps1 -SkipMeasurements
```

That script requires a build configured with `XUI_DESKTOP_TESTS=ON`.
It covers native tests, C# tests, Rust tests, and the original UIA clients.
Use the individual build commands for other toolchain locations or architectures.

### Measurements and captures

```powershell
& ".\$build\Release\xui_performance_tests.exe" --benchmark
& ".\$build\Release\xui_menu_tests.exe" "$build\menu-captures"
& ".\$build\Release\xui_image_tests.exe" "$build\image-fixtures" --fixtures
```

The fixture command creates original images, including deliberately malformed files.
Use a dedicated output directory.
The repository also includes `measure-browser.ps1`, `measure-task-manager.ps1`, `measure-window-memory.ps1`, and `measure-resize-memory.ps1` under `tests`.
Their defaults refer to historical build locations.
Inspect their parameters before selecting another executable or output directory.
The [memory report](windows-gui-memory.md) defines the counters and reproduction methods.
Historical results are not performance guarantees.

## Optional WebView2

The default build has no WebView2 dependency.
The optional host requires the pinned SDK and an installed Microsoft Edge WebView2 runtime.
XUI does not install that runtime.

Restore the SDK version from `integrations\webview2\packages.config`:

```powershell
$version = '1.0.2903.40'
New-Item -ItemType Directory -Force "$build\packages" | Out-Null
Invoke-WebRequest "https://www.nuget.org/api/v2/package/Microsoft.Web.WebView2/$version" -OutFile "$build\packages\webview2.zip"
Expand-Archive "$build\packages\webview2.zip" "$build\packages\Microsoft.Web.WebView2.$version" -Force
$sdk = (Resolve-Path "$build\packages\Microsoft.Web.WebView2.$version").Path
cmake -S . -B $build -DXUI_ENABLE_WEBVIEW2=ON "-DXUI_WEBVIEW2_SDK_DIR=$sdk"
cmake --build $build --config Release --target xui_gallery xui_hosts_window_tests
ctest --test-dir $build -C Release -R '^xui_hosts_window_tests$' --output-on-failure
```

The [native-host reference](../contracts/scenes-and-hosts.md) describes explicit loads, allowed origins, and cleanup.

## VS Code syntax package

Use the [extension README](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/integrations/vscode-xui/README.md) for packaging, installation, and tokenizer commands.
The package supplies syntax support, not a language server or visual designer.

## Microsoft Edit LSH grammar

The standalone grammar is `integrations\edit-lsh\xui.lsh`.
The [language guide](../contracts/xui-language.md#microsoft-edit-syntax-support) describes its highlighting limits.
The regression suite requires Rust 1.93 or later.
Cargo downloads the LSH compiler and runtime from a pinned Microsoft Edit commit.
No native XUI build is required.

From the XUI repository root, run:

```powershell
cargo test --locked --manifest-path integrations\edit-lsh\Cargo.toml
```

The suite checks token colors, filename detection, multiline state, UTF-8 span boundaries, repository samples, and compatibility with the built-in Edit definitions.
The pinned revision is `826b4c097b6f14ba0a846dc56f2f0223a3aaf73a`.
Both dependencies in `Cargo.toml` must use the same revision.

To use the grammar in Edit, start with a separate [Edit source checkout](https://github.com/microsoft/edit).
From the XUI repository root, set `$edit` to that checkout:

```powershell
$edit = "C:\src\edit"
$sample = (Resolve-Path bindings\dotnet\DeclarativeSample\Counter.xui).Path
Copy-Item integrations\edit-lsh\xui.lsh "$edit\crates\lsh\definitions\xui.lsh"
```

In the Edit checkout, run:

```powershell
Set-Location $edit
cargo run -p lsh-bin -- assembly crates\lsh\definitions
cargo run -p lsh-bin -- render --input $sample crates\lsh\definitions
cargo build --release -p edit
```

Edit discovers the copied definition during its build.
An installed Edit binary does not load this source file at runtime.
The [Edit build documentation](https://github.com/microsoft/edit#building-from-source) lists platform requirements.

### Repository-local packages

[`dep`](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/dep/README.md) contains checked-in NuGet archives for dependencies supplied manually to this repository.
The root `NuGet.Config` adds this local feed without clearing existing machine or user feeds.
The [package inventory](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/dep/README.md#package-inventory) records versions, provenance, checksums, and license locations.
Extracted packages and restore caches stay under the ignored `build` directory.
NuGet also retains its normal cache behavior for ordinary managed project restores.

To add or update a manually supplied package:

1. Confirm that its license permits redistribution.
2. Put the versioned `.nupkg` archive in `dep`.
3. Record its source, version, SHA-256, and license location in `dep/README.md`.
4. Pin each consuming project to the intended version.
5. Update native package paths if the build consumes the archive directly.
6. Run the affected build and runtime checks before committing the archive and configuration together.

Do not put credentials, private feed tokens, extracted files, or generated packages in `dep`.
Do not replace the contents of an existing versioned archive. Use a new package version.

### LSH highlighting in XUI applications

The gallery, Designer, and FileExplorer use LSH when the native XUI build enables it.
The default Windows native build enables the checked-in `dep\Lsh.0.3.0.nupkg` for x64 or ARM64.
CMake extracts the archive into a content-addressed directory under the native build directory.
This native path needs neither a NuGet download nor the .NET SDK.
Archive changes trigger CMake configuration again.
This package supplies custom-grammar compilation through its native C API.
The samples do not need the package's managed wrapper.

For a local Designer build with required syntax highlighting, use the build script:

```powershell
.\scripts\Build-Designer.ps1
```

The script restores from `dep` by default.
For another local feed containing `Lsh.0.3.0.nupkg`, use `-LshPackageFeed <directory>`.
For an existing extracted package, use `-LshPackageDirectory <package-directory>` instead.
The script selects the host architecture, builds native XUI and Designer, and checks the deployed DLLs and license.
Use `-Architecture x64` or `-Architecture ARM64` to select another target.
Use `-BuildDirectory <directory>` for a separate native build.
If Designer is open, use `-OutputDirectory <new-directory>` to keep its running files unchanged.
If CMake is absent from `PATH`, use `-CMakePath <path-to-cmake.exe>`.
The script requires LSH and stops on restore, configuration, build, or deployment errors.
It does not download or install Microsoft Edit.
An explicit native opt-out still supports plain text without LSH.

The ordinary CMake build also enables the bundled package:

```powershell
cmake -S . -B $build -DXUI_ENABLE_LSH=ON -DXUI_REQUIRE_LSH=ON
cmake --build $build --config Release --target xui xui_gallery xui_winui_gallery --parallel 4
dotnet build bindings\dotnet\Designer -c Release -r $rid
dotnet build bindings\dotnet\FileExplorer -c Release -r $rid
```

Use the `$build` and `$rid` values from [Build the native code](#build-the-native-code).
The default managed sample paths use `build\<architecture>\Release`.
For another build directory, pass `-p:XuiNativeDir=<native-output-directory>` to each managed command.
To disable LSH intentionally, set `XUI_ENABLE_LSH=OFF` and `XUI_REQUIRE_LSH=OFF`.
`XUI_REQUIRE_LSH=ON` rejects an explicit opt-out instead of silently producing plain text.
`XUI_LSH_PACKAGE_DIR` can override the archive with an existing extracted `Lsh 0.3.0` package.
An empty override selects the checked-in archive. It no longer disables highlighting.
A missing archive or invalid enabled-package path stops configuration.
The release build also requires LSH and includes its runtime and license in the sample archives.

CMake embeds the trusted XUI, C, C++, C#, and Rust grammars at build time.
It copies the matching `lsh_lib.dll` and `LSH-LICENSE.txt` beside the native binaries.
Managed sample builds and publishes copy those files with `xui.dll`.
Keep all three files together when deploying an LSH-enabled managed sample.
For a statically linked C++ application, keep the LSH DLL and license beside the executable.
An unknown file extension uses plain text.
Missing DLLs, incompatible APIs, grammar errors, and highlighting failures report errors.
No sample loads a grammar from the file being previewed.

Run the focused checks with LSH enabled:

```powershell
cmake --build $build --config Release --target xui_syntax_highlighting_tests xui_document_syntax_tests xui_document_syntax_window_tests xui_document_editing_window_tests xui_document_editing_abi_tests --parallel 4
ctest --test-dir $build -C Release -R '^xui_(syntax_highlighting|document_syntax|document_syntax_window|document_editing_window|document_editing_abi)_tests$' --output-on-failure -j 1
dotnet run --project bindings\dotnet\Syntax.Tests -c Release -r $rid
```

The native syntax test also supports an LSH-disabled build.
The managed syntax fixture requires LSH.
Native window checks need an interactive Windows desktop.
The document syntax window fixture also checks the optional line-number gutter: owned-window pixels, scrolling, wrapped and empty lines, DPI, themes, and retained native undo.
Its live checks cover buffered painting, suppressed background erase, synchronous newline numbering and digit-boundary growth, native caret/focus, and GDI resource retention.
The 999-line highlighted fixture requires 80 synchronous scroll frames and 20 newline frames with syntax refreshes to finish within two seconds per batch.
Run `& "$build\Release\xui_document_syntax_window_tests.exe" --caret` for just the hosted caret pixel regression.
It places RichEdit inside a scrolling viewport and checks parent-only repaints and subsequent keyboard/mouse caret movement at line ends, empty lines, and whitespace-only lines.
The owned-window captures cover both visual styles, three themes, visible/hidden native carets, and gutters on/off; the full document fixture includes these checks too.

For the native document scrollbar regression, enable the desktop tests:

```powershell
cmake -S . -B $build -DXUI_DESKTOP_TESTS=ON
cmake --build $build --config Release --target xui_document_syntax_window_tests --parallel 4
ctest --test-dir $build -C Release -R '^xui_document_(syntax|theme)_window_tests$' --output-on-failure -j 1
```

The theme check captures only its own window.
It checks actual dark scrollbar pixels, light/high-contrast palette transitions, native scrolling, selection, undo, and redo.
It does not change the Windows high-contrast setting.
Run desktop suites sequentially.

## Documentation and changes

### Retype preview and GitHub Pages

The handbook uses [Retype](https://retype.com/guides/getting-started/) for local preview and static HTML.
The Markdown also remains compatible with GitBook.
The documentation tools require Node.js 22 and Python 3.10 or later.
They do not require the native XUI build.

From the repository root, install the pinned documentation dependency:

```powershell
npm ci
```

On Windows ARM64, use this command instead:

```powershell
npm ci --cpu=x64
```

Retype 4.6.0 has no native Windows ARM64 package.
The helper runs its x64 executable through Windows 11 emulation.
Other platforms use the matching Retype package.

Start the local preview:

```powershell
npm run docs:dev
```

The server listens only on `127.0.0.1:5000` and opens the browser.
The helper watches the source pages and updates the generated input.
Retype refreshes the site after each change.
Edit the original Markdown, not the generated files under `build`.
Press Ctrl+C to stop the preview.

To select another port without opening a browser, run:

```powershell
npm run docs:dev -- --port 5001 --no-open
```

Run the source checks and create the static site:

```powershell
npm run docs:check
npm run docs:build
```

The build writes `build\retype-site`.
It checks rendered page coverage, sidebar order, local links, anchors, assets, and the `/xui/` URL prefix.
It also compares every rendered code block with its Markdown source.
Control examples must use the tab order `.xui`, `C#`, `Rust`, `C++`.
The source check rejects missing languages, malformed groups, and C++ examples outside their language tab.
Unexpected output files stop the build before artifact upload.
It does not publish the output.
The build uses Retype's public [GitHub Pages community key](https://retype.com/community/).
This key permits Pro features on the default `github.io` domain.
It is a public license key, not a repository credential.
An explicit `RETYPE_KEY` environment variable takes precedence.
A custom domain requires a separate license review.

#### Content and navigation

`docs/specs/SUMMARY.md` remains the single page list and ordering source.
`tools/docs_site.py` creates Retype input under `build\retype-input`.
It converts summary sections into folders and adds navigation metadata to generated copies.
The book contents page remains accessible but does not appear in the sidebar.
`retype.yml` defines the site URL, output, and branding.

Only pages in the summary, plus the contents page itself, enter the site.
The helper does not copy maintainer notes, application sources, native binaries, or sample build output.
Links to other repository files point to GitHub at the source checkout's exact commit.
These source links still require repository access while the repository is private.
Fenced examples remain unchanged.
Template processing is disabled so C++ initializer braces remain literal text.
The adapter tests are in `tests/test_docs_site.py`.
Page frontmatter requires an explicit adapter update rather than a silent metadata override.

Control guides use GitBook tab directives in their Markdown source:

````markdown
{% tabs %}
{% tab title=".xui" %}
Declarative example and any required C# construction.
{% endtab %}
{% tab title="C#" %}
Handwritten C# example.
{% endtab %}
{% tab title="Rust" %}
Rust example.
{% endtab %}
{% tab title="C++" %}
C++ example.
{% endtab %}
{% endtabs %}
````

The helper converts these directives to Retype tabs in generated input.
It leaves fenced code unchanged.
GitBook retains its native tab syntax, and both renderers show `.xui` first.
Put shared behavior notes outside the group.
For an unbound API, state the limitation in its tab instead of inventing a call.
For a bound control without a markup constructor, show C# creation and a `.xui` `Content(...)` component.

#### Enable public deployment

**The repository is private. GitHub Pages publication makes the selected handbook pages and their code examples public.**
The workflow does not publish until an administrator explicitly enables deployment.
A private repository also requires a GitHub plan that supports Pages.

After approval for public publication:

1. Merge the documentation branch into `main`.
2. Open the repository's **Settings > Pages**.
3. Select **GitHub Actions** as the build and deployment source.
4. Review the `github-pages` environment and restrict deployment to `main`.
5. Create the Actions repository variable `XUI_PAGES_PUBLIC` with the value `true`.
6. Run the **Documentation** workflow on `main`.

The site URL is `https://zadjii-msft.github.io/xui/`.
Later pushes to `main` build and deploy the site automatically.
Pull requests build the site but never deploy it.
The workflow uploads only `build\retype-site`, not the repository.
The build job has read-only repository access.
Only the deployment job receives Pages and identity-token permissions.
The workflow uses commit-pinned actions and a locked Retype version.

To stop future deployments, remove the `XUI_PAGES_PUBLIC` variable.
This action does not remove an already published site.
To remove the public site, unpublish it in **Settings > Pages**.

### GitBook documentation

The [XUI handbook](../index.md) is the GitBook entry point.
`.gitbook.yaml` uses the repository root as its content root.
It selects `docs/specs/README.md` and `docs/specs/SUMMARY.md` as the first page and navigation file.
The wider content root keeps links to contributor procedures and sample sources within the repository.
The summary selects the public pages; maintainer notes are not sidebar chapters.

To host the book, connect this repository and the desired branch through GitBook Git Sync.
Keep the configuration and Markdown in Git.
GitBook hosting is separate from the Retype workflow.
The configuration follows GitBook's [content configuration reference](https://gitbook.com/docs/docs-as-code/git-sync/content-configuration).
Do not install the obsolete `gitbook-cli` package to process these Git Sync files.

When adding a public page, link it from its section index and `docs/specs/SUMMARY.md`.
Each page can appear only once in the summary.
Use relative Markdown links for repository pages.
Keep control coverage tied to current public headers and binding factories, not the names of style-target enum members.
Some enum members describe unsupported facade targets; a style schema does not imply a markup constructor.

Run the dependency-free documentation check from the repository root:

```powershell
python tests\check-docs.py
```

It checks navigation uniqueness, local links and heading anchors, section coverage, and control-catalog names against current source.
It does not publish the site or verify external URLs.
Compile the tutorial sample separately after changing its examples.

### GitBook tutorial sample

The [tutorials](../learn/tutorials/index.md) include a complete task-card application.
After the native build, use the same `$build` and `$rid` values from the earlier procedures:

```powershell
dotnet run --project docs\specs\tutorials\sample\TaskCard.csproj -r $rid
```

For development reload:

```powershell
dotnet watch --project docs\specs\tutorials\sample\TaskCard.csproj --non-interactive "-p:RuntimeIdentifier=$rid"
```

For a compile-only check, no native DLL is needed:

```powershell
dotnet build docs\specs\tutorials\sample\TaskCard.csproj -c Release -r $rid -p:XuiCopyNativeRuntime=false
dotnet build docs\specs\tutorials\sample\TaskCard.csproj -c Debug -r $rid -p:XuiCopyNativeRuntime=false
```

For NativeAOT, use the same project path in the [publish procedure](#nativeaot-and-deployment).
Build and publish copy this checkout's `xui.dll` into the output directory automatically.
The tutorial sample does not ship in the release sample ZIPs.
The sample stores task state only in memory.
Do not describe Apply as persistent storage or reload replacement as state preservation.

### Zoey brand assets

The [Zoey brand kit](zoey.md) contains the canonical mascot and six status palettes.
Normal native and managed builds use the checked-in assets and do not need an SVG renderer.
Asset regeneration requires Node.js 22 or later and npm.
The pinned renderer works on Windows, Linux, and macOS without a browser or system fonts.

Install the repository dependencies:

```powershell
npm ci
```

Edit `assets\branding\zoey.svg`, then regenerate the assets:

```powershell
npm run branding:generate
npm run branding:check
npm run branding:test
```

To promote an edited copy instead, supply its path:

```powershell
npm run branding:generate -- --source path\to\updated-zoey.svg
```

The script validates the SVG before it writes assets.
It replaces the canonical source, regenerates all palette exports, and updates the VS Code package icon.
The generator uses only the canonical SVG and palette configuration as artwork inputs.
Unchanged output files keep their timestamps.
The check command reports missing or stale assets without writing files.

The editable source must retain its named layers and six solid-color mane paths.
These include `segments`, `segment-1` through `segment-6`, `face`, `face-border`, `border-colors`, and `border-segment-1` through `border-segment-6`.
It also retains `mane`, `mane-backing`, `outer-mane-border`, `border-backing`, `title`, and `desc`.
Internal mask and clip references must remain valid.
External images, fonts, scripts, CSS, and file references are not supported.
The square viewBox controls the export size; path edits can change the artwork within it.

Edit `assets\branding\palettes.json` to change palette names, status labels, or single-hue colors.
If a canonical face color changes, update its `sourceFace` entry too.
The canonical rainbow palette comes from the source SVG.
Each status version uses a single mane hue, coordinated face tones, and a darker outer border.

Outputs live in `assets\branding\generated`.
They include seven SVGs, seven multi-resolution ICOs, fourteen PNG sizes per palette, a web manifest, and a palette preview.
`manifest.json` records file hashes and the pinned renderer version.
The generated `integrations\vscode-xui\images\zoey.png` is the same as the canonical 256-pixel PNG.
Do not edit generated files by hand.
If a palette is removed, delete only its obsolete generated exports before regeneration.

Open `assets\branding\generated\index.html` to inspect every palette on light and dark artboards.
After regeneration, rebuild the applications to refresh their embedded icons.
Run `npm run docs:build` to refresh the staged documentation assets.
Commit the canonical SVG, palette configuration, and generated assets together.

Native samples embed Zoey through `demo\zoey.rc` and load their window icons from their own executables.
They do not need a separate icon file at runtime.
The shared `demo\xui.rc` remains manifest-only.
Managed sample apphosts embed Zoey and copy `zoey.ico` into build and publish outputs.
Keep this file beside the managed executable when you distribute the application.
File Explorer retains its folder and file icons at runtime.
The NuGet package icon does not change icons in consumer applications.

### Document scope

Keep each document focused on its reader:

- `README.md`: A brief introduction, small examples, and links for application authors.
- `CONTRIBUTING.md`: Build requirements, commands, tests, and contribution procedures.
- `docs/specs`: Public API contracts, language guides, sample behavior, and human-facing design proposals.
- `docs/llm`: Source maps, implementation plans, handoffs, historical results, and unresolved investigations.

When behavior changes, update the relevant public reference.
Add maintainer evidence separately, with its date, scope, and limitations.
Do not append test transcripts or implementation diaries to the README.
Preserve native editing, accessibility, ownership, and cancellation contracts in code changes.
The [maintainer index](https://github.com/zadjii-msft/xui/blob/9e6673cffbb2f4fb320da652937729f1b7a03099/docs/llm/README.md) identifies the relevant source maps and previous investigations.
