Skip to content

Add browser playground with Node.js and Python examples#4

Merged
NathanFlurry merged 1 commit into
mainfrom
fix-browser-support-tests
Mar 10, 2026
Merged

Add browser playground with Node.js and Python examples#4
NathanFlurry merged 1 commit into
mainfrom
fix-browser-support-tests

Conversation

@NathanFlurry

@NathanFlurry NathanFlurry commented Mar 10, 2026

Copy link
Copy Markdown
Member

Summary

  • Add new @libsandbox/playground package with browser-based code execution UI supporting Node.js and Python
  • Implement browser runtime worker that properly awaits async filesystem operations and Promise-based code
  • Fix permission callback serialization for Web Worker context by inlining return values
  • Add example selection submenus demonstrating in-memory counters and file system operations
  • Include server implementation with COEP/COOP headers and path alias support for vendor assets

Tests

  • Added browser runtime integration tests
  • Verified async/await behavior in worker eval context
  • Tested file system example counter persistence across executions
  • Python permission callbacks now work correctly in browser context

@NathanFlurry NathanFlurry force-pushed the fix-browser-support-tests branch from 4bc8628 to bb6ebe8 Compare March 10, 2026 06:32
@pkg-pr-new

pkg-pr-new Bot commented Mar 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/rivet-dev/secure-exec@4

commit: 9e27746

@NathanFlurry NathanFlurry merged commit fbf126c into main Mar 10, 2026
1 of 2 checks passed
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…el native debugging

When a milestone is blocked on a hang/crash/wrong behavior, first name the native technique you'd use
(gdb bt, strace -f, /proc/wchan, GDK_DEBUG/GDK_SYNCHRONIZE, xtrace), then build the parallel tool for
the wasm/secure-exec runtime if feasible (it's reusable and expected work, not a detour); if no
reasonable parallel exists, fall back to ad-hoc probes and move on. Lists the high-ROI parallels:
sync-RPC trace (strace), on-demand guest stack dump (gdb bt), process/pump-decision view (top//proc),
env passthrough to guests (app debug flags), built-in X wire tracer (xtrace). Motivated by the M8
gtk_init cross-VM poll-scheduling hang costing far more to find than to fix, for lack of observability.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
… M8 debugging

Per SPEC.md constraint #4 (parallel native debugging tools). Logs every guest<->sidecar sync RPC per
process with timing at the central dispatcher (service_javascript_sync_rpc). Pure instrumentation,
off unless SECURE_EXEC_TRACE is set; identifies processes by kernel_pid.

Immediately paid off on the M8 gtk_init hang: it REFUTED the prior 'X server starved by the client's
net.poll' theory. The trace shows the X server (pid 1) healthy, looping net.poll/server_accept the
whole time, while the GTK client (pid 2) stops making ANY RPC at t=12s (its last polls return ready in
2-14us = data arrived) and goes silent. Combined with /proc thread states (client session-v8-exec
thread at 103% CPU, state R; a second session-v8-exec = a GLib worker thread; everything else in
futex_wait_queue), the real cause is a BUSY-SPIN between the GTK leader and a GLib worker thread in
pure wasm (no host calls) — not server starvation and not a futex deadlock. Next tool: a wasm sampling
profiler / stack unwinder to pinpoint the spin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…ecklist) for M8 observability

Records the methodology behind SPEC.md constraint #4 and a prioritized checklist grouped EXPOSE /
ANALYZE / PORT(reuse). Key constraints: CLI is veneer (expose the capability, not the tool); debug
from the host; wasm guests have no native CPU so the gdb/strace/ptrace class must be built wasm-aware;
port only to reuse parsing/symbolization host-side; off-by-default zero-cost instrumentation. Short-term
plan: all-isolate stack-dump + DWARF symbolizer, then lock/contention tracer, then process/scheduler
view, then an on-hang bundle. SPEC.md constraint #4 now links to it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…ols + correlatable breadcrumbs

SPEC M8.1: add tools #4 (sync-RPC tracer), #5 (lock-holder/silent-guest watchdog = the M8.1
thread/lock-holder dump), #6 (host-stamped guest "BC:" breadcrumbs on the watchdog timeline), the
SECURE_EXEC_ASYNC_POLL A/B switch, and the still-TODO DWARF-symbolizer-for-parked-wasm. Records the
first payoff (the openbox+pcmanfm interior stall is in-guest, not a sidecar deadlock) and the scoped
NEXT STEPS for the M8.6 interior-paint fix.

