EngineRegistry caches one Engine per working-project URL.
MainWindowView.init does a pure lookup, so SwiftUI's
view-tree re-evaluations cannot open extra ProjectStores
that race the live one's BEGIN IMMEDIATE and crash via
try!.
UI-state persistence (collapse flag, sidebar selection,
session detail section, etc.) lives on Engine for GTK to
adopt. SQLite has a 5s busy timeout. Engine open failures
surface as an error view.
TargetPicker is host @State injected via environment.
Global instrument-UI defaults register at app startup;
per-engine instrument and local-notifier hookups live in
Engine extensions.
Gate min-width frames behind isCompactWidth so the event stream,
target picker, codeshare browser, and collaboration panel collapse
cleanly on iPhone instead of forcing a scroll at their regular
widths. Give the event stream a dedicated compact header that
promotes the source / process filters to icon menus and keeps the
search, pause, and clear controls inline.
Drop the auto-select-first behavior in the target picker and
codeshare browser on compact, so tapping a sidebar row navigates
to the detail pane on NavigationSplitView's built-in stack instead
of stranding the user looking at a preselected item.
Push the instrument event-row monospaced font up into each
InstrumentUI factory and out of JSInspectValueView, so tracer,
hook-pack, and codeshare rows match without recomputing it for
every sub-value. Migrate the JS inspector disclosure label to
AttributedString to kill the deprecated Text + Text concatenation
warning. Tighten REPL result formatting and relabel the detach
banner hint.
Workspace is now a thin host adapter. Engine owns sessions and
notebook entries (via store observation), GitHub auth + OAuth
device flow, hook-pack discovery, address annotations and address
actions, the disassembler cache, and all instrument lifecycle.
EventLog is @Observable so SwiftUI tracks it directly; the host
no longer mirrors event arrays or version counters.
R2 (live disassembly + trace inspection) lives entirely in
LumaCore as concrete Disassembler / TraceDisassembler classes
returning portable StyledText spans. ProcessNodeViewModel and
InstrumentRuntime are gone; views read engine.processNodes /
node.instruments / engine.descriptor(for:) directly.
Reorganize Luma/Models/ — instrument UI dispatch lives under
Luma/Instruments/, Monaco editor glue under Luma/Editor/, and the
remaining UI types sit at the top of Luma/.
InstrumentDescriptor (LumaCore) holds the data: kind,
identifier, display name, icon, initial config, and
event summary. Engine maintains a descriptor registry.
InstrumentUI protocol (Luma) defines the SwiftUI view
factories. TracerUI, HookPackUI, and CodeShareUI
implement it. InstrumentUIRegistry maps descriptor
IDs to UI instances.
Workspace no longer constructs templates. Views look
up descriptors via engine and UI via the registry.