v0.2.192
What's New
Geisterhand: in-process input fuzzer for Perry UI
New --enable-geisterhand flag embeds an HTTP server (default port 7676) for programmatic widget interaction and automated UI testing. The perry-ui-geisterhand crate provides endpoints for clicking, typing, sliding, toggling, hovering, double-clicking, and taking screenshots across all 5 native platforms. Chaos mode randomizes interactions for fuzz testing. Configurable port via --geisterhand-port <PORT>.
- Screenshot capture on all 5 native platforms (macOS CGWindowListCreateImage, iOS UIGraphicsImageRenderer, Android JNI, GTK4 GskRenderer, Windows PrintWindow+inline PNG encoder)
- Auto-build:
--enable-geisterhandautomatically compiles required libs when missing - HTTP endpoints:
/widgets,/click/:h,/type/:h,/slide/:h,/toggle/:h,/state/:h,/hover/:h,/doubleclick/:h,/screenshot,/chaos/start|stop|status
WASM target: full perry/ui support
The --target wasm output now supports the complete perry/ui widget set via DOM-based JS runtime. 170+ UI functions ported including widget creation, reactive State system, styling, events, canvas drawing, menus, toolbars, sheets, dialogs, keyboard shortcuts, navigation stacks, and windows. Firefox NaN canonicalization fixed via memory-based calling convention for all 150+ bridge functions.
Documentation
New pages for WebAssembly platform, perry-styling/theming, perry run command, --minify flag, gc() built-in, and Geisterhand testing guide (all 5 platforms documented).
Bug fixes
- Detached method this-unbinding:
CAPTURES_THIS_FLAGprevents incorrectthisin detached method calls - Object literal method this-binding: via closure capture
- Comparison operators: reverted to 1.0/0.0 (NaN-boxed booleans broke arithmetic)
- String() coercion: now handles BigInt values
- CLASS_CAPTURE: skips class-internal parameter LocalIds
- Closure default params: simplified check to TAG_UNDEFINED only
- Regex .test(): works on
Named(RegExp)variables; inlineMath.PI/E/LN2constants - TsParamProp: TypeScript parameter properties now compile correctly
- NaN-boxing fixes: proper tags for closure args, array method returns,
LocalSetfor closures in Any-typed locals,IndexSetstring-key path, dynamic closure calls on object properties - Rest params in closures: args correctly packed into array
- Nullish coalescing (
??): no longer treats strings/pointers as nullish - Shared SHAPE_CACHE corruption: fixed key collision in object field init
- Number() hex string parsing: now parses
0xprefixed strings correctly - Native library stubs: don't generate stubs for native library FFI functions
- Mutable capture detection: walks into
ArrayPush/ArrayUnshift/ArrayPushSpread - Class instance .map() interception: fixed; var loop closure hoisting; user-defined class type inference
- Plugin builds: restore
dead_stripwith selective symbol retention - String-returning function calls: recognized in concat and console.log
- Dynamic property access: via array key
New APIs
Uint8Array.prototype.set(source, offset)andUint8Array.prototype.fill()trimStart()/trimEnd()string methods- Plugin host support: export symbols for
dlopen'd plugins
Full Changelog: v0.2.183...v0.2.192