host: stamp guest stderr with a relative-ms timestamp so fprintf "BC:" breadcrumbs line up with the
sidecar rpc-watchdog dumps in the run log.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…onditional drain skip

Per constraint #4 (observability before guessing): the ~140s LXDE listing load under 3-client
contention is net_poll's drain doing a net.poll sync-RPC PER connected socket PER poll
(pollHostNetSocket calls callSyncRpc('net.poll') every time), and the single-threaded X server
spins at timeout=0 over 3 client fds — the 8000/s futex storm. (net_recv already batches.)
Tried skipping the drain when the readiness generation is unchanged: it BLACK-SCREENED
openbox+pcmanfm — the per-socket drain is load-bearing (pollHostNetSocket pulls one chunk per
call; a global last-gen is wrong for multi-threaded pcmanfm). Reverted, render restored
(center-window back to 209817). The correct fix is to BATCH the drain into one net.poll_batch
sync-RPC for all of a process's sockets, or mirror the readiness gen into a SAB the guest reads
without a round-trip. Speed is polish, not an M8.6 blocker (it renders in under 5 minutes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…r-thread Hello is the blocker)

XU1 (xfconf+xfsettingsd) foundation. xfconf reaches the bus via GDBus (GIO), not libdbus, so the
gate is GDBus-over-host_net — de-risked before building the xfconf stack (constraint #4). Adds a
GDBus probe (guest-xclient/gdbus-probe.c + scripts/build-gdbus-probe.sh: g_bus_get_sync(SESSION)
+ ListNames, linked against the threaded GLib/GIO stack + the dbus_creds host_net shims) run
against the daemon via --bus-test.

Progress:
- GIO AF_UNIX connect fixed (general platform bug, in the vendored wasi sysroot): GLib's
  g_socket_connect needs sizeof(sockaddr_storage) >= sizeof(sockaddr_un)=110, but wasi's was ~34
  (__ss_data[32]) -> every GIO AF_UNIX connect failed G_IO_ERROR_NO_SPACE. Enlarged sockaddr_storage
  to 128 (Linux _SS_SIZE) + recompiled glib's gsocket objects via compile_commands.json.
- GDBus SASL auth now works over host_net (ANONYMOUS; EXTERNAL rejected because GIO getuid()->-1).
- Harness forwards G_DBUS_DEBUG/G_MESSAGES_DEBUG for client-side tracing.

Remaining blocker: post-auth a GDBus worker thread sends the initial Hello and blocks before the
bytes reach the daemon (GMainContext/GSocket async I/O + cross-thread context wakeup over host_net,
the M8.5 worker-context area). XU1 not yet closed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…iro A1 shape masks)

Constraint #4 observability: XTRACE + a new bare-X-server repro
(guest-xclient/bgpixmap-test.c) narrow the xfwm4 decoration blank to a precise,
proven root cause.

Findings:
- xfwm4 runs as a WM: reparents (3 ReparentNotify), creates the 326x32 titlebar,
  uploads REAL decoration pixel data (18 PutImage, 17-62% nonzero), ~30 CopyArea.
  Images load fine.
- The wasm X server (real X.Org Xvfb) passes EVERY primitive xfwm4 uses, proven
  by bgpixmap-test: solid bg color, background pixmap, TILED bg pixmap (16x16 on
  200x150), direct draw, and the SHAPE ext XShapeCombineMask (left-half mask ->
  left visible, right shaped away). openbox decorates fine in the same workspace.
- Root cause: xfwm4 shapes its title/side/corner decoration windows with a mask
  via XShapeCombineMask (frame.c:512-544); the mask is a depth-1 bitmap drawn
  with CAIRO (cairo_xlib_surface_create_for_bitmap). An all-zero mask shapes a
  window to nothing (proven). Since even fully-opaque transcoded decoration PNGs
  render invisible, cairo->depth-1(A1)-bitmap rendering produces EMPTY masks in
  the wasm cairo build -> XShapeCombineMask shapes all decorations away. openbox/
  twm draw rectangular decorations directly and never shape, so they work.

