Move to the single cmd that returns an R2CommandResult with an
optional output, and handle the nil that r2 yields for commands
with no string result (e.g. an invalid command from completion).
Bump the SwiftyR2 pin to the revision with that fix.
cmdWithLogs adds a collector callback for hasErrors but never
muted radare2's own stderr printing, so read-only function
probes flooded the console. Set log.quiet on both disassembler
cores; the collector still fires, so error detection is
unchanged.
New LumaCore.Appearance (light, dark). DisassemblyRequest,
Disassembler and TraceDisassembler key on it directly; the
r2 theme mapping lives in one place. ThemeWatcher returns
Appearance; remaining C-interop callers compare to .dark at
the boundary. CFG views use themeAppearance to avoid clashing
with NSView's inherited appearance property.
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/.