Commit Graph
64 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås f96764edf7 ui: Move insight refreshes to the sidebar menu 2026-10-01 20:49:11 +02:00
Ole André Vadla Ravnås a6f769221f ui: List pattern types in the sidebar
Show each file's declared types under it, with a browse popover when
there are many, and reveal a type's declaration when it is chosen.
2026-10-01 20:49:11 +02:00
Ole André Vadla Ravnås b83995dcce ui: Add a patterns section with an editor
List the library's files in the sidebar with new, import, rename and
delete, and edit each in the code editor, which now colours by syntax.
2026-10-01 20:49:11 +02:00
Ole André Vadla Ravnås 67b08b72ca ui: Show how connecting to a device is going
Read the shared connection activity in the target picker and put the
current stage, with a progress bar that eases toward the next stage
over its expected duration, under the spinner in place of "Querying".
Show the stage on an attaching session's row too, since a session
re-establishing connects the same way.
2026-09-16 13:00:08 +02:00
Ole André Vadla Ravnås 58cc198c6a Scroll the columns and the strip together
A drill reveals its new column whole, scrolling through the reader
rather than at a position measured before the column exists, and
the strip's thumb both follows the columns and drives them.
2026-08-13 12:46:08 +02:00
Ole André Vadla Ravnås 3aab17ca5a Run Pharo from the notebook and a playground
Boot the VM against a bundled image, evaluate from a notebook cell
or a playground snippet, and keep what each evaluation produced.
The image is staged on every build; the framework release is pinned.
2026-08-13 12:46:08 +02:00
Ole André Vadla Ravnås 5ed87e6018 Make sidebar hooks collapsible like module groups
Give instruments that have hooks a disclosure chevron and persist
the per-instrument collapsed state in the session UI state. Toggle
the module and thread groups on a full header-row click. Pad the
module view so its tabs clear the top-left edge.
2026-06-27 15:30:30 +02:00
Ole André Vadla Ravnås 38e5198209 Move modules and threads into the sidebar
Drop the modules/threads tabs; show both as collapsible sidebar
groups mirroring the hooks UX: a handful of top picks plus a
browse popover for the rest. Default threads to collapsed.

Revert the eager re-analysis of persisted modules on attach; keep
disassembly analysis lazy and add a per-module Analyze action and
status indicator instead.

Share one sidebar-row and one browser-popover component across
hooks, modules, and threads in both the SwiftUI and GTK frontends.
2026-06-27 14:53:01 +02:00
Ole André Vadla Ravnås 2a281a133d Gate hosting on the driver seat when collaborative
Claim the driver seat when hosting a session, both on a fresh
spawn/attach and on re-host, wiring the previously unused claim-driver
op so the driver tracks the actual host.

Gate every spawn/attach/re-attach control on canTakeHosting: owner,
joined to the lab, and the seat free (not actively hosted by another).
Re-attach is now disabled while offline, since you can't hold the seat
then. Apply across both frontends — sidebar menus and detached
banners.
2026-06-26 15:34:02 +02:00
Ole André Vadla Ravnås 0b8f09d4d9 Hide arm action on non-arm-flow sessions 2026-05-21 00:23:58 +02:00
Ole André Vadla Ravnås dd71943d94 Allow naming address insights
Replace the auto-derived title with userTitle (nil = auto)
and a parentInsightID link. Display name is userTitle, else
<parent.title>+0x<delta>, else sub_<offset> if at a function
start, else module+offset. Sidebar context menu Rename… and
an LLM rename_insight tool both go through Engine.renameInsight,
which broadcasts via the existing updateInsight op and pushes
the new name into r2 as a flag (plus afn at function starts).

getOrCreateInsight kicks off a background pass that links a
new insight to its enclosing function-start insight, and
adopts siblings inside its region when the new insight is
itself the function start. The same adoption runs when a
fresh ModuleAnalysis newly reveals a function start under an
existing insight.
2026-05-19 16:01:25 +02:00
Ole André Vadla Ravnås 70dda51c70 core: Gate wire forwarding on remote node liveness 2026-05-17 01:49:17 +02:00
Ole André Vadla Ravnås 4b8b3ab570 core: Re-host on take-over from non-host owners 2026-05-17 00:21:20 +02:00
Ole André Vadla Ravnås 212323c748 ui: Hide host badge when host is local user 2026-05-17 00:21:20 +02:00
Ole André Vadla Ravnås cfc9f66b46 ui: Hide detach mark when hosted by others 2026-05-17 00:21:20 +02:00
Ole André Vadla Ravnås c39b4c639c ui: Replace hosted-by banner with sidebar avatar 2026-05-16 23:03:18 +02:00
Ole André Vadla Ravnås 274c023458 sidebar: Align child icons with parent icon end
Adopt Finder-style indentation: child icon starts where its
parent icon ends; spacings are 3/5/6 (leading, chevron-to-icon,
icon-to-label). Same rule cascades to grandchildren.

