@@ -94,6 +94,34 @@ flowchart LR
9494 F --> G["WebView window (OS)"]
9595```
9696
97+ ## Launch Policy (Deterministic)
98+
99+ ` AppOptions ` now uses a single deterministic policy object:
100+
101+ ``` zig
102+ pub const LaunchPolicy = struct {
103+ preferred_transport: enum { native_webview, browser } = .native_webview,
104+ fallback_transport: enum { none, browser } = .browser,
105+ browser_open_mode: enum { never, on_browser_transport, always } = .on_browser_transport,
106+ allow_dual_surface: bool = false,
107+ app_mode_required: bool = false,
108+ };
109+ ```
110+
111+ Decision summary:
112+
113+ | ` preferred_transport ` | Native backend available | ` fallback_transport ` | Active transport |
114+ | ---| ---| ---| ---|
115+ | ` native_webview ` | yes | any | ` native_webview ` |
116+ | ` native_webview ` | no | ` browser ` | ` browser_fallback ` |
117+ | ` native_webview ` | no | ` none ` | ` native_webview ` (error if render required) |
118+ | ` browser ` | any | any | ` browser_fallback ` |
119+
120+ Browser opening summary:
121+ - ` never ` : never auto-launch browser.
122+ - ` on_browser_transport ` : launch browser only when active transport resolves to browser.
123+ - ` always ` : always launch browser; combine with ` allow_dual_surface=true ` for explicit dual-surface behavior.
124+
97125## API At A Glance
98126
99127Core flow:
@@ -118,9 +146,11 @@ pub fn main() !void {
118146
119147 var service = try webui.Service.init(gpa.allocator(), rpc_methods, .{
120148 .app = .{
121- .transport_mode = .native_webview,
122- .browser_fallback_on_native_failure = true,
123- .auto_open_browser = true,
149+ .launch_policy = .{
150+ .preferred_transport = .native_webview,
151+ .fallback_transport = .browser,
152+ .browser_open_mode = .on_browser_transport,
153+ },
124154 },
125155 .window = .{ .title = "WebUI Zig" },
126156 .rpc = .{ .dispatcher_mode = .threaded },
@@ -167,6 +197,24 @@ Dispatch modes:
167197- ` threaded ` (worker queue)
168198- ` custom ` (hook dispatcher)
169199
200+ Async jobs (push-first):
201+ - Set ` RpcOptions.execution_mode = .queued_async ` .
202+ - ` POST <rpc_route> ` returns ` { job_id, state, poll_min_ms, poll_max_ms } ` .
203+ - Completion is pushed over WebSocket as ` rpc_job_update ` .
204+ - JS bridge waits for push first, then uses bounded polling fallback (` GET /rpc/job?id=... ` ).
205+ - Cancel route: ` POST /rpc/job/cancel ` with ` { "job_id": <id> } ` .
206+
207+ Typed APIs:
208+ - ` Window.rpcPollJob(allocator, job_id) !RpcJobStatus `
209+ - ` Window.rpcCancelJob(job_id) !bool `
210+ - ` Service ` mirrors both methods.
211+
212+ Runtime introspection and diagnostics:
213+ - ` Window.runtimeRenderState() ` / ` Service.runtimeRenderState() `
214+ - ` Window.probeCapabilities() ` / ` Service.probeCapabilities() `
215+ - ` Service.listRuntimeRequirements(allocator) `
216+ - ` App.onDiagnostic(...) ` / ` Service.onDiagnostic(...) `
217+
170218## Close Semantics (No Random Window Closes)
171219
172220Close is backend-authoritative:
@@ -197,6 +245,24 @@ Build outputs:
197245- ` zig-out/share/webui/runtime_helpers.embed.js `
198246- ` zig-out/share/webui/runtime_helpers.written.js `
199247
248+ ## Linux Runtime Requirements API
249+
250+ You can query runtime packaging requirements before showing a window:
251+
252+ ``` zig
253+ const reqs = try service.listRuntimeRequirements(allocator);
254+ defer allocator.free(reqs);
255+ for (reqs) |req| {
256+ std.debug.print("{s}: required={any} available={any}\n", .{
257+ req.name, req.required, req.available,
258+ });
259+ }
260+ ```
261+
262+ On Linux this reports helper/runtime expectations such as:
263+ - ` webui_linux_webview_host `
264+ - ` webui_linux_browser_host `
265+
200266## Build Flags
201267
202268| Flag | Default | What it does |
@@ -220,6 +286,7 @@ Exported compile-time values:
220286
221287- ` zig build ` (install)
222288- ` zig build test `
289+ - ` zig build dispatcher-stress `
223290- ` zig build examples `
224291- ` zig build run `
225292- ` zig build bridge `
@@ -289,6 +356,6 @@ Manual GUI validation checklist: `docs/manual_gui_checklist.md`.
289356
290357## Docs
291358
292- - ` MIGRATION .md`
359+ - ` docs/migration .md`
293360- ` CHANGELOG.md `
294361- ` docs/upstream_file_parity.md `
0 commit comments