From f4cb6eba274c411c503cbc8b4ed10fdfc6b70dcb Mon Sep 17 00:00:00 2001 From: blasty Date: Sat, 25 Jul 2026 11:51:38 +0200 Subject: projects: switch between a project's binaries in the TUI (phase 1c) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires the project model + worker pool into the app. Project mode is ADDITIVE — without --project the app is exactly the single-binary tool it was, which is what keeps the 167-check pilot meaningful. * IdaTui(project=...) builds a WorkerPool and opens the project's first binary; _open_worker_client asks the pool instead of spawning directly. * BinaryState snapshots what a switch leaves behind (program, func_index, nav, cur, view prefs, filter). Switching reuses the _after_reconnect shape: swap client+program, rebuild the index, reopen the entry. A still-resident binary restores instantly (Program + index are in memory); an evicted one gets a fresh worker but keeps its nav history, which is just addresses. * ProjectPalette (Ctrl+O, + a "Switch binary…" palette command): the project's binaries with resident/analysed/pinned/active state and memory, filterable. * launch.py --project FILE, creating the project when binaries are also given; stages everything up front so the source tree is never written to. Two bugs found while testing: * _did_auto_land is app-wide, but landing is per-binary: after the first binary landed, a cold switch never landed at all AND left the switch overlay up forever. Reset it per switch. * PRE-EXISTING: the status Static had Textual markup enabled, so a single-word bracket marker parses as a style tag and is silently eaten — [listing] and [pseudocode] have never actually rendered (only [split · listing] survived, because the · makes it an invalid tag). Status is plain text with brackets and symbol names, so markup=False. tests/test_project_ui.py: end-to-end pilot on two real binaries (18 checks) — boot, switcher contents, switch, per-binary index, both workers resident, switch back with state intact, return-to-where-you-were, and the promise that the source tree stays pristine while every artifact lands in the sidecar. Full single-binary suite unchanged at 167/2 (the standing flakes). --- docs/PROJECTS.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'docs/PROJECTS.md') diff --git a/docs/PROJECTS.md b/docs/PROJECTS.md index d1e2806..1f39c05 100644 --- a/docs/PROJECTS.md +++ b/docs/PROJECTS.md @@ -108,10 +108,19 @@ basename and must be unique (it names the staged file). ## Phases -**Phase 1 — project model + switching.** Project file, staging dir, -`WorkerPool` (lazy spawn, budget eviction, save-on-evict, clean shutdown), -`BinaryState` save/restore, switcher palette, active binary in the status bar, -`--project` CLI. One active binary; no cross-binary search yet. +**Phase 1 — project model + switching. DONE.** Project file + staging +(`idatui/project.py`), `WorkerPool` with budget eviction / save-on-evict / +clean shutdown (`idatui/pool.py`), `BinaryState` snapshot+restore and the switch +itself, the `Ctrl+O` switcher palette, the active binary in the status line, and +`--project` (which creates the project when given binaries). One active binary; +no cross-binary search yet. + +Project mode is **additive**: with no `--project` the app is byte-for-byte the +single-binary tool it was, which is what keeps the 167-check pilot honest. +Switching reuses the `_after_reconnect` shape — swap client+program, rebuild the +index, reopen the entry. A binary whose worker is still resident restores +instantly (its `Program` and index are still in memory); an evicted one comes +back with a fresh worker but keeps its nav history, since that is just addresses. **Phase 2 — index cache + project-wide search.** Per-binary index (functions, strings) persisted after first open, keyed by source size+mtime. Scope toggle in -- cgit v1.3.1-sl0p