<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ida-tui.git/idatui, branch main</title>
<subtitle>tui for headless ida</subtitle>
<id>https://git.sl0p.foo/ida-tui.git/atom/idatui?h=main</id>
<link rel='self' href='https://git.sl0p.foo/ida-tui.git/atom/idatui?h=main'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/'/>
<updated>2026-07-11T20:58:52Z</updated>
<entry>
<title>disasm: render opcode bytes (toggle 'o'), padded to widest insn</title>
<updated>2026-07-11T20:58:52Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-11T20:58:52Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=17b8c95b948d4fe2d38cac4f80ffa8fb0a750d4f'/>
<id>urn:sha1:17b8c95b948d4fe2d38cac4f80ffa8fb0a750d4f</id>
<content type='text'>
Fetch per-instruction opcode bytes alongside the disasm listing and show
them in a column between the address and the mnemonic. Instruction length
comes from consecutive addresses (variable-length safe: x86 movabs shows
its full 10 bytes); the block over-fetches one instruction for the last
line's boundary, falling back to the function end for the final insn.

The column pads to the widest instruction across the whole function:
_fetch_block tracks a running max, and on load a background scan_bytes()
settles a stable width so padding doesn't jump as blocks stream in.
_op_field is shared by the rendered strip, _line_plain, and search _fmt
so cursor/match offsets stay aligned. 'o' toggles the column.
</content>
</entry>
<entry>
<title>drive: make `dis` drive the live UI too (generalize _show_decomp -&gt; _show_view)</title>
<updated>2026-07-11T19:09:45Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-11T19:09:45Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=b55e5529fb96e0cfa5769d1af4e89350c8c255ce'/>
<id>urn:sha1:b55e5529fb96e0cfa5769d1af4e89350c8c255ce</id>
<content type='text'>
</content>
</entry>
<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>drive pc: render pseudocode in the TUI, not just the driver</title>
<updated>2026-07-11T08:09:03Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-11T08:09:03Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=156168cb42237884edd39af15bc80138c9443910'/>
<id>urn:sha1:156168cb42237884edd39af15bc80138c9443910</id>
<content type='text'>
The pc command called only the read-only pseudocode RPC (runs off the UI
loop, never touches the screen), so LLM-driven sessions showed nothing on
the live pane. Compose goto + toggle_view + search so the real TUI
navigates to the function, makes the decomp pane the visibly-active view,
and jumps the cursor to the needle — then return the same text as before.
</content>
</entry>
<entry>
<title>app: multi-line comments via literal \\n (long notes were clipping)</title>
<updated>2026-07-10T14:43:32Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T14:43:32Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=7ae37ba3b432bbb2482df9c99864350e685b0241'/>
<id>urn:sha1:7ae37ba3b432bbb2482df9c99864350e685b0241</id>
<content type='text'>
The comment prompt is single-line, so a long note rendered as one giant
'//' line that ran off the right edge and got clipped. Interpret a literal
'\\n' (backslash-n) in the comment text as a real newline in _do_comment
(the single choke point for the ';' prompt and the RPC 'comment' verb) —
Hex-Rays renders each as its own '//' line. Verified live and locked in
the comment_func scenario (multi-line render); suite 104 green.
</content>
</entry>
<entry>
<title>drive: add save + retype; point docs/skills at the ergonomic frontend</title>
<updated>2026-07-10T14:21:36Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T14:21:36Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=a03a1e08f65806f8963eeffc5f65c28af40bc949'/>
<id>urn:sha1:a03a1e08f65806f8963eeffc5f65c28af40bc949</id>
<content type='text'>
Round out idatui.drive with 'save' and 'retype &lt;fn&gt; &lt;proto&gt;' 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.
</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: comment on a no-address line -&gt; function comment (was refused)</title>
<updated>2026-07-10T14:12:22Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T14:12:22Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=3b4e397f48e4519c6b5a24fede2e41707e355a92'/>
<id>urn:sha1:3b4e397f48e4519c6b5a24fede2e41707e355a92</id>
<content type='text'>
Pressing ';' on the decompiler's signature or local-declaration lines did
nothing ('no address on this line to comment') because those lines carry
no /*0xEA*/ marker. Fall back to the current function's entry ea so
commenting the header annotates the function itself; the prompt says
'function comment @ ...'. Body-line comments are unchanged.

New scenario comment_func locks it (suite 104 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>pane: auto-start the ida-pro-mcp supervisor if it's down</title>
<updated>2026-07-10T13:50:30Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T13:50:30Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=23a63681a61c2b522576d77dfd140f2174273a95'/>
<id>urn:sha1:23a63681a61c2b522576d77dfd140f2174273a95</id>
<content type='text'>
Before creating the TUI pane, spawn probes 127.0.0.1:8745 and, if nothing
is listening, launches ./spawn.sh in its own detached tmux pane and waits
for the port (server_started/server_pane are reported in the JSON). Only
for a local server, never a duplicate (spawn.sh binds the port), and it's
not killed on 'stop' (shared across TUIs). --no-ensure-server opts out;
IDATUI_SERVER_CMD overrides the launch command (used by the test).

tests/pane_smoke.py exercises the machinery with a dummy port-binder in a
pane (start / detect / idempotent / remote-guard), 5 green.
</content>
</entry>
</feed>