GTK: drop the 1px border on .luma-session-icon for an inset
shadow so the icon's allocation stays at 24.
2026-05-16 12:05:06 +02:00
Ole André Vadla Ravnås 619f42ccc9 ui: Add instrument status indicator popover
Replace the simple warning icon with a button that opens a
popover containing the headline, summary and diagnostic
stack (when present). Tracer hook rows reuse the same
indicator, driven by the per-component status map on the
node's InstrumentRef.
2026-05-16 12:04:54 +02:00
Ole André Vadla Ravnås 7c780f8c43 core: Replace incompatibility reason with status
Promote the runtime per-instrument flag from a bare reason
string to an InstrumentStatus enum so later kinds (load,
reload, compile failures) can share the surface. Behaviour
is unchanged: skipIfIncompatible sets .incompatible and the
sidebar still renders a single warning icon.
2026-05-16 02:51:01 +02:00
Ole André Vadla Ravnås b3176396ff ui: Show reattach badge on detached sidebar rows 2026-05-15 15:24:24 +02:00
Ole André Vadla Ravnås 54e798553c ui: Polish sidebar and editor chrome
Sidebar: manual expansion for sessions and custom instruments;
child rows align under parent icon column. Surface tracer hooks
inline under the Tracer item with a Browse-all popover for the
overflow.

Editor: drop static header rows; SaveBar slides down from the
editor top with Save button and unsaved indicator. Shared
between tracer and custom instrument editors.

GTK: pin detached banner to system-orange across focused and
backdrop states. Trim chevron button padding so it honors the
24px column, and tighten row padding so the icon sits 4px from
the row edge.
2026-05-13 22:58:47 +02:00
Ole André Vadla Ravnås d1606523b5 Support multi-file custom instruments
- Store source files as named CustomInstrumentFile rows per def
- Render sidebar with disclosure groups
- Drive editor via Monaco project models with activePath
- Validate Add/Rename/Delete dialogs and submit on Enter
- Fork installed hook packs into editable custom instruments
- Reload instances on def change; clear stale compat reasons live
- Focus editor on selection (native + Monaco)
2026-05-13 08:54:48 +02:00
Ole André Vadla Ravnås 14f4759a38 ui: Surface instrument compatibility
Pickers gray out mismatched descriptors with a tooltip and
disable the Add action. Sidebars badge instruments skipped at
restore time. Custom defs grow a Compatibility… popover with
canonical Frida values (macOS, x86_64, MIPS, …).
2026-05-12 15:05:31 +02:00
Ole André Vadla Ravnås 46bdce36f7 ui: Drop accent tint on sidebar row icons
Tinted icons disappeared into the accent-filled background
on selected rows. Letting them inherit the primary color
lets the sidebar invert them to white on selection.
2026-05-12 12:56:53 +02:00
Ole André Vadla Ravnås c5d2ff7050 core: Replace Workspace with per-document Engine
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.
2026-05-11 21:15:47 +02:00
Ole André Vadla Ravnås b52d37d604 Align sidebar row labels 2026-05-11 10:42:46 +02:00
Ole André Vadla Ravnås 26d687cecd Wire widgets through agent, UI, and collab
Engine owns the widget state cache, applies inbound updates from
the agent, persists session-scoped widgets, and broadcasts to
collaborating peers (action invocations route to the host).
Renderers in both UIs read the cache and the unified update
stream, with a Clear button that propagates to peers.

Agent SDK adds ctx.widget(id) with push/upsertItem/removeItem/
clear, plus a typed onAction handler. create() now takes a
restored snapshot seeded from persisted state and the join
snapshot.

Per-def .d.ts narrows the widget map, restored shape, and action
union to the exact ids declared in the editor.
2026-05-10 21:02:42 +02:00
Ole André Vadla Ravnås 029a403c71 Round-trip custom instruments as hookpacks
Hookpack manifest mirrors CustomInstrumentDef: rich features,
TypeScript entry, optional file-based icon. Folder name is the
pack id.

HookPackConfig holds FeatureState per feature, producing the
same agent-JSON shape as custom instruments. Hookpack sources
compile through the shared TypeScript pipeline.

Import sits next to "New Custom Instrument..."; Export on the
custom-instrument context menu. Both UIs.
2026-05-10 16:15:56 +02:00
Ole André Vadla Ravnås 5a13ca1eda ui: Render session icons from one source
Sidebar and phone session list both rendered from
node.processIcons when the session was attached and
session.iconPNGData otherwise, with the iconPNGData branch
in the sidebar carrying an extra accent-color overlay. That
fork made agent-created sessions look subtly off until the
node arrived. Drop the live branch, render only from
session.iconPNGData, and replace the inline icon-stash
copies with a new ProcessSession.adoptIcon helper that
performAttach keeps current.
2026-05-10 09:22:27 +02:00
Ole André Vadla Ravnås 178e2725cb ui: Hide arm menu for attach sessions
Arming is a spawn-only concept; the session context menu
should mirror the banner and skip "Arm for Next Launch" on
attach-kind rows.
2026-05-10 09:12:24 +02:00
Ole André Vadla Ravnås f005c84a08 agent: Label missions with an LLM-generated title
A new title column carries a short label generated in
parallel with mission start. Each LLMProviderDescriptor
declares a summarizationModelID so the pass runs on the
mission's own backend (Haiku for Anthropic and Claude
Code, gpt-5-mini for OpenAI, llama3.2:3b locally). The
instruction sits in the user message to dodge Claude
Code's prompt layering and asks for two to four punchy
words. Sidebar shows title or goal; header keeps the
full goal under the title.
2026-05-10 08:39:14 +02:00
Ole André Vadla Ravnås 5f6cb1b293 ui: Allow deleting missions from the sidebar
Right-click on a mission row exposes a Delete Mission
action behind a confirmation dialog so it follows the
same pattern as session, instrument, and trace deletion.
2026-05-09 22:27:31 +02:00
Ole André Vadla Ravnås d028a4193a agent: Pin MCP port; fix sidebar mission row
MCPServer.start tries a preferred port (persisted via the
TokenStore) before falling back to .any, so the URL stays
stable across launches. SidebarMissionRow swaps the Text
maxWidth frame for a trailing Spacer — matches the existing
session-row pattern and survives sidebar widening.
2026-05-09 15:04:05 +02:00
Ole André Vadla Ravnås b524221d07 ui: Fix mission UI glitches
NewMissionSheet drops the API-key prompt for providers that
don't need one. Action Queue header anchors top instead of
centring. Sidebar mission row truncates long goals.
2026-05-09 15:04:05 +02:00
Ole André Vadla Ravnås 5d0748515b mission: Add goal-driven agent loop
LLM agent for user-stated RE goals: propose-and-approve over the
existing RPC, evidence-grounded findings, collab via the op-outbox
pattern. Anthropic / OpenAI / local-OAI providers. r2ai used for
explain_function when the plugin is loaded; falls back to the
mission's own provider otherwise.
2026-05-09 12:54:14 +02:00
Ole André Vadla Ravnås 45481e1d2a swiftui: Wire spawn gating UI
Target picker grows a Wait for Launch mode with a popover-anchored
suggestions list. Sidebar context menu adds Arm/Disarm with a regex
prompt; armed sessions get a scope badge.

Detail banner picks among armed, idle, and detached states. The
armed banner offers Resume when gating is paused or failed and
Disarm otherwise.

EventStreamView renders spawn-gating events; raw payloads unwrap to
the inner message string instead of String(describing:) on the case
wrapper. REPL inactive message reflects armed/paused/detached.
2026-05-08 16:15:25 +02:00
Ole André Vadla Ravnås 5f892159b8 swiftui: Confirm before deleting a trace
Match the GTK behaviour: route the sidebar's Delete Trace
context menu through a confirmationDialog before calling
deleteITrace.
2026-05-07 18:49:33 +02:00
Ole André Vadla Ravnås 128b5980ff swiftui: Wire session detail and .luma directory
Sessions now have a top-level detail pane (Summary / Modules /
Threads) with master-detail panes for module symbols and thread
register snapshots. Sidebar gains a session row, and the ITrace
sidebar entries adopt the unified naming.

ITrace detail decodes the streaming trace data with first-paint
prefix, onProgress, and a Stop control restricted to thread
origins; the timeline paginates past 200 instructions.

The document is now a .luma directory wrapper containing
db.sqlite alongside a traces/ folder. Workspace owns the
ProjectUIState (selection, event-stream layout, collaboration
visibility) and a per-session SessionUIState (detail section,
last selected module/thread). MainWindowView reads/writes these
through Bindings instead of local @State.
2026-05-07 16:46:42 +02:00
Ole André Vadla Ravnås 5facbb71cf swiftui: Align custom instrument sidebar icon
Match the size and column width of built-in instrument
rows so the sidebar lines up.
2026-05-06 18:37:15 +02:00
Ole André Vadla Ravnås 8c82612579 Switch instrument icon to rich model 2026-05-06 00:05:01 +02:00
Ole André Vadla Ravnås 6ab2e3d3b2 macos: Add custom instrument UI 2026-05-05 19:15:56 +02:00
Ole André Vadla Ravnås 51c693a665 swiftui: Add accessibility identifiers for UI tests 2026-05-03 22:29:31 +02:00
Ole André Vadla Ravnås 9d02419562 Sync sessions across collaborative labs
Sessions in a lab are now collaborative artifacts. Any owner can
host (own the local Frida attachment) and any owner can drive
(issue REPL evals and instrument commands); a driver's actions
are relayed to the current host. Members watch read-only and see
an "Only lab owners can host sessions" CTA when they try the new
session button.

Re-host (Run on My Device…) lets an owner take over a running
session by attaching to their own equivalent process; the prior
host's Frida attachment detaches and the new host auto-loads the
session's instruments. Driver auto-reverts to host when the
current driver fully disconnects from the lab.
2026-04-30 23:28:15 +02:00
Ole André Vadla Ravnås a4abd75d0a placeholder: Generalize and use in target picker
The monogram placeholder wasn't really session-specific — the same
hue-from-seed + initials logic fits every target that has an
optional bundle icon. Rename `SessionPlaceholder` → `IconPlaceholder`
(data in LumaCore) and the two view wrappers to `IconPlaceholderView`
so the scope reads correctly, then wire the target picker's app and
process rows to fall back on it when no Frida-provided icon is
available. Seeds are app.identifier for applications and proc.name
for processes so repeat targets keep consistent colours.
2026-04-22 18:39:05 +02:00
Ole André Vadla Ravnås a7d6770606 sessions: Add hashed monogram placeholder icon
Sessions that lack a bundle icon all rendered the same generic
glyph, making rows hard to tell apart at a glance. Derive a stable
hue and monogram from the device ID and process name in LumaCore,
and pair each frontend with a native renderer — SwiftUI paints the
gradient + initials view, GTK draws the equivalent through Cairo
so the same session ends up the same colour across platforms.
2026-04-22 17:54:33 +02:00
Ole André Vadla Ravnås e577e1ca7e engine: Observe installed packages for sidebars
Both frontends showed stale sidebars after an install that
didn't come from the Manage Packages dialog — SwiftUI had a
dead @State placeholder that nobody assigned to, and GTK only
re-rendered when the search dialog invoked its own completion
callback. Installing from the tracer's inline Install button
skipped both paths entirely.

Add observeInstalledPackages to ProjectStore, wire the engine
to mirror it into Engine.installedPackages (an @Observable
array), and publish an onInstalledPackagesChanged callback.
SwiftUI reads the observable directly; the GTK window
subscribes to the callback and calls its existing
renderPackages helper.
2026-04-16 15:18:26 +02:00
Ole André Vadla Ravnås f122f5d775 swiftui: Wire sidebar to observable engine state
The sidebar fetched instruments, insights, and ITrace captures
directly from the SQLite store inside its body, so SwiftUI's
observation tracking never registered any dependency on them.
Adds, deletes, and updates went through the store and the
LumaGtk-side onSessionListChanged callback, but the SwiftUI host
had no way to know it should re-render. Items only appeared when
some unrelated observable change happened to trigger a body
re-evaluation.

Add ValueObservation-backed observers to ProjectStore for all
three collections, mirroring the existing observeSessions /
observeNotebookEntries pattern. Engine subscribes in start() and
exposes instrumentsBySession / insightsBySession / capturesBySession
as @Observable maps. SidebarView reads from these instead of
hitting the store directly, so changes propagate the moment GRDB
notices a row insert or delete.

LumaGtk's incremental sidebar continues to drive itself from
onSessionListChanged callbacks unchanged.
2026-04-11 09:43:32 +02:00
Ole André Vadla Ravnås 0e669be3dc Move the rest of business logic into LumaCore
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/.
2026-04-07 10:11:31 +02:00
Ole André Vadla Ravnås 8230ad9e4b Delete pointless Workspace delegates
Engine and ProcessNode are @Observable. Workspace
observes engine.processNodes via withObservationTracking
to sync VMs reactively. Views call workspace.engine.*
directly for spawn, attach, resume, instrument lifecycle,
insights, and tracer hooks. Engine instrument methods
take InstrumentInstance directly instead of split params.
2026-04-07 08:13:37 +02:00
Ole André Vadla Ravnås 4430492505 Move all business logic to Engine
Engine now handles the full instrument lifecycle (add,
remove, enable, config, load via RPC, dispose), tracer
instruction hook creation, session reestablishment,
and address-to-hook resolution. InstrumentDescriptor
is the UI-agnostic instrument metadata type.

Workspace is reduced to a thin SwiftUI shell: template
view factories, address decoration UI, ProcessNode VM
wrapping, and @Published state for observation.
2026-04-06 23:11:38 +02:00