Next (constraint #5, platform): a cairo-to-A1 test to confirm, then fix the wasm
cairo A1/depth-1 xlib-surface (pixman A1) rendering. xfwm4 stays unmodified.
Side finding: xfwm4's xpm_image_load fread+fseek+getc hits a wasi-libc
fseek-after-fread stdio-buffer bug (PNG fallback covers it). M8+XU0+XU1 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…h (every other layer ruled out)

Eliminated every layer below cairo with standalone wasm probes (constraint #4),
all PASS:
- X-server A1: core-X XFillRectangle, XRenderFillRectangle->A1 Picture,
  XGetImage+XPutImage round-trip (xrender-a1-test E/F/G)
- bg-pixmap + tiled bg-pixmap + SHAPE XShapeCombineMask (bgpixmap-test)
- PictStandardA1 + depth-1 pixmap formats present (rfmt-probe)
- pixman_image_fill_boxes on a PIXMAN_a1 image: set_bits=1024/2048, exactly the
  left half (pixman-a1-test)
- cairo -> depth-24 color pixmap (xfwm4's 18 real PutImages)

ONLY cairo -> depth-1 (A1) mask is broken (empty -> xfwm4 decorations shaped
away). So it is NOT the X server, NOT pixman, NOT the XPutImage upload, NOT
cairo-in-general -- the break is specifically cairo's
cairo_xlib_surface_create_for_bitmap + A1-fill orchestration in the wasm cairo
build (likely a wrong render/pixman-format pick for depth-1).

Next (wasm cairo build): get a cairo test harness running (cairo crashes on
first use in a minimal non-GTK binary -- an init/TLS issue, not the A1 bug),
then inspect _cairo_xlib_surface_create_for_bitmap's format selection. xfwm4
stays unmodified. New probe tools: guest-xclient/{xrender-a1-test,pixman-a1-test}.c.
M8+XU0+XU1 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
… blockers

Built UNMODIFIED xfce4-panel 4.18.6 -> xfce4-panel.wasm (15.9 MB) +
libxfce4panel-2.0.a via scripts/build-xfce4-panel.sh (Xfce autotools + GTK
recipe; all deps already built from XU1/XU2; --datadir=/usr/share). The panel
binary links + fpcasts and starts, but crashes at startup. Observability
(constraint #4) pinned two general Xfce-static-linking blockers:

1. libxfce4ui GResource not registered -> Gtk-ERROR abort. The dialog UI is a
   GResource whose register-constructor sits in libxfce4ui-resources.o inside
   libxfce4ui-2.a; archive-pull drops it (nothing references it), so the ctor
   never runs -> "resource ... does not exist" -> unreachable. (xfwm4/xfsettingsd
   link the same lib but never open a dialog.) Force-linking it is BLOCKED on
   automake plumbing: the panel link ignores `make LDFLAGS=` (uses configure-time
   AM_LDFLAGS with the thread flags) and the LIBS-based --whole-archive/--undefined
   produced a byte-identical binary (make not relinking). Next: a clean manual
   relink or the right per-target automake var. Also helps XU4/XU5.

2. gmodule/dlopen static plugins. All 13 panel plugins are external .so loaded
   via g_module_open/symbol (none X-XFCE-Internal); no dlopen in the sandbox.
   Unlike M8's lxpanel (built-in plugins), xfce4-panel has no static registration.
   Next: a gmodule shim, or build core plugins as X-XFCE-Internal into the panel.

M8 + XU0 + XU1 green; XU2 decoration done.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…ex deadlock

Full observability chain (constraint #4): XTRACE shows the panel maps windows but
never draws (PutImage=0); an EMPTY menu (just xfce-applications.menu + .directory,
zero apps) also stalls so it's the menu INIT not the app scan; the RPC watchdog
is silent so it's not a sync-RPC; and the stackdump (a 16MB names-kept fpcast --
--strip-dwarf without --strip-debug, since the 56MB --debuginfo build won't
launch) shows EVERY guest thread PARKED-ON-FUTEX (V8 FutexEmulation::WaitSync <-
WasmI32AtomicWait) = a pthread cond/mutex deadlock. A GIO worker thread probes
the system bus (/run/dbus/system_bus_socket -> ENOENT) and exits at ~51s; the
menu-init's cross-thread cond/futex is never signaled (same class as the known
GIO worker-context wakeup issue).

Fix is one of: (a) [pending human sign-off, a D-Bus surface decision] point
DBUS_SYSTEM_BUS_ADDRESS at the existing session bus so the worker connect
succeeds instead of failing+exiting; (b) [runtime] wake/abort futexes when a
worker isolate exits, or fix the GIO worker GMainContext wakeup.

The default panel (clock/tasklist/systray/separator) renders fine; the
applicationsmenu button renders; only the populated menu deadlocks. M8+XU0+XU1
green; XU2 decoration done.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…ck fix

Reversible non-TCB experiment (constraint #4): hypothesized the system-bus probe
during garcon menu init came from GIO's NetworkManager network-monitor backend,
so the null/base monitor would avoid it. Added GIO_USE_NETWORK_MONITOR=base to
the host cenv (analogous to the existing GIO_USE_VOLUME_MONITOR=null), rebuilt,
re-ran the populated applicationsmenu: STILL deadlocks and the system-bus probe
STILL fires -> not from GNetworkMonitor. Reverted (ineffective).

Conclusion: the app-menu stall is the deeper GIO worker-context wakeup issue (the
GMainContext/GSource cross-thread wakeup on a GIO worker thread that the XU1
GDBus-worker fix didn't cover for garcon's menu-init async path), or it needs the
D-Bus option (a) (DBUS_SYSTEM_BUS_ADDRESS -> session bus), still awaiting human
sign-off. The taskbar/clock/systray/separator + xfwm4-decorated windows all work.
M8+XU0+XU1 green; XU2 done.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…up block, NOT the volume monitor

Per constraint #4, traced Thunar's full lifecycle. Findings: hard-blocked (black at
165s, not slow); 0 windows ever map; ~30s silent startup, then the GtkApplication
session-management setup (session manager + inhibit portal proxies all fail as
expected in the sandbox) + the volume-monitor GModule warning, then silence.

Volume monitor RULED OUT: GIO_USE_VOLUME_MONITOR=null is a deliberate host setting
(avoids the union-monitor deadlock) and pcmanfm rendered with the identical setting
+ warning. So Thunar blocks in the GtkApplication startup/open phase before
constructing the ThunarWindow -- distinct from the fixed file-monitor hang.

The inotify task#11 fix DID generalize to Thunar (file-monitor hang gone, session
bus + xfconf working); only this GtkApplication-startup block remains. Next:
Thunar-specific open/command-line tracing; separately verify inotify on xfdesktop
desktop icons (XU4, non-GtkApplication, likely simpler).

M8+XU0-XU2 green; XU3 panel+applicationsmenu DONE; XU4 wallpaper done; XU5
file-monitor+session-bus unblocked, window-map pending.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…pawn+pty); 14 guest shims to port

Investigated the impl scope (constraint #4). The threaded vanilla libc provides only ioctl -- the other 14
(posix_spawnp/waitpid/kill/fork/execv/execve/setsid/getpgid/grantpt/posix_openpt/ptsname/unlockpt/tcgetattr/
tcsetattr/dup2/pthread_sigmask/cfmakeraw) are absent (the spawn/pty/process wasi-libc patches arent in the
threaded sysroot; pty is musl pty.c/ptsname.c). KEY: the wasm-gui SIDECAR already serves spawn
(execution.rs:3035 spawn_process + proc_spawn) AND a PTY seam (13618 pty_set_raw_mode + pty_set_discipline)
-- so the terminal is FEASIBLE.

Plan: build a threaded vte-syscompat lib providing the 14 shims (port the wasi-libc spawn patch + musl
pty.c wired to the sidecar seams, termios on pty_set_discipline, the fork->posix_spawn deferred shim +
stubs), link into xfce4-terminal. The VTE library already compiles (835KB); only these shims remain.

XU6 terminal; not 100% (XU7 = sidecar sign-off).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…stripped by wasm-ld (lsda=0), not a type_info linkage issue

Instrumented the EH runtime (constraint #4). Evidence: typeid(int) returns a valid type_info at runtime (so
the type_info IS present -- the earlier "type_info wont link" was WRONG; nm 0-ZTI was a stripped NAME).
__gxx_personality_wasm0: native=1, class correct, but scan_eh_tab returns CONTINUE_UNWIND. _Unwind_CallPersonality
shows lpad_index=0 lsda=0x0 -- the landing pad passes a NULL LSDA. scan_eh_tab line 627 early-returns on lsda==0.
catch(...) works WITHOUT the personality (wasm catch_all catches directly) -- exactly why catch(...) works and
catch(int) fails. eh-tref.o HAS GCC_except_table0 + the landing pad sets lsda via R_WASM_MEMORY_ADDR_SLEB
GCC_except_table0+0 (reloc correct in the .o), so wasm-ld dead-strips the per-function LSDA at the final link ->
reloc resolves to 0. --no-gc-sections doesnt fix it (pulls fd_advise importers + bloat).

True fix (deep wasm-ld/codegen, autonomous toolchain, not a sign-off item): make wasm-ld retain the per-function
LSDA referenced by R_WASM_MEMORY_ADDR_SLEB from kept code. THE blocker for VTE typed catches. VTE renders, pty_open rc=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…wIn fix); settings-grid is a manager code-path, definitively stopped

Constraint-#4 observations (which I had skipped, guessing "deeper" at T39) converged the settings-manager empty-grid cause:
(1) the real settings .desktop carry OnlyShowIn=XFCE -> garcon hides them unless the guest advertises XFCE. Fixed generally
in the host: XDG_CURRENT_DESKTOP=XFCE in the guest cenv (all 3 launch paths) -- correct for the Xfce session, helps any
freedesktop OnlyShowIn/NotShowIn filter. (2) the manager builds per-category boxes from menu SUB-MENUS, not flat items.
With XDG set + correct sub-menu structure + absolute AppDir + real .desktop, the grid is STILL empty -> it is the managers
garcon item-loading / category_box population in the wasm guest (code path, silent class), not a fixture. Definitively
stopped. Hub chrome renders (T37). Genuine win: the XDG_CURRENT_DESKTOP host fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…lyShowIn removed, still empty) -- definitively closed

