fix: let the thread that finished a job wake the plugin that started it

A plugin's Waker only ever set a thread-local, and every caller of it is a
worker thread the plugin started, so waking was a no-op from the one place
that does it. Nothing told the host a traced frame had landed either, so a
host that steps a plugin only when it has a reason to had no reason to, and
a settled editor sat on a finished job until something else asked for a
frame.

The wake is now a call out of the guest. It sets a flag any thread can set
and reaches the host through be3_host::host_wake, which is the one host call
a spawned thread may make: it touches nothing but the shared wake, where
every other call belongs to the thread that made the plugin. The native host
turns it into a repaint request, and a step that produced nothing is only
quiet when no wake arrived during it. The browser answers a thread's wake
with a message to the worker the plugin runs on, which schedules the next
step, because the JavaScript beside a module belongs to the thread that made
it.

A thread that trapped now wakes the host as well. Its failure was only ever
read on the next step, so a region that had stopped being stepped swallowed
it; the wake is what gets the host to ask. The plugin also reports a failure
recorded while it was idle before it runs another step rather than after.

The browser bootstrap runs the plugin's constructors too, which it was
missing for the same reason the native host was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017FqS3Cpn9uRcrCwAABBq2p
e5322d8244Claude committed on 9/20/2026, 8:12:03 PM· committed by pfgparent0714cdd
18 files changedLine totals unavailable