From a03a1e08f65806f8963eeffc5f65c28af40bc949 Mon Sep 17 00:00:00 2001 From: blasty Date: Fri, 10 Jul 2026 16:21:36 +0200 Subject: drive: add save + retype; point docs/skills at the ergonomic frontend Round out idatui.drive with 'save' and 'retype ' so the whole common RE loop (orient/understand/act/persist) has a terse command. Update docs/RPC.md and both skills (idatui, idatui-rpc) to recommend idatui.drive as the day-to-day driving surface, with rpcclient/raw as the fallback for unwrapped verbs. --- docs/RPC.md | 11 +++++++++-- idatui/drive.py | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/RPC.md b/docs/RPC.md index a4d077f..5cb73ee 100644 --- a/docs/RPC.md +++ b/docs/RPC.md @@ -7,7 +7,10 @@ identical on-screen effect a real keyboard would. Layers: `idatui/rpc.py` (server, above `app.py`), `idatui/_sync.py` (the shared "wait until the UI settled" logic, also used by the tests), `idatui/rpcclient.py` -(stdlib client + CLI). +(stdlib raw JSON client + CLI), and `idatui/drive.py` (the **ergonomic** CLI on +top — terse text, auto-resolves the socket). For agent-driven RE, prefer +`idatui.pane` (spawn/stop panes) + `idatui.drive` (see the `idatui-rpc` skill); +this doc is the underlying protocol reference. ## Running @@ -15,7 +18,11 @@ Layers: `idatui/rpc.py` (server, above `app.py`), `idatui/_sync.py` (the shared # pane A — the TUI (real render) + a socket listener python -m idatui.tui --db --rpc /tmp/ida.sock -# pane B — drive it +# pane B — drive it. Ergonomic (auto-finds the socket, terse text): +python -m idatui.drive where +python -m idatui.drive pc main strrchr +python -m idatui.drive rename sub_5BE0 stdout_isatty +# ...or the raw JSON transport underneath: python -m idatui.rpcclient --sock /tmp/ida.sock goto target=main python -m idatui.rpcclient --sock /tmp/ida.sock screen ``` diff --git a/idatui/drive.py b/idatui/drive.py index 5a36add..35909df 100644 --- a/idatui/drive.py +++ b/idatui/drive.py @@ -167,6 +167,19 @@ def cmd_note(c, args): return f" noted {args[0]}" +def cmd_retype(c, args): + if len(args) < 2: + raise SystemExit("usage: retype ") + c.call("goto", target=args[0], delay_ms=0) + st = c.call("retype", proto=" ".join(args[1:]), word=args[0], delay_ms=0) + return _fmt_where(st) + + +def cmd_save(c, args): + c.call("save") + return " saved" + + def cmd_screen(c, args): return c.call("screen").get("text", "") @@ -184,8 +197,8 @@ def cmd_raw(c, args): COMMANDS = { "where": cmd_where, "go": cmd_go, "pc": cmd_pc, "dis": cmd_dis, "callees": cmd_callees, "callers": cmd_callers, "names": cmd_names, - "rename": cmd_rename, "mv": cmd_mv, "note": cmd_note, - "screen": cmd_screen, "raw": cmd_raw, + "rename": cmd_rename, "mv": cmd_mv, "note": cmd_note, "retype": cmd_retype, + "save": cmd_save, "screen": cmd_screen, "raw": cmd_raw, } -- cgit v1.3.1-sl0p