Ran the definitive constraint-#4 isolation rather than assume the T42 verdict: removed OnlyShowIn from the staged .desktop
(test fixture, not source) + re-rendered. Grid still empty (0 crashes, chrome only). So OnlyShowIn/the XDG env is NOT the
cause -- ruled out. With T37-T42 having eliminated flat/real/sub-menu fixtures, every fixture/env hypothesis is gone: the
empty grid is the managers garcon/category_box code path in the wasm guest (silent class), verified not guessed.
Definitively closed -- no more attempts. Hub chrome renders (T37). The XDG_CURRENT_DESKTOP=XFCE host fix (T42) stands as a
general correctness fix independent of the grid. Net: 1 real host fix + a verified code-path verdict.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…p (XfceTitledDialog type unregistered)

Major constraint-#4 win. The silent-trap class was "deep" only for lack of a symbolizer (KEEP_NAMES bloats big GTK guests
past the frame cap). KEY: the runtime prints trap frames as wasm-function[N], so an ADDRESS-based symbol map works without
running a named binary -- re-fpcast KEEP_NAMES to extract --symbolmap, then strip ONLY the name section (indices preserved)
to get a runnable index-matched binary, re-render, map the frames. Keyboard stack resolved to g_log_writer_default->abort =
a GLib fatal log: "Failed to load the UI file: Invalid object type XfceTitledDialog". Root cause: the 3 rendering dialogs
force-register the type (if xfce_titled_dialog_get_type()==0) before their builder; the keyboard does not, and the static
no-dlopen build does not auto-register it. Fix shape (constraint #5): a build-linked constructor that ensures the type,
keyboard source untouched. Symbolizer is reusable for the whole silent class (grid, theme enum). proof-kbd.symbolmap saved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…symbolizer->root-cause->platform-fix

The full constraint-#4 chain, end to end:
- Built an address-based trap symbolizer (the runtime prints wasm-function[N] frames): re-fpcast KEEP_NAMES to extract
  --symbolmap, strip ONLY the name section (indices preserved) for an aligned runnable binary, re-render, map frames.
- Root-caused the keyboard silent trap to a GLib fatal log: Invalid object type XfceTitledDialog (NOT XKB as long guessed,
  NOT tree-view as a misaligned first pass suggested). The 3 rendering dialogs force-register the type after
  gtk_init_with_args; the keyboard does not, and the static no-dlopen build does not auto-register it.
- Fixed in the platform layer (constraint #5): toolchain/xfce-type-ensure.c wraps gtk_init_with_args (-Wl,--wrap) to
  ensure the type right after the real init -- keyboard SOURCE unmodified. (A pre-main constructor ran too early:
  g_type_register_static asserts before GObject init.)
- Result: keyboard-settings renders fully (Behavior/App-Shortcuts/Layout tabs, repeat sliders, Test area), exit 0.

The symbolizer is reusable for the remaining silent traps (settings grid, theme enumeration). Records updated
(progress.html, XUBUNTU-SPEC, M8-STATUS-LOG); proof-kbd.symbolmap + xu6-keyboard.png saved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…source, did not build tweaks/workspace

Constraint-#4 source check: tweaks-settings.c line 530 has the same "cannot work with your current window manager" exit as
xfwm4-settings.c, and workspace-settings.c uses libwnck (talks to the running WM). So all 3 xfwm4 Settings-Manager dialogs
require a running WM = a 2-guest scenario = Root-2-gated (T53). Did not build tweaks/workspace; the parameterized
build-xfwm4-settings.sh covers all 3 for when Root-2 is resolved. The xfwm4 settings trio folds into the XU7 sign-off.
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…ecipe extends to the exo package family

The constraint-#4 "look before concluding harvested" found a clean target where the last two were gated. exo-desktop-item-edit
(Create Launcher / Edit Launcher, used by xfdesktop/Thunar) has 0 WM checks, gtk_init_with_args, links libxfce4ui+libexo.
Wrote scripts/build-exo-item-edit.sh; built (14MB), rendered first try (0 LinkError/traps) with --create-new args (host
--client passes args). Faithful UI: Name/Comment/Command/Working-Dir/Icon + startup-notification/run-in-terminal checkboxes,
Help/Cancel/Create. First component from exo -- the recipe+shim generalize beyond xfce4-settings. Records updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…est scope correction

The thunar-sbr renamer plugin now loads all-wasm: the bulk-rename dialog shows live rule controls
(Insert/Overwrite, Name only, Insert/Text/At-position) instead of the "No renamer modules" infobar.
Proof: ~/tmp/gui-progress/2026-06-26T17/xu3-thunar-sbr-static.png.

Mechanism (toolchain/, components untouched -- constraint #5): keep-shim constructor defeats wasm-ld
--gc-sections; --export the entry points; --wrap=g_module_open returns a non-NULL sentinel handle (the runtime
has no self/main-module handle so g_module_open(NULL)=0); --wrap=g_module_symbol resolves the 3 thunarx entry
points by name; a marker .so triggers the factory dir-scan. The real bug was found by adding SHIMLOG logging to
the wraps (constraint #4) -- correcting an earlier WRONG "libtool strips the flags" root cause.

HONEST CORRECTION: I initially framed this as the "XU3 core blocker" -- wrong. XU3 (panel+plugins) was already
DONE 2026-06-25 via the EXISTING toolchain/gmodule-shim.c (named-handle + generated table); the cron seed is
stale. This is an XU5 Thunar enhancement (different plugin family). My gmodule-static-shim.c (sentinel) +
thunar-sbr-symwrap.c (hardcoded names) DUPLICATE that existing shim inferiorly -- it already returns a
name-carrying handle (never hits g_module_open(NULL)=0, the thing I spent ~12 fires re-discovering) and resolves
via a table. FOLLOW-UP (GMODULE-STATIC-PLUGINS.md): consolidate thunar onto the existing shim, drop the
duplicates, re-verify panel+thunar. Lesson: observe existing solutions + re-read the spec before a long build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant