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.
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.
Snapshot the r2 seek after each r2 eval, storing it on
SessionUIState as an AddressAnchor so it re-bases across runs.
Resolve and restore it during the session warm-up, which now
also runs when only a seek (no analysis) was saved.
Carry a display/insert split through completion so command
suggestions show r2's help text via the native secondary title,
and complete command arguments against eval vars and flagspaces
in addition to flags. Recall the language alongside the code when
cycling history, and keep r2 output's leading whitespace intact.
Persist the REPL draft and active language per session in
SessionUIState so they survive reopening the project. Defer the
input field's first-responder change out of the view update.
requestAIReply runs against an ambient mission per session,
billing token usage and recording the call as a MissionAction
so the user can review the chain in the mission view. System
prompt seeds the model with disasm + pdc around the anchor.
- 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)
Engine subscribes to module/thread deltas and trace updates, drives
the unified ITrace lifecycle, paginates set-trace-data uploads with
lazy server-stat resume, and falls back to a paginated +fetch with
optional first-paint prefix and onProgress reporting. Server-driven
trace-data-progressed broadcasts feed back as cache invalidations.
ProjectStore picks up itrace, project_ui_state and session_ui_state
tables; the schema is created with if-not-exists, no migrations.
SessionOp carries upsertTrace, removeTrace, traceDataProgressed,
and the module/thread updates are now ModuleDelta/ThreadDelta.