<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ida-tui.git/tests/rpc_smoke.py, branch pre-codemode</title>
<subtitle>tui for headless ida</subtitle>
<id>https://git.sl0p.foo/ida-tui.git/atom/tests/rpc_smoke.py?h=pre-codemode</id>
<link rel='self' href='https://git.sl0p.foo/ida-tui.git/atom/tests/rpc_smoke.py?h=pre-codemode'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/'/>
<updated>2026-07-24T12:53:56Z</updated>
<entry>
<title>mcp: delete the ida-pro-mcp transport, supervisor, and mcp-only tests</title>
<updated>2026-07-24T12:53:56Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-24T12:53:56Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=22ffea91210610d1def042e230ffe8d223022b30'/>
<id>urn:sha1:22ffea91210610d1def042e230ffe8d223022b30</id>
<content type='text'>
The idalib worker is the only backend now, so remove the dead HTTP/supervisor
surface entirely (~2200 lines):

* deleted idatui/client.py (the IDAClient HTTP/JSON-RPC transport + session
  manager), idatui/tui.py (the old mcp TUI entry, superseded by launch.py),
  spawn.sh, and systemd/ (the supervisor unit).
* deleted the mcp-only tests (stress_client, smoke_client, test_keepalive,
  stress_paging, rpc_smoke, serverctl.sh, pane_smoke, test_domain) -- the worker
  pilot (tests/test_scenarios.py) supersedes them.
* migrated the tmux RPC harness (idatui/pane.py) to the worker: it spawns
  `idatui.launch &lt;binary&gt; --rpc &lt;sock&gt;` instead of the mcp `idatui.tui`, drops
  the supervisor auto-start/ensure machinery, and reaps our own worker
  (idatui/worker.py) instead of ida_pro_mcp.idalib_server. --db/--url/--no-
  ensure-server are gone; --open is required.
* __init__ / __main__ / domain no longer import client (exceptions come from
  errors.py, the domain client hint is WorkerClient); pyproject points both
  console scripts at idatui.launch; README + ida-tui header describe the
  worker-only flow.

What stays (by design): the ida_pro_mcp *package* (the worker reuses its @tool
functions in-process) and server/patch_server.py (the worker injects its custom
tools on startup). Verified: whole package imports + IdaTui constructs + pilot
lists 31 scenarios. The worker pilot (134 pass / 2 known flakes) is the E2E gate.
</content>
</entry>
<entry>
<title>drive: ergonomic RE helper over the RPC socket (terse text, auto socket)</title>
<updated>2026-07-10T14:17:50Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T14:17:50Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=33bd85e41221a82a8ee7b71d39eda59d89b78ee7'/>
<id>urn:sha1:33bd85e41221a82a8ee7b71d39eda59d89b78ee7</id>
<content type='text'>
Driving via rpcclient meant re-exporting the socket every fresh shell,
long invocations, and piping ~every call through python -c to pull one
field or grep pseudocode. idatui.drive fixes that: it auto-resolves the
socket (the single live pane from the registry), prints compact text
instead of JSON, and bundles the common gestures:

  where | go | pc &lt;fn&gt; [substr] | dis &lt;fn&gt; [n] | callees/callers &lt;fn&gt; |
  names &lt;substr&gt; | rename &lt;old&gt; &lt;new&gt; | mv old=new... | note &lt;fn&gt; &lt;text&gt; |
  screen | raw &lt;method&gt; k=v

So 'goto+rename+parse' becomes 'drive rename old new', and 'pseudocode |
python -c grep' becomes 'drive pc fn needle'. rpcclient stays the raw
transport. rpc_smoke drives it end-to-end (29 green).
</content>
</entry>
<entry>
<title>app: drop the Header (keep the Footer); rpc: function-scope xrefs_from</title>
<updated>2026-07-10T14:01:54Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T14:01:54Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=ead2125f041649024ede36d0b4eb8e4c4c466e32'/>
<id>urn:sha1:ead2125f041649024ede36d0b4eb8e4c4c466e32</id>
<content type='text'>
The clock/title Header added noise (and made screen() non-deterministic);
remove it from the app itself — the Footer stays. Layout shifts up a row;
scenario suite still 101 green.

