Skip to content

feat: a headless surface that does not compile the window runtime - #51

Merged
pathscale merged 4 commits into
masterfrom
fix/headless-without-tauri
Sep 6, 2026
Merged

pathscale merged 4 commits into
masterfrom
fix/headless-without-tauri

Conversation

@pathscale

Copy link
Copy Markdown
Owner

qa-inspect-host opens no window. It serves a socket, answers Inspect, and activates nodes: nine functions from this crate, none of which touch one.

Those functions sat in runtime.rs beside the Tauri Runtime impl, so depending on them meant compiling Tauri, and on Linux that means GTK.

What that cost

A headless QA host needed GTK development headers to build a binary that never creates a window. Worse, on Linux it could not be built at all, because this crate does not compile there:

callback(RawWindow { _marker: &marker });
         ^^^^^^^^^ missing `default_vbox` and `gtk_window`

RawWindow is a gtk::ApplicationWindow and a gtk::Box on that platform, and a Blitz window has neither. So the renderer's QA suite could only run where a window system happened to exist, which is the opposite of what headless means.

The change

The dependency edge was wrong, not the platform.

  • The inspection and activation surface moves to agent.rs.
  • tauri, tauri-runtime and tauri-utils become optional, behind a new default runtime feature.
  • Everything that needs a window sits behind that feature.

A consumer takes default-features = false, features = ["agent-control"]:

cargo tree --edges normal --no-default-features --features agent-control
0 tauri / gtk / glib / webkit crates

No code changed. Every moved item is byte-identical; what moved is which module it lives in and which feature compiles it.

Verification

  • cargo clippy --all-features --all-targets -- -D warnings: clean
  • cargo clippy --no-default-features --features agent-control -- -D warnings: clean
  • cargo test --all-features -- --test-threads=1: 37 passed, 1 ignored
  • qa-inspect-host built against this branch with no Tauri in its graph, driving pathscale/ps-blitz#86's fixture suite: 6/6 groups pass

CI

A new job builds the headless configuration and fails if the graph ever contains a window-stack crate again.

That matters here specifically: the existing Linux job never compiled anything for Linux. cargo tree resolves without building and cargo package --no-verify skips the build by definition, which is how a crate that does not build on Linux kept a green tick.

Releases 0.3.3; 0.3.2 is already published.

`qa-inspect-host` opens no window. It serves a socket, answers `Inspect`, and
activates nodes: nine functions from this crate, none of which touch one. But
those functions sat in `runtime.rs` beside the Tauri `Runtime` impl, so
depending on them meant compiling Tauri, and on Linux that means GTK.

The consequences were not small. A headless QA host needed GTK development
headers to build a binary that never creates a window, and on Linux it could not
be built at all, because this crate does not compile there: `RawWindow` is a
`gtk::ApplicationWindow` and a `gtk::Box` on that platform, and a Blitz window
has neither. So the QA suite for the renderer could only run where a window
system happened to exist, which is the opposite of what headless means.

The dependency edge was wrong, not the platform. The inspection and activation
surface moves to `agent.rs`, `tauri`, `tauri-runtime` and `tauri-utils` become
optional behind a new default `runtime` feature, and everything that needs a
window sits behind it. A consumer takes `default-features = false, features =
["agent-control"]` and gets no window stack:

    cargo tree --edges normal --no-default-features --features agent-control
    0 tauri / gtk / glib / webkit crates

No code changed. Every moved item is byte-identical; what moved is which module
it lives in and which feature compiles it.

CI gains a job for that configuration, because the point is that it keeps
working: it lints the headless build and fails if the graph ever contains a
window-stack crate again. The existing Linux job never compiled anything for
Linux -- `cargo tree` resolves without building and `cargo package --no-verify`
skips the build by definition -- which is how a crate that does not build there
kept a green tick.
meh added 3 commits September 6, 2026 21:52
Two things the local `--all-features" check could not see.

The runtime imported the capture path and the activation path under one
attribute, so a build with `agent-control` and not `diagnostics" -- the default
-- failed on three names it never uses. They are gated separately now, matching
the items. A stray `cfg` left over from a deleted import was compounding it, and
over-gating `keyboard_types` along with it.

And the headless job needs fontconfig. A renderer needs fonts wherever it runs;
that is not a window stack, and the graph check is what holds that line.
macOS runners are for building packages, not routine checks. They are the
expensive capacity and every push was spending it on work Linux does: the
protocol and headless jobs already assert everything about this crate that is
not the window runtime itself, and that only matters when a release is cut.
`workflow_dispatch` runs it deliberately.

The Linux jobs move to ubicloud, which is what everything else here uses.
Neither one needs four. `protocol` resolves a dependency graph and packages
without verifying; `headless` type-checks one crate against a feature set that
excludes the heaviest half of it.
@pathscale
pathscale merged commit e1739e6 into master Sep 6, 2026
3 checks passed
@pathscale
pathscale deleted the fix/headless-without-tauri branch September 6, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant