aboutsummaryrefslogtreecommitdiffstats
path: root/.agents/skills
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-14 00:26:27 +0200
committeruser <user@clank>2026-08-14 00:26:27 +0200
commitbb5db57c72ac814cfb8019583e9cfd3c5fdea00e (patch)
tree48b83020f76630ab11ff74b0505971d857bbc325 /.agents/skills
parentPort to the ida-codemode 0.5.3+ public API (diff)
downloadida-tui-bb5db57c72ac814cfb8019583e9cfd3c5fdea00e.tar.gz
ida-tui-bb5db57c72ac814cfb8019583e9cfd3c5fdea00e.tar.xz
ida-tui-bb5db57c72ac814cfb8019583e9cfd3c5fdea00e.zip
Re-check the upstream findings report against 0.6.1
Items 4, 8 and 9 are fixed (loader switches on reopen, package exports, py.typed), so the report and the skill no longer claim 4-9 are all open. Item 7 is partial: DatabaseManager grew a DatabaseEventCallback, but there is still nothing an external caching client can observe, which was the point. 5 and 6 are untouched. The "are these files byte-identical" re-check recipe is removed: it named client.py/registry.py/resolver.py, which 0.5.x renamed, so it would have reported "unchanged" forever. The replacement is a diff of __all__ and the DatabaseOpenOptions fields, both of which the contract suite now asserts whenever the library is importable. Also records two things that cost time here: the loader-switch strip needs input_path != source, so an .i64 passed directly alongside load options still fatals; and an editable checkout does not enforce its own dependency floors, so a `git pull` to 0.6.1 leaves ida-domain/zeromcp silently too old.
Diffstat (limited to '.agents/skills')
-rw-r--r--.agents/skills/idatui/SKILL.md54
1 files changed, 37 insertions, 17 deletions
diff --git a/.agents/skills/idatui/SKILL.md b/.agents/skills/idatui/SKILL.md
index 336b31a..ba28e56 100644
--- a/.agents/skills/idatui/SKILL.md
+++ b/.agents/skills/idatui/SKILL.md
@@ -11,7 +11,7 @@ compatibility: "Backend is the ida-codemode LIBRARY (a normal dependency; see py
# idatui — IDA TUI frontend
A minimal, tasteful, keyboard-first (mouse-capable) TUI for IDA Pro, driving
-**IDA Code Mode** (`ida_codemode.client.DatabaseHandle`) — it takes a *lease* on a
+**IDA Code Mode** (`ida_codemode.DatabaseHandle`) — it takes a *lease* on a
database that is either an already-open IDA **GUI** session or a shared **managed
idalib worker**. idatui never owns or terminates an IDA process. Repo:
this repository. Built with **Textual**. This skill is the memory of how it
@@ -184,12 +184,32 @@ it fails with `ModuleNotFoundError: idatui`.
## IDA Code Mode gotchas
-- **`ida-codemode` is a normal dependency** (`pyproject.toml` pins `>=0.3.1`); these
- notes are current as of **0.3.2**. If you install it **editable from a git checkout**
- (handy for tracking upstream), remember that a `git pull` in that checkout swaps the
- backend under the TUI **immediately, with no reinstall** — convenient, but it means an
- upstream change can alter behaviour without anything in this repo changing. Run the
- full gate after any such pull.
+- **`ida-codemode` is a normal dependency** (`pyproject.toml` pins `>=0.5.3`, `uv.lock`
+ pins **0.6.1**); these notes are current as of **0.6.1**. If you install it **editable
+ from a git checkout** (handy for tracking upstream), remember that a `git pull` in that
+ checkout swaps the backend under the TUI **immediately, with no reinstall** —
+ convenient, but it means an upstream change can alter behaviour without anything in
+ this repo changing. Run the full gate after any such pull. A version bump can also move
+ the checkout's *dependency floors* without touching its code: 0.6.1 needs
+ `ida-domain>=0.5.1` and `zeromcp>=1.8.0`, and an editable install does not enforce
+ them — run `pip check` in `~/ida-venv` after a pull, or the failure surfaces much later
+ and much less legibly.
+- **We import from the package ROOT, never from submodules.** 0.5.x made
+ `ida_codemode.__all__` the public API and hid the rest behind underscores
+ (`client.py` → `handle.py`, `registry.py` → `_registry.py` + `instances.py`,
+ `resolver.py` → `_resolver.py`). Anything importing `ida_codemode.client`,
+ `.registry` or `.resolver` is pre-0.5 and stale. Loader options are a frozen
+ `DatabaseOpenOptions` dataclass passed as `open(path, options=...)`, ownership
+ questions are `find_database_owner()`, and lock-release waiting is
+ `wait_database_released()` — we no longer poke `FileLock`/`REGISTRY_DIR` ourselves.
+- **`codemode_client.py` binds every Code Mode name to `None` when the library is
+ absent**, so the pure suites run under stdlib `python3`. That makes `except
+ SomeCodeModeError:` a landmine: `except None` raises `TypeError: catching classes that
+ do not inherit from BaseException`, but ONLY if something inside the `try` actually
+ raises — so it hides until the day another line in that block fails. If you add a call
+ to a Code Mode symbol inside a `try`, make `tests/test_codemode_client.py` inject a
+ fake for it too (it fakes `DatabaseHandle`, `DatabaseOpenOptions` and
+ `DatabaseBusyError` for exactly this reason).
- **Two big client-side workarounds existed and are now DELETED, because 0.3.2 fixed
them upstream.** Don't re-add them, and don't trust older docs that describe them:
- the runtime used to wrap every `execute_python` in `sys.settrace(timeout_trace)`,
@@ -202,16 +222,16 @@ it fails with `ModuleNotFoundError: idatui`.
(compact separators, `default=str`) — no longer load-bearing for performance.
- Re-measure both with `PYTHONPATH=. ~/ida-venv/bin/python experiments/bench_pack_trace.py`.
- **`docs/CODEMODE_UPSTREAM.md` is our findings report to the ida-codemode maintainers,
- and every item is re-checked against 0.3.2.** Items **1, 2 and 3 are FIXED** (trace
- hook, to_jsonable, the execute_sync floor). Items **4–9 are still open** — loader
- switches fatal on reopen, replaced IDB under a live lease, no close-without-save, no
- change notification, package exports, no `py.typed`/handle Protocol — and they are
- open *by construction*: `client.py`, `registry.py`, `resolver.py`, `server.py`,
- `database.py` and `worker.py` are byte-identical between 0.3.1 and 0.3.2, and those
- items all live in those files. Read it before assuming a Code Mode behaviour is a bug
- in our code. **Cheap way to re-check after any upstream pull:**
- `for f in client registry resolver server database worker; do git diff --quiet OLD..HEAD -- ida_codemode/$f.py; done`
- — if they're all unchanged, items 4–9 cannot have moved.
+ and every item is re-checked against 0.6.1.** Items **1, 2, 3 are FIXED** (trace hook,
+ to_jsonable, the execute_sync floor) and so are **4, 8, 9** (loader switches on reopen,
+ package exports, `py.typed`). Still open: **5** replaced IDB under a live lease, **6**
+ no close-without-save, **7** no change notification (0.6.1 has a
+ `DatabaseEventCallback` on `DatabaseManager`, but nothing an external caching client
+ can observe). Read it before assuming a Code Mode behaviour is a bug in our code.
+ The old "are these files byte-identical" re-check recipe is DEAD — those files were
+ renamed in 0.5.x. Re-check by diffing `ida_codemode/__all__` and the
+ `DatabaseOpenOptions` fields instead; `tests/test_codemode_client.py` asserts both
+ automatically whenever the library is importable.
- **The old ~2ms per-operation floor is GONE in 0.3.2 (7.0x).** Same-box A/B:
`execute_python("result = 1")` was **2.055ms** on 0.3.1 and is **0.294ms** on 0.3.2,
about the cost of a bare HTTP GET — the `execute_sync` marshalling that was ~93% of