<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ida-tui.git/idatui/rpc.py, branch main</title>
<subtitle>tui for headless ida</subtitle>
<id>https://git.sl0p.foo/ida-tui.git/atom/idatui/rpc.py?h=main</id>
<link rel='self' href='https://git.sl0p.foo/ida-tui.git/atom/idatui/rpc.py?h=main'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/'/>
<updated>2026-07-11T08:59:48Z</updated>
<entry>
<title>fix: don't hang drive pc on undecompilable functions</title>
<updated>2026-07-11T08:59:48Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-11T08:59:48Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=2c86330705569805c5d201113a569c9e03c0214a'/>
<id>urn:sha1:2c86330705569805c5d201113a569c9e03c0214a</id>
<content type='text'>
toggle_view's settle predicate (lambda: app._active != before) never
fired when tabbing toward pseudocode on a function Hex-Rays can't
decompile: App._apply_decomp snaps the view back to disasm, so _active
returns to its prior value -&gt; full 20s settle timeout (x2 in _show_decomp,
~40s for drive pc). Recognize the decomp-failed fallback as settled.

Also harden two amplifiers surfaced by the same case:
- rpcclient: the CLI socket had no read timeout and would block forever
  on any server slowness; add a bounded settimeout (IDATUI_RPC_TIMEOUT,
  default 90s) with a clear error.
- domain.decompile: pass a bounded 15s timeout and cache failures, so a
  failing decompile can't sit at the 30s client default or be re-run by
  transport retries.
</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>
