* chore: release v0.8.159
* chore: v0.8.159 notes list the first-frame fix
* chore: v0.8.159 notes list the sandboxed GPU check fix
* chore: v0.8.159 notes list the hidden-scene fix and the offline font test
* chore: release v0.8.154
* ci: give the studio test job fifteen minutes
The queue run installs and builds inside the same ten minute cap.
It was still inside the studio tests when that cap cancelled the job.
* chore: release v0.8.152
* docs(changelog): correct the v0.8.152 release notes
The summary overstated snapshot retention, history turns, and video state.
It also left out the new artifact paths and nullable keyframe times.
* fix(cli): snapshot, check, layout and thumbnails honour software WebGPU like render
* test(cli): stub the local WebGPU helper in the studio server tests
* fix(engine): webgpu compositions are recognised after the bundled runtime script
* fix(engine): a hung GPU probe falls back to software in 15 s instead of 120 s
* fix(engine): the GPU probe keeps the configured launch timeout and bounds only its page
* build(parsers): declare the html-attribute-spans subpath in its descriptor
* build(gcp-cloud-run): the BeginFrame contract stage copies parsers, which the engine now imports
* test(cli): the screenshot launch pin follows the shared local WebGPU helper
* fix(engine): the GPU probe's wait for Chrome's first page falls inside its 15 s limit
* fix(studio): serve files whose name has a bare percent sign
A browser sends src="100%.png" with the % unescaped, and decoding the whole path threw, so Studio answered 500. Only well-formed escapes are decoded now.
* fix(cli): serve files with a bare percent sign from the check and snapshot server
One shared decode rule for request paths; the image thumbnail route's malformed-escape 400 could no longer fire, so a name that is not a file is a 404.
* fix(cli): name a failed file with a bare percent sign in check
* fix(studio): keep apostrophes and dollar signs in file names when editing attributes
An attribute value is matched by its own quote kind, so src="it's.png" is replaced instead of duplicated, and every insert uses a function replacer, so $1 or $& in a file name is written as is.
* fix(studio): rename references spelled with %20 or & and read quoted media sources
WIP: not yet tested; see the resume note.
* fix(studio): match whole attribute names when editing media sources
* fix(studio): compare decoded names and escape replacement references
* fix(studio): preserve file references across URL and string consumers
* docs: clarify raw file references and URL fields
* fix(studio): keep raw path identity distinct from URL spelling
* fix: share attribute grammar and decode media URLs at their readers
* fix: preserve local filename identity in HTML URL output
* fix: decode entity references before rename candidate matching
* style: format rename entity handling and regressions
* fix: preserve platform file identity when renaming references
* fix(core): decode CSS escapes before rebasing asset URLs
* fix(core): consume CSS continuations before URL encoding
* fix(core): preserve CSS URL identity and escape rebased suffixes
* fix(core): express CSS suffix controls with Unicode categories
* fix(core): preserve URL backslash identity while rebasing
* test(core): respect platform backslash filename semantics
* fix(studio): a dropped file with %, # or ? in its name loads, and an encoded reference renames
* fix(studio): read an authored src as a URL so dropped files with spaces, %, # or ? load
* fix(studio): media routes find files named with ? or #, and the probe reads a src as a URL
* fix(studio-server): one rule for request file paths, so loudness finds files named with %, # or ?
* chore: drop the design note from the change
* fix(core): rename replaced clips whose src is URL-encoded