Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3d50ae0
chore(deps): move the frontend to @pathscale/ui 2.11.9 and Solid 2.0.…
Aug 31, 2026
6c7cdbd
docs(theme): drop the stale daisyUI reference from the layer comment
Aug 31, 2026
d55e84c
chore(deps): take @pathscale/ui 2.11.10
Aug 31, 2026
34fce86
fix(capture): honour the capture viewport environment variables
Aug 31, 2026
5f3ea4f
fix(capture): fetch the scripts a page discovers while running
Aug 31, 2026
12ca80d
fix(browser): fetch runtime-discovered scripts in the window too
Aug 31, 2026
de70a25
feat(net): give the page a working fetch and XMLHttpRequest
Aug 31, 2026
f6e8cf7
feat(shim): give the page the web APIs the corpus found missing
Aug 31, 2026
48fd0fa
feat(net): let fetch and XMLHttpRequest honour an abort
Aug 31, 2026
b4a4b49
feat(shim): DOMException, window identity, and the load-time scroll p…
Aug 31, 2026
811d536
feat(shim): atob and btoa, which measurement found and the corpus had…
Aug 31, 2026
1b46f4f
feat(inspect): reach the diagnostics tool, not just agent control
Aug 31, 2026
37b113d
build: take the engine at 0.4 and tauri-runtime-blitz at 0.3.2
Aug 31, 2026
1fb429a
build: take endpoint-libs 3, the version the control surface now speaks
Aug 31, 2026
24ac618
build: take ps-dioxus-native 0.7.3, the version built against the 0.4…
Aug 31, 2026
86106f1
test(corpus): keep the corpus tooling in the repo
Sep 1, 2026
5d49dbe
feat(net): let Chuzz say who it is, and record what that buys
Sep 1, 2026
c92688d
docs: re-verify the four 2026-08-12 findings; all four are fixed
Sep 1, 2026
b23227e
fix(shims): report a viewport, a location origin, and real media queries
Sep 1, 2026
5c11662
chore: stop tracking compiled Python bytecode
Sep 1, 2026
fa3f973
chore: remove the Python corpus tooling
Sep 1, 2026
263c6a1
refactor(app): make the browser a library, so a second binary can be it
Sep 8, 2026
a917f5f
feat(headless): give a built page an origin, so a directory can be a …
Sep 8, 2026
e49e7fd
feat(headless): serve one page over the inspection socket, with no wi…
Sep 8, 2026
a560849
feat(headless): follow a link, so a route can be reached
Sep 8, 2026
7518be2
feat(headless): carry storage across a navigation
Sep 8, 2026
e447b5b
ci: an action that gives a site a headless browser to be checked in
Sep 8, 2026
f998604
feat(shim): a Blob, and an object URL that can be loaded
Sep 8, 2026
2f217e9
fix(serve): serve a compressed bundle as what it decompresses to
Sep 8, 2026
ac56c1b
fix(net): resolve a page's relative fetch against the page
Sep 8, 2026
5100d59
fix(serve): let the page run while nothing is being asked of it
Sep 8, 2026
1aa0ef5
fix(serve): serve a built page from its directory
Sep 8, 2026
079135e
ci(host): require a driver that reads QA_TIMEOUT_SCALE
Sep 8, 2026
9687f1d
style(serve): collapse the condition that picks out a built page
Sep 8, 2026
345064f
fix(serve): type a built stylesheet as CSS whatever the build named it
Sep 8, 2026
9876aeb
feat(net): a WebSocket that opens a connection
Sep 8, 2026
7c66719
feat(headless): let the page run for the time a request consumed
Sep 8, 2026
872154d
feat(ui): take @pathscale/ui 4.0.0
Sep 7, 2026
0028df4
fix(deps): pin @pathscale/ui to ^3.1.0
Sep 7, 2026
bfa3ceb
build(frontend): resolve the lockfile, and match the layouts compiler…
Sep 7, 2026
b9647e4
fix(tabs): let the tab list shrink when a tab closes
Sep 7, 2026
c694572
feat(headless): give the page a clipboard
Sep 8, 2026
1a2c911
feat(headless): a window to open, a query to build, and a route to st…
Sep 8, 2026
0a4d199
Use current Homebrew cask lifecycle steps
Sep 5, 2026
0cb484e
release: 0.1.35
Sep 9, 2026
c803fae
build: stop committing lockfiles
Sep 9, 2026
df35f9e
build: pin @solidjs/signals to the release solid-js was cut against
Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/actions/headless-host/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Headless browser host
description: >
Build chuzz-headless and install ps-qa, so a site's built output can be driven
through a real browser engine with no window.

inputs:
chuzz-ref:
description: The chuzz revision to build the host from.
default: master
token:
description: >
A token that can read pathscale/chuzz. Required, because the host is built
from source rather than installed from a registry.
required: true
ps-qa-version:
description: >
The driver's version requirement. A floor rather than "latest": a check
file can use a field an older driver does not know, and the failure then
reads as a broken workflow rather than a driver that is too old.

0.6.3 is the floor because it is the first that reads `QA_TIMEOUT_SCALE`
from the environment. Every site workflow sets it, so an older driver
silently runs a shared runner against the strict local latency contract.
default: "^0.6.3"

outputs:
host:
description: Path to the built chuzz-headless binary.
value: ${{ steps.build.outputs.host }}

runs:
using: composite
steps:
- name: Check out chuzz
uses: actions/checkout@v4
with:
repository: pathscale/chuzz
ref: ${{ inputs.chuzz-ref }}
path: .qa-host
token: ${{ inputs.token }}

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
with:
workspaces: .qa-host
# A failing check must not make the corrective run rebuild a browser
# engine from zero.
cache-on-failure: true

# The driver links no renderer, so it installs from the registry. The host
# is built here because it is the browser, and the browser is not a crate a
# site can install.
- name: Install ps-qa
shell: bash
env:
CARGO_TARGET_DIR: .qa-host/target/qa-tools
run: cargo install ps-qa --version "${{ inputs.ps-qa-version }}"

- name: Build the host
id: build
shell: bash
run: |
cargo build --release --manifest-path .qa-host/Cargo.toml --bin chuzz-headless
echo "host=$PWD/.qa-host/target/release/chuzz-headless" >> "$GITHUB_OUTPUT"
21 changes: 5 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,6 @@ jobs:
- name: Check formatting
run: cargo fmt --all -- --check

# Reads Cargo.lock only, so it needs neither a toolchain nor a network. This
# is the check that would have caught the engine cascade being repinned
# halfway; see the script's own header for why that failure reads as a broken
# engine rather than as two of them.
one-rev:
runs-on: ubicloud-standard-2
steps:
- uses: actions/checkout@v4

- name: One rev per git source
run: scripts/check-one-rev-per-git-source.sh

# The portable half of the workspace, linted and tested for real.
control:
runs-on: ubicloud-standard-4
Expand Down Expand Up @@ -91,8 +79,9 @@ jobs:
# only because `solid-layouts-oxc` is a direct devDependency. Bun links the
# bins of direct dependencies into the root `.bin` and leaves a transitive one
# under its own dependent, which is how the release job failed for fourteen
# releases while `bun install` reported success. `--frozen-lockfile` so a PR
# cannot quietly resolve a different tree from the committed bun.lock.
# releases while `bun install` reported success. There is no bun.lock to be
# frozen against: this repository commits no lockfiles, so every job resolves
# the ranges in package.json the way a fresh checkout does.
frontend:
runs-on: ubicloud-standard-4
defaults:
Expand All @@ -107,7 +96,7 @@ jobs:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile
run: bun install

# Proves the binary the release job needs is actually on PATH, and names
# it plainly if it is not. Cheap, and it turns the one failure that has
Expand Down Expand Up @@ -152,7 +141,7 @@ jobs:
# dependencies have to be present before cargo starts.
- name: Install frontend dependencies
working-directory: apps/chuzz/frontend
run: bun install --frozen-lockfile
run: bun install

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
Expand Down
18 changes: 8 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ jobs:
# day a new engine package was added, because a path dependency resolves
# against whatever is on disk and no local build could notice.
#
# `Cargo.toml` now pins ps-blitz, tauri-runtime-blitz and endpoint-libs by
# revision, so cargo fetches them and `Cargo.lock` records them. An
# ordinary `cargo build` on any machine resolves exactly what this job
# does. See scripts/local-engine.sh for building against a working
# checkout, which is opt-in so the default keeps testing these pins.
# `Cargo.toml` now takes ps-blitz, tauri-runtime-blitz and endpoint-libs
# from crates.io on a caret, and no lockfile is committed, so this job
# resolves the newest published versions that satisfy the ranges. An
# ordinary `cargo build` on any machine resolves the same thing. See
# scripts/local-engine.sh for building against a working checkout, which
# is opt-in so the default keeps testing what is actually released.

# For `bunx @tauri-apps/cli signer sign` below. The runner has no bun
# preinstalled, and without this the release builds, bundles and packs
Expand Down Expand Up @@ -148,12 +149,9 @@ jobs:
# for fourteen releases. It worked on a developer machine because an older
# install had hoisted it there by luck, which is also why the local tree
# was compiling with 0.1.5 while the lockfile said 0.1.6.
#
# `--frozen-lockfile` so a release cannot quietly resolve a different tree
# from the committed bun.lock.
- name: Install frontend dependencies
- name: Install frontend dependencies
working-directory: apps/chuzz/frontend
run: bun install --frozen-lockfile
run: bun install

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
Expand Down
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,16 @@ apps/chuzz/gen/
# Engine redirect for local builds. Untracked on purpose: it names paths that
# exist on one machine. See scripts/local-engine.sh.
.cargo/local-engine.toml

# Python bytecode from scripts/corpus/
__pycache__/
*.pyc

# Lockfiles are not committed here. Every dependency is a caret range on a
# published version, so a build resolves the newest thing that satisfies it and
# a broken upstream release fails the build that introduced it. A committed lock
# turns that into a pin nobody chose: it kept the workspace on ps-blitz 0.4.4
# and tauri-runtime-blitz 0.3.6 for as long as those satisfied the caret, so
# fixes that had already shipped were invisible to every build and to CI.
Cargo.lock
bun.lock
24 changes: 19 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
- Control is opt-in, local-only, and unauthenticated only because the socket and descriptor are owner-readable. Never bind it to a network interface.
- **Every dependency is a published version with a caret, not a sibling
checkout.** `ps-blitz`, the renderers and `endpoint-libs` are ordinary
crates.io dependencies on `^`, so `cargo update` can move them, `Cargo.lock`
records exactly what a release builds, and two crates asking for the same
range share one copy instead of getting a second. Do not turn them back into
crates.io dependencies on `^`, so a build resolves the newest published
version that satisfies the range, and two crates asking for the same range
share one copy instead of getting a second. Do not turn them back into
`path = "../..."`. That is what this repository did before, and it put the
revision CI used in a `BLITZ_REF` env var in release.yml while every developer
built against whatever happened to be on disk. The pin sat 44 commits behind,
Expand All @@ -27,12 +27,26 @@
`endpoint-libs` alongside the registry copy is precisely how this repository
ended up with two of it. There are no exceptions left: `tauri-runtime-blitz`
was the last git dependency, and it is `^0.1.0` from crates.io like the rest.
- **No lockfiles are committed. Not `Cargo.lock`, not `bun.lock`.** They were,
and a lockfile is the one thing that can hold a caret dependency still: any
version already recorded satisfies `^`, so cargo never reconsiders it. This
workspace sat on `ps-blitz` 0.4.4 and `tauri-runtime-blitz` 0.3.6 that way
while 0.4.5 and 0.3.7 were published, carrying fixes chuzz needed, and neither
a local build nor CI could see it. A stale-but-valid pin is the dangerous
kind; a stale-and-invalid one repairs itself, which is why the boa dependency
moved on its own and these did not. Without a lock, every build resolves the
newest published version in range, and a bad upstream release fails the build
that picked it up rather than waiting for whoever runs `cargo update`. Do not
add one back, and do not reach for `--locked`, `--frozen` or
`--frozen-lockfile` in a workflow: they only mean anything against a committed
lock. If a specific version is genuinely required, say so in the range.
- **Building against a working checkout is opt-in and never edits a tracked
file.** Put the `[patch]` tables in `.cargo/local-engine.toml`, which is
gitignored, and reach for them per command:
`scripts/local-engine.sh check -p chuzz-gui`. The wrapper snapshots and
restores `Cargo.lock`, because a redirected build rewrites it to point at
directories that exist on one machine. Patch only the crates you are actually
restores any `Cargo.lock` a redirected build leaves behind, because that one
points at directories that exist on one machine and the next plain `cargo
build` would silently reuse it. Patch only the crates you are actually
changing; every entry is a pin that stops being tested.
- When you move the engine version, move `tauri-runtime-blitz`'s to match. Both
resolve a ps-blitz, and two different ones put two engines in the graph, which
Expand Down
Loading
Loading