ida-code 0.2.1__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {ida_code-0.2.1 → ida_code-0.2.3}/CHANGELOG.md +36 -1
  2. {ida_code-0.2.1 → ida_code-0.2.3}/PKG-INFO +8 -4
  3. {ida_code-0.2.1 → ida_code-0.2.3}/README.md +6 -2
  4. {ida_code-0.2.1 → ida_code-0.2.3}/pyproject.toml +2 -2
  5. ida_code-0.2.3/src/ida_code/code_search.py +800 -0
  6. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/config.py +2 -0
  7. ida_code-0.2.3/src/ida_code/doc_search.py +168 -0
  8. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/executor.py +8 -31
  9. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/guidelines.py +94 -0
  10. ida_code-0.2.3/src/ida_code/ida_thread.py +92 -0
  11. ida_code-0.2.3/src/ida_code/server.py +1138 -0
  12. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/session.py +163 -48
  13. ida_code-0.2.3/tests/test_code_search.py +556 -0
  14. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_doc_search.py +16 -33
  15. ida_code-0.2.3/tests/test_e2e.py +141 -0
  16. ida_code-0.2.3/tests/test_executor.py +116 -0
  17. ida_code-0.2.3/tests/test_ida_thread.py +90 -0
  18. ida_code-0.2.3/tests/test_session.py +129 -0
  19. ida_code-0.2.1/src/ida_code/doc_search.py +0 -255
  20. ida_code-0.2.1/src/ida_code/example_search.py +0 -570
  21. ida_code-0.2.1/src/ida_code/server.py +0 -1011
  22. ida_code-0.2.1/tests/test_example_search.py +0 -304
  23. ida_code-0.2.1/tests/test_executor.py +0 -153
  24. ida_code-0.2.1/tests/test_session.py +0 -59
  25. {ida_code-0.2.1 → ida_code-0.2.3}/.gitignore +0 -0
  26. {ida_code-0.2.1 → ida_code-0.2.3}/LICENSE +0 -0
  27. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/__init__.py +0 -0
  28. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/_search_utils.py +0 -0
  29. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/comments.py +0 -0
  30. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/macho.py +0 -0
  31. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/prompts.py +0 -0
  32. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/snapshots.py +0 -0
  33. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/structures.py +0 -0
  34. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/undo.py +0 -0
  35. {ida_code-0.2.1 → ida_code-0.2.3}/src/ida_code/variables.py +0 -0
  36. {ida_code-0.2.1 → ida_code-0.2.3}/tests/__init__.py +0 -0
  37. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_comments.py +0 -0
  38. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_macho.py +0 -0
  39. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_search_utils.py +0 -0
  40. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_structures.py +0 -0
  41. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_undo.py +0 -0
  42. {ida_code-0.2.1 → ida_code-0.2.3}/tests/test_variables.py +0 -0
