Add a machine abstraction to LumaCore, with QEMU as its first
backend: templates mirroring frida-core's test guests, a QMP client,
and a display that maps QEMU's surface over D-Bus rather than
copying frames.
Leave readiness to the user: drive the guest, mark it ready, and come
back to that snapshot later. Keep the machine in the project, so
booting it again resumes where it was marked. Hand the stub to
addBareboneDevice, so it joins the picker beside the other devices.
Show the display while booting, and afterwards in a Machines panel,
which the side panel now models as an enum to share its slot.
The playground, the notebook cells, the source editor with its
marks, the inspector columns and the canvas are written once for
both Apple platforms, with a file naming what the two frameworks
call differently. The editor is where they really part company.
The engine owns the image and its start-up, so a mission reaches
the whole of Pharo.
Bundle compiler reads Agent/bundle.json describing outputs,
bundles, typings, and externals. Package install is driven by
Agent/package.json + Agent/package-lock.json (managed via
frida-pm), so the lockfile is the source of truth for resolved
versions.
@types/frida-gum and @types/node are embedded into
LumaTypings.swift at build time; the Resources d.ts is no
longer checked in. Editor profiles append both as extra libs.
Apple's Network.framework default signature_algorithms ClientHello
extension lists only RSA and ECDSA — never ed25519 (0x0807) — so an
Ed25519-only TLS server is unreachable from any third-party client
that links Apple TLS instead of statically linking OpenSSL. The
existing pinned cert was Ed25519, which works when using
glib-networking's OpenSSL backend, but breaks when moving to its
new Apple backend.
Switch the bundled pin to a fresh ECDSA P-256 cert with the same
extension structure (CA:TRUE + SKI/AKI + SAN). Forward-secrecy posture
is unchanged: TLS 1.3 still negotiates X25519MLKEM768 (NIST FIPS 203)
for the KEM, which is what protects against Harvest-Now-Decrypt-Later
regardless of the cert signature algorithm.
Point BackendConfig at portal.luma.frida.re:27042 and ship the
matching self-signed Ed25519 cert (LumaPortal.pem) as the only
trust anchor. The Let's Encrypt root (ISRG Root X1) is removed
along with the CA-based trust model.
Invite links now use https://luma.frida.re/l/<roomID> — the
portal server renders an HTML landing page for those paths so
shared links have a preview. The URL prefix lives in
BackendConfig so it only needs updating in one place.
The portal server uses the same cert on both control (for this
client) and cluster (for frida-join) endpoints, so the app never
trusts anything else for the portal and we're off the 90-day LE
renewal treadmill.
REPL completion:
- Caret-anchored popover via pango layout measurement.
- Capped popover height to 160px so it always opens
downward and never overlaps the input.
- Enter / Tab accept the selected suggestion; Up/Down
navigate; Esc dismisses; popover never re-opens until
the user actually adds or removes a character.
- dismissCompletionPopover now cancels both the debounce
and the in-flight request task so a stale continuation
can't re-show the popover after acceptance.
- suppressUntilText lock guards every onChanged event
that matches the freshly-written text.
- selectRegion(-1, -1) clears the all-selected trap after
programmatic edits.
Sidebar / context menus:
- .luma-menu-item class on every popover-menu button so
Adwaita's flat-button hover styling can't compete; the
.luma-menu-destructive variant now uses red text + red
hover background as expected.
- Translate row-local click coordinates to pane-local
space so context menus open at the cursor even when
the popover anchors to the stable pane widget (so a
new event arriving while the menu is open doesn't
unparent it).
Tracer:
- EmptyStateSearch renamed to TracerHookSearch with a
Layout enum (.emptyState / .popover); the empty state
and the toolbar "+" button both embed the shared
widget. The "+" popover is held strongly by the editor
and dismissed after a successful add.
Add Instrument:
- CodeShare branch now mirrors SwiftUI: empty state
("No snippet loaded" + Browse CodeShare suggested
action) when nothing is loaded, full editor + name /
description / source fields once a snippet exists.
- Default window size bumped to 960×720 so the Add
button is visible without scrolling.
- Tracer dedupe no longer exempts the tracer descriptor.
Event stream:
- Collapsed mode uses a CSS border-top on
.event-stream-pane instead of an explicit Separator
so the visual weight stays consistent across states.
- Toggle button left margin trimmed to remove the
asymmetric padding before the triangle.
Engine:
- Reset session phase to .idle on Engine.start() so
sessions loaded from disk show the detached banner
instead of presenting as already attached.
LumaCore typings:
- Move frida-gum.d.ts up out of Resources/Typings so
SwiftPM's flat resource processing finds it without
a subdirectory hack on Linux. TypeScriptTypings just
does a single Bundle.module.url lookup.
App:
- rebuildPrimaryMenu skips when the recents signature
is unchanged, fixing the "duplicate child name in
GtkStack: Open Recent" warning on document open.
LumaCore now ships frida-gum.d.ts as a processed resource and
exposes it via TypeScriptTypings.fridaGum so both the SwiftUI
host and LumaGtk read from one source of truth. The host's
TypeScriptEnvironment reuses the new accessor; LumaGtk's
MonacoTypings does the same.
CollaborationSession is now @Observable. Views read its
state directly via workspace.engine.collaboration. The
notebook entry methods live on Engine. The portal cert
is a LumaCore SwiftPM resource via Bundle.module.
Workspace keeps only the auth-flow glue (showing the
sign-in sheet, signOut clearing UI state) and the deep
link join handler.