The test suite
bun run test runs the integration suite on the GPU test renderer. The real
app is mounted, painted and hit tested, so the tests drive the same tree the
user sees.
Two things the test renderer cannot do
- Exit animations never settle. The renderer only paints on demand, so an
AnimatePresenceexit keeps the element in the tree forever. Assert on the painted state when a row is removed. - A sliding panel has to settle before it is clicked. The automation clicks the last painted bounds, so freeze the clock, advance it, and wait until the element stops moving.
The CI
.github/workflows/ci.yml runs:
The test job is not on Linux: the native test renderer only ships with the
GPUIX builds that carry the
test-support feature, and on Linux the suites
skip themselves.
integration.yml drives source and compiled windows on Windows, checks intentional
close does not restart the packaged cockpit, and runs the browser preview smoke.
release.yml packages and smoke-tests the compiled cockpit and engine on Windows,
macOS and Linux, then extracts the actual archive and runs its binaries outside
the checkout. The engine suite also tests incomplete, corrupt and inconsistent
release artifacts against the publication gate. Tag builds publish signed release
provenance and delta manifests only after all platforms pass. The aggregate
verify complete release job downloads all three platforms and delta chunks and
checks the actual publication inputs on every PR, without publishing a release.
The install is bun install --frozen-lockfile, so the lockfile and
package.json cannot drift apart. .bun-version pins Bun for the local
runtime and for CI.
Driving the app
@gpuix/react/automation gives a Playwright shaped API over the GPU
renderer. It drives the real input pipeline, not a DOM.
GPUIX_BACKGROUND=1 opens the window without taking the keyboard. Use it
whenever you drive the app yourself.
screenshot.ts uses an isolated HIROSHI_HOME and temporary workspace, captures
the current controls, closes its window and stops its daemon in cleanup. It needs
a desktop session and GPU. Windows hosted runners support real window tests;
macOS hosted runners do not provide a desktop session.
Browser preview
bun run web:dev serves the preview at http://127.0.0.1:4173 (override PORT).
bun run web:build only checks the bundle. web-entry.tsx mounts the published
GPUIX Wasm renderer with demo conversations and no engine. The native window
dragging and geometry adapters are replaced with no-ops; OS window controls are
hidden. Workspace operations and model calls need the desktop engine.
The preview has been verified in headless Chrome with software WebGPU on Windows.
bun run test:web waits for the rendered canvas keyboard target, sends a demo
prompt through GPUIX automation, asserts the reply and captures
screenshots/browser-preview.png. It creates its own Chrome profile and removes
it afterward. Set HIROSHI_CHROME for a Chrome/Chromium executable elsewhere;
the default is the standard Windows Chrome install path. Hosting elsewhere must
preserve the server’s COOP/COEP headers for Wasm shared memory.
Resource limits on Windows
Run builds and automated tests sequentially throughscripts/run-guarded.ps1:
The rules that matter
The repository carries its own rules, inAGENTS.md and in the
hiroshi-gpuix skill. The ones that bite most often:
- A drag region needs
pointerEvents: 'auto'and the three mouse handlers. - An unfilled
divhas no hitbox, so an empty region is dead. - There is no
zIndex; the tree order is the stacking order. - A
<text>with several children wraps. Use one template literal. - Never use Unicode symbols for icons; they resolve to Windows emojis. Use
the SVG set in
assets/icons/.