@@ -4,7 +4,42 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
- ## [Unreleased]
7
+ ## [0.2.3] - 2026-05-10
8
+
9
+ ### Added
10
+
11
+ - **Dedicated ida-thread** — new `src/ida_code/ida_thread.py`: a single daemon worker thread that owns idalib. Submit work via `submit()` (sync) or `await on_ida_thread()` (async). idalib hangs when called from any thread other than the one that imported `idapro`; pinning all idalib calls to one thread we control unblocks fastmcp v3 compatibility.
12
+ - **`get_source` tool** — companion to `search_code`. When a search result is truncated (`snippet_start_line` + `total_lines` set), the LLM fetches more lines via `get_source(file, start_line, line_count)`. Sandboxed to the indexed corpora (`python/`, `python/examples/`, `idalib/python/`, `idalib/examples/`); paths outside those roots can't be read.
13
+
14
+ ### Changed
15
+
16
+ - **fastmcp pin lifted to `>=2.0,<4`** — the ida-thread refactor lets v3 work as well as v2. Verified end-to-end on v3.2.4 with both stdio and in-process transports: `open_database` + `list_functions` + `close_database` complete in <1s on a warm `.i64` cache.
17
+ - **All idalib-touching tools are now `async def`** — every `@mcp.tool` that touches idalib (28 tools) dispatches its body via `await on_ida_thread(_impl, ...)`. The 3 non-idalib tools (`list_architectures`, `search_docs`, `search_code`) stay plain sync `def`. Keeps the asyncio event loop free during idalib work and is transport-agnostic across fastmcp v2 / v3.
18
+ - **`session.py` lazy idapro import** — `import idapro` moved off module top into `_ensure_idalib_loaded()` which runs on the ida-thread on first use. A targeted `signal.signal` monkey-patch silences the `SIGINT, SIG_DFL` install in `idapro/__init__.py:179` that raises `ValueError` on non-main threads (other signal calls pass through). `session.idapro` is the module-level handle, replacing the prior import.
19
+ - **Guidelines refresh** — each `guidelines://` resource now carries (a) Hex-Rays' own IDAPython conventions extracted from `python/examples/README.md` (avoid `idc.py` / `idaapi` / `from X import Y` re-exports; double-quote strings; example docstring header), (b) a "Discovering APIs and examples" footer pointing at `search_docs` / `search_code` / `get_source` so callers know the chain. The standalone-script guideline additionally references the `py-activate-idalib.py` setup path from `idalib/README.txt` for users who'd rather `pip install` than bootstrap manually.
20
+
21
+ ### Changed (BREAKING)
22
+
23
+ - **`search_examples` → `search_code`** — unified Python-source search that indexes library APIs (formerly under `search_docs`) plus example scripts. New corpora included in the index: the `idapro` Python package (`idalib/python/idapro/*.py`) so signatures like `open_database(file_path, run_auto)` surface from the actual Python wrapper, and `idalib/examples/` so the canonical standalone-idalib example (`idacli.py`) is findable. Adds `kind` filter (`""|"library"|"example"`), `imports` filter (e.g. `imports="idapro"` finds standalone-idalib scripts), `docstring_only: bool` flag to restrict scoring to docstring text for semantic queries, and `include_docs: bool = True` for a `related_docs` cross-link to HTML docs. Library entries weight docstrings at 3x (between name 5x and body 1x) so docstring matches outrank coincidental code-comment matches. Snippet shaping: `max_snippet_lines` caps height, `max_snippet_line_chars` (default 200) truncates each line with `...`, and when a snippet doesn't cover the full source the result includes `snippet_start_line` (1-based, file-absolute) plus `total_lines` so a follow-up read can fetch the rest at the right offset. Result objects are tuned for token efficiency: `score` and `apis` are never emitted, empty fields (level/category/summary/imports) are dropped, `title` is dropped when it equals the filename, and `kind` is dropped when the caller filtered to one. `search_docs` is now HTML-only; its `include_examples` cross-link goes through `search_code(kind="example")` internally.
24
+
25
+ ### Removed
26
+
27
+ - **`execute` / `execute_file` `timeout` parameter** — the prior implementation used `signal.SIGALRM`, which only delivers to the process main thread. With user code now running on the ida-thread there's no portable way to interrupt it mid-call, so the parameter was removed rather than left as a silently-ignored knob.
28
+
29
+ ## [0.2.2] - 2026-05-07
30
+
31
+ ### Added
32
+
33
+ - **End-to-end regression test** — `tests/test_e2e.py` opens a real binary through fastmcp's in-process `Client` + `FastMCPTransport`, asserting the call returns within 15s. Catches future regressions that route idalib off the main thread (which would hang). Auto-skips when idalib isn't available.
34
+
35
+ ### Changed
36
+
37
+ - **Pin fastmcp back to `>=2.0,<3`** — v3 dispatches sync tool functions to `anyio.to_thread.run_sync`, but idalib hangs indefinitely when called from a non-main thread, so every idalib-touching tool wedged. v2 runs sync tools on the main thread and works in 0.7s on the same call. Reverts the v2→v3 bump from 0.2.1.
38
+ - **`open_database` refuses paths with unpacked fragments present** — if `.id0`/`.id1`/`.id2`/`.nam`/`.til` files exist for the target and `overwrite=False`, raise a clear `ToolError` listing them instead of letting idalib return an opaque `-1`. The message warns that the fragments may belong to another active IDA instance and only suggests `overwrite=True` if nothing else owns them.
39
+
40
+ ### Fixed
41
+
42
+ - **`open_database` overwrite cleans up unpacked fragments** — `overwrite=True` now also deletes `.id0`, `.id1`, `.id2`, `.nam`, and `.til` files, not just `.i64`/`.idb`. A failed open could leave these partial fragments behind, after which every subsequent attempt would fail immediately with a generic `-1` because IDA refused to overwrite the half-written unpacked database.
8
43
 
9
44
  ## [0.2.1] - 2026-05-05