xrefs_from on a function was near-useless: the server's xrefs_from is
address-scoped, so passing the entry ea only returned the fall-through
from the first instruction. For a function target it now returns
whole-body references from the decompiler (callees + string/data refs:
{to,name,string,is_func,type}); an explicit 0xADDR stays address-scoped.
Verified live: xrefs_from main now lists setlocale/getopt_long/sub_* etc.
rpc_smoke: 25 green.
</content>
</entry>
<entry>
<title>rpc: cursor_on + word= edits, single-driver gate, colored screen</title>
<updated>2026-07-10T13:45:51Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T13:45:51Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=b90ae8d52623e9a59d6f5ee68ff2f96537bf965d'/>
<id>urn:sha1:b90ae8d52623e9a59d6f5ee68ff2f96537bf965d</id>
<content type='text'>
cursor_on {word,line?,occurrence?} places the cursor on a token, verified
with the app's own tokenizer (so 'main' won't match inside 'domain');
rename/retype/follow gain an optional word= that runs it first — the
ergonomic way to edit a named symbol without a manual view+cursor dance.

Single-driver gate: the socket now serves one client at a time; a second
concurrent connection is refused with 'busy' (no multi-driver support yet,
by request). Sequential connections are unaffected.

screen gains format=text|html|svg (html/svg are colored — for an
out-of-band web viewer). rpc_smoke: 24 green.
</content>
</entry>
<entry>
<title>rpc: readiness, quit, methods discovery, not-ready guard</title>
<updated>2026-07-10T13:35:21Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T13:35:21Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=0531f0e1787061aff06b01981d0e72d3718e3637'/>
<id>urn:sha1:0531f0e1787061aff06b01981d0e72d3718e3637</id>
<content type='text'>
Spawn-and-drive needs to know when the freshly-launched TUI is usable:
ping/state now carry {ready,functions,complete} (cheap; no health call)
and ping adds the module name. Add a graceful 'quit' verb (acks, then
exits on a short delay so the reply still flushes) and a self-documenting
'methods' table. Program-dependent verbs are refused with a clear
'not ready' instead of exploding in a worker while still loading.

rpc_smoke covers readiness, methods and quit (21 green).
</content>
</entry>
<entry>
<title>rpc: more verbs — structured reads, modal select, in-view search, save</title>
<updated>2026-07-10T13:29:21Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T13:29:21Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=9583334d0d413d8f4962b5d8fa1eccdbc196dd33'/>
<id>urn:sha1:9583334d0d413d8f4962b5d8fa1eccdbc196dd33</id>
<content type='text'>
Introspection (offloaded to a thread so a big fetch can't freeze the
render): pseudocode (full body), disassembly (bounded), xrefs_to/from
(structured), resolve (name-&gt;ea). These let an agent reason about a
function and the call graph without scraping screen().

Semantic: select (choose the highlighted/nth item in the open xrefs or
symbol-palette list and activate it — the natural follow-up to xrefs/
symbols), search (/ or ? incremental in the active code view), save
(Ctrl+S). rpc_smoke exercises all of them end-to-end (18 green).
</content>
</entry>
<entry>
<title>rpc: semantic verbs (typed-with-delay ops + fast movement)</title>
<updated>2026-07-10T13:14:49Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T13:14:49Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=85c717ac6aa7e6a2559c1ffb8e4e4f344419a667'/>
<id>urn:sha1:85c717ac6aa7e6a2559c1ffb8e4e4f344419a667</id>
<content type='text'>
Layer high-level verbs over the raw injection: goto/open, rename, comment,
retype, follow, back, toggle_view, hex, xrefs, symbols, structs, close,
plus fast move/cursor. Editing/goto verbs type through the real prompts
with a per-char delay (default 35ms) so viewers see it typed; movement
uses bare keypresses with a pump-only settle to stay snappy. Each verb
settles on an op-specific predicate where one exists (goto lands on the
target, follow grows the nav stack, toggle flips _active, modals open),
so the returned state is never stale.

rpc_smoke now drives the semantic path end-to-end (rename round-trip via
the prompt-fill seam), 11 green.
</content>
</entry>
<entry>
<title>rpc: unix-socket puppeteering server (raw keys + introspection + screen)</title>
<updated>2026-07-10T13:10:25Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T13:10:25Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=690a34512eaed933917f2d2c1cf12327923b39ac'/>
<id>urn:sha1:690a34512eaed933917f2d2c1cf12327923b39ac</id>
<content type='text'>
Run the TUI with --rpc &lt;sock&gt; and it renders normally while an asyncio
listener on the same loop lets another process drive it. Handlers touch
the UI directly (same loop, no thread hop), so every injected key has the
identical on-screen effect a keyboard would — the point for livestreaming.

Newline-delimited JSON. v1 methods: keys/text (raw injection, via the same
_press_keys the pilot uses; text can interleave wait:&lt;ms&gt; for a typed-out
look), state/view/screen/functions (introspection; screen() is a full
plain-text render of exactly what the viewer sees). No auth by design —
the socket is 0600, local only.

tests/rpc_smoke.py drives it end-to-end over a real socket (7 green).
</content>
</entry>
</feed>