10
45
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ida-code
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: MCP server for AI-assisted IDAPython scripting via idalib
5
5
  Project-URL: Homepage, https://github.com/Dil4rd/ida-code
6
6
  Project-URL: Repository, https://github.com/Dil4rd/ida-code
@@ -21,7 +21,7 @@ Classifier: Topic :: Security
21
21
  Classifier: Topic :: Software Development :: Disassemblers
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: >=3.12
24
- Requires-Dist: fastmcp<4,>=3.0
24
+ Requires-Dist: fastmcp<4,>=2.0
25
25
  Requires-Dist: lief>=0.15
26
26
  Provides-Extra: dev
27
27
  Requires-Dist: pytest>=8.0; extra == 'dev'
@@ -76,7 +76,7 @@ For other MCP clients, run the server directly:
76
76
  IDA_INSTALL_DIR=/opt/ida-pro-9.3 ida-code # stdio transport
77
77
  ```
78
78
 
79
- ## Tools (35)
79
+ ## Tools (36)
80
80
 
81
81
  Full parameter docs live in each tool's docstring — surfaced automatically to MCP clients via `tools/list`.
82
82
 
@@ -90,7 +90,7 @@ Full parameter docs live in each tool's docstring — surfaced automatically to
90
90
  | Snapshots | `list_snapshots`, `create_snapshot`, `restore_snapshot`, `delete_snapshot` |
91
91
  | Undo/redo | `get_undo_status`, `perform_undo`, `perform_redo` |
92
92
  | Inventory | `get_strings`, `get_imports`, `get_exports` |
93
- | Search | `search_docs`, `search_examples` |
93
+ | Search | `search_docs`, `search_code`, `get_source` |
94
94
 
95
95
  ## Resources & prompts
96
96
 
@@ -156,6 +156,10 @@ uv sync --extra dev
156
156
  uv run pytest
157
157
  ```
158
158
 
159
+ ## Known issues
160
+
161
+ See [KNOWN_ISSUES.md](KNOWN_ISSUES.md) for caveats and workarounds (e.g. why we pin `fastmcp<3`).
162
+
159
163
  The test suite covers the executor, doc/example search, comments, snapshots, structures, undo, variables, and Mach-O parsing. Tests that need idalib are skipped if it's not available.
160
164
 
161
165
  ## Credits
@@ -47,7 +47,7 @@ For other MCP clients, run the server directly:
47
47
  IDA_INSTALL_DIR=/opt/ida-pro-9.3 ida-code # stdio transport
48
48
  ```
49
49
 
50
- ## Tools (35)
50
+ ## Tools (36)
51
51
 
52
52
  Full parameter docs live in each tool's docstring — surfaced automatically to MCP clients via `tools/list`.
53
53
 
@@ -61,7 +61,7 @@ Full parameter docs live in each tool's docstring — surfaced automatically to
61
61
  | Snapshots | `list_snapshots`, `create_snapshot`, `restore_snapshot`, `delete_snapshot` |
62
62
  | Undo/redo | `get_undo_status`, `perform_undo`, `perform_redo` |
63
63
  | Inventory | `get_strings`, `get_imports`, `get_exports` |
64
- | Search | `search_docs`, `search_examples` |
64
+ | Search | `search_docs`, `search_code`, `get_source` |
65
65
 
66
66
  ## Resources & prompts
67
67
 
@@ -127,6 +127,10 @@ uv sync --extra dev
127
127
  uv run pytest
128
128
  ```
129
129
 
130
+ ## Known issues
131
+
132
+ See [KNOWN_ISSUES.md](KNOWN_ISSUES.md) for caveats and workarounds (e.g. why we pin `fastmcp<3`).
133
+
130
134
  The test suite covers the executor, doc/example search, comments, snapshots, structures, undo, variables, and Mach-O parsing. Tests that need idalib are skipped if it's not available.
131
135
 
132
136
  ## Credits
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ida-code"
3
- version = "0.2.1"
3
+ version = "0.2.3"
4
4
  description = "MCP server for AI-assisted IDAPython scripting via idalib"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Topic :: Software Development :: Disassemblers",
21
21
  "Topic :: Software Development :: Libraries :: Python Modules",
22
22
  ]
23
- dependencies = ["fastmcp>=3.0,<4", "lief>=0.15"]
23
+ dependencies = ["fastmcp>=2.0,<4", "lief>=0.15"]
24
24
 
25
25
  [project.urls]
26
26
  Homepage = "https://github.com/Dil4rd/ida-code"