libcontext 0.2.0__tar.gz → 0.3.0__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 (49) hide show
  1. {libcontext-0.2.0 → libcontext-0.3.0}/.github/workflows/ci.yml +18 -27
  2. {libcontext-0.2.0 → libcontext-0.3.0}/.gitignore +5 -0
  3. libcontext-0.3.0/CHANGELOG.md +89 -0
  4. {libcontext-0.2.0 → libcontext-0.3.0}/DEPENDENCIES.md +14 -8
  5. {libcontext-0.2.0 → libcontext-0.3.0}/PKG-INFO +81 -21
  6. {libcontext-0.2.0 → libcontext-0.3.0}/README.md +80 -20
  7. {libcontext-0.2.0 → libcontext-0.3.0}/pyproject.toml +1 -1
  8. {libcontext-0.2.0 → libcontext-0.3.0}/src/libcontext/__init__.py +18 -1
  9. libcontext-0.3.0/src/libcontext/_security.py +184 -0
  10. libcontext-0.3.0/src/libcontext/cache.py +265 -0
  11. {libcontext-0.2.0 → libcontext-0.3.0}/src/libcontext/cli.py +267 -39
  12. libcontext-0.3.0/src/libcontext/collector.py +727 -0
  13. {libcontext-0.2.0 → libcontext-0.3.0}/src/libcontext/config.py +4 -0
  14. libcontext-0.3.0/src/libcontext/diff.py +294 -0
  15. {libcontext-0.2.0 → libcontext-0.3.0}/src/libcontext/exceptions.py +14 -5
  16. {libcontext-0.2.0 → libcontext-0.3.0}/src/libcontext/inspector.py +70 -2
  17. libcontext-0.3.0/src/libcontext/mcp_server.py +270 -0
  18. libcontext-0.3.0/src/libcontext/models.py +378 -0
  19. libcontext-0.3.0/src/libcontext/renderer.py +1206 -0
  20. libcontext-0.3.0/tests/test_cache.py +384 -0
  21. {libcontext-0.2.0 → libcontext-0.3.0}/tests/test_cli.py +395 -0
  22. {libcontext-0.2.0 → libcontext-0.3.0}/tests/test_collector.py +512 -12
  23. {libcontext-0.2.0 → libcontext-0.3.0}/tests/test_config.py +11 -0
  24. libcontext-0.3.0/tests/test_diff.py +546 -0
  25. {libcontext-0.2.0 → libcontext-0.3.0}/tests/test_inspector.py +187 -1
  26. {libcontext-0.2.0 → libcontext-0.3.0}/tests/test_mcp_server.py +154 -1
  27. libcontext-0.3.0/tests/test_models.py +336 -0
  28. libcontext-0.3.0/tests/test_renderer.py +1432 -0
  29. libcontext-0.3.0/tests/test_security.py +215 -0
  30. libcontext-0.2.0/CHANGELOG.md +0 -52
  31. libcontext-0.2.0/src/libcontext/collector.py +0 -286
  32. libcontext-0.2.0/src/libcontext/mcp_server.py +0 -164
  33. libcontext-0.2.0/src/libcontext/models.py +0 -92
  34. libcontext-0.2.0/src/libcontext/renderer.py +0 -484
  35. libcontext-0.2.0/tests/test_renderer.py +0 -463
  36. {libcontext-0.2.0 → libcontext-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  37. {libcontext-0.2.0 → libcontext-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  38. {libcontext-0.2.0 → libcontext-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  39. {libcontext-0.2.0 → libcontext-0.3.0}/.github/workflows/release.yml +0 -0
  40. {libcontext-0.2.0 → libcontext-0.3.0}/CONTRIBUTING.md +0 -0
  41. {libcontext-0.2.0 → libcontext-0.3.0}/LICENSE +0 -0
  42. {libcontext-0.2.0 → libcontext-0.3.0}/SECURITY.md +0 -0
  43. {libcontext-0.2.0 → libcontext-0.3.0}/docs/adr/001-progressive-disclosure-over-always-on-context.md +0 -0
  44. {libcontext-0.2.0 → libcontext-0.3.0}/docs/adr/002-skill-plus-cli-as-primary-integration.md +0 -0
  45. {libcontext-0.2.0 → libcontext-0.3.0}/docs/adr/004-ast-only-inspection.md +0 -0
  46. {libcontext-0.2.0 → libcontext-0.3.0}/docs/adr/README.md +0 -0
  47. {libcontext-0.2.0 → libcontext-0.3.0}/src/libcontext/py.typed +0 -0
  48. {libcontext-0.2.0 → libcontext-0.3.0}/tests/__init__.py +0 -0
  49. {libcontext-0.2.0 → libcontext-0.3.0}/tests/test_cli_mcp_parity.py +0 -0
@@ -23,18 +23,17 @@ jobs:
23
23
  steps:
24
24
  - uses: actions/checkout@v4
25
25
 
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v5
28
+
26
29
  - name: Set up Python ${{ matrix.python-version }}
27
- uses: actions/setup-python@v5
28
- with:
29
- python-version: ${{ matrix.python-version }}
30
+ run: uv python install ${{ matrix.python-version }}
30
31
 
31
32
  - name: Install dependencies
32
- run: |
33
- python -m pip install --upgrade pip
34
- pip install -e ".[dev]"
33
+ run: uv sync --group dev
35
34
 
36
35
  - name: Run tests
37
- run: pytest -v --cov=libcontext --cov-report=xml
36
+ run: uv run pytest -v --cov=libcontext --cov-report=xml
38
37
 
39
38
  - name: Upload coverage
40
39
  if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
@@ -50,24 +49,23 @@ jobs:
50
49
  steps:
51
50
  - uses: actions/checkout@v4
52
51
 
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@v5
54
+
53
55
  - name: Set up Python
54
- uses: actions/setup-python@v5
55
- with:
56
- python-version: "3.12"
56
+ run: uv python install 3.12
57
57
 
58
58
  - name: Install dependencies
59
- run: |
60
- python -m pip install --upgrade pip
61
- pip install -e ".[dev]"
59
+ run: uv sync --group dev
62
60
 
63
61
  - name: Ruff lint
64
- run: ruff check src/ tests/
62
+ run: uv run ruff check src/ tests/
65
63
 
66
64
  - name: Ruff format check
67
- run: ruff format --check src/ tests/
65
+ run: uv run ruff format --check src/ tests/
68
66
 
69
67
  - name: Type checking (mypy)
70
- run: mypy src/libcontext
68
+ run: uv run mypy src/libcontext
71
69
 
72
70
  build:
73
71
  name: Build package
@@ -76,21 +74,14 @@ jobs:
76
74
  steps:
77
75
  - uses: actions/checkout@v4
78
76
 
79
- - name: Set up Python
80
- uses: actions/setup-python@v5
81
- with:
82
- python-version: "3.12"
83
-
84
- - name: Install build tools
85
- run: |
86
- python -m pip install --upgrade pip
87
- pip install build twine
77
+ - name: Install uv
78
+ uses: astral-sh/setup-uv@v5
88
79
 
89
80
  - name: Build
90
- run: python -m build
81
+ run: uv build
91
82
 
92
83
  - name: Check package
93
- run: twine check dist/*
84
+ run: uvx twine check dist/*
94
85
 
95
86
  - name: Upload artifacts
96
87
  uses: actions/upload-artifact@v4
@@ -62,6 +62,11 @@ dmypy.json
62
62
  # ruff
63
63
  .ruff_cache/
64
64
 
65
+ # Specs / internal docs
66
+ specs/
67
+ CHECKLIST_SPEC.md
68
+ ROADMAP.md
69
+
65
70
  # OS files
66
71
  .DS_Store
67
72
  Thumbs.db
@@ -0,0 +1,89 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.3.0] - 2026-03-23
11
+
12
+ ### Added
13
+
14
+ - **Security module** (`_security.py`): centralised input sanitisation, path boundary validation, output size guards, and search result caps. All security invariants enforced in one auditable location.
15
+ - **Stub file support**: `.pyi` stub files are discovered (colocated and standalone stub packages) and merged with `.py` sources — signatures from stubs, docstrings from sources.
16
+ - **Overload grouping**: `@typing.overload`-decorated functions are grouped into a single entry showing all signatures in one code block.
17
+ - **Type alias rendering**: PEP 613 (`TypeAlias`) and PEP 695 (`type X = T`) type aliases are detected via AST analysis and rendered in dedicated "Type Aliases" sections.
18
+ - **JSON output**: `--format json` flag for all CLI modes; versioned JSON envelope with `schema_version`; `from_dict()` classmethods on all model dataclasses; `search_package_structured()` for programmatic search results.
19
+ - **API diff**: `libctx diff old.json new.json` compares two API snapshots and reports added, removed, and modified symbols with breaking change detection; `render_diff()` Markdown output; `--format json` support.
20
+ - **Search enhancements**: `--type` filter (`class`, `function`, `variable`, `alias`); docstring search with preview annotations.
21
+ - **Persistent disk cache**: Caches collected `PackageInfo` as JSON on disk; invalidation by `(version, max_mtime, file_count)`; LRU eviction (max 50 entries); `--no-cache` flag; `libctx cache clear` subcommand.
22
+
23
+ ### Security
24
+
25
+ - **Path traversal prevention**: cache filenames are sanitised via regex allowlist — crafted package names like `../../etc/passwd` can no longer escape the cache directory.
26
+ - **Symlink boundary enforcement**: all `rglob()` file walks (collector and cache stats) now verify that resolved paths remain within the package root, blocking symlink-based file read attacks.
27
+ - **File size guard**: source files exceeding 10 MiB are skipped during both collection and inspection, preventing memory exhaustion from generated or malicious files.
28
+ - **HTML marker escaping**: package names are escaped before insertion into `<!-- BEGIN/END LIBCONTEXT -->` markers, preventing comment injection and downstream prompt injection.
29
+ - **Output truncation**: all MCP tool responses are capped at 120k characters (~30k tokens) with an explicit truncation notice, preventing context window saturation.
30
+ - **Search result cap**: `search_package()` and `search_package_structured()` return at most 100 results by default, with a configurable `max_results` parameter.
31
+ - **JSON input size limit**: the `diff` command (CLI and MCP) rejects inputs exceeding 50 MiB before deserialisation, preventing JSON-based denial of service.
32
+ - **Config bounds validation**: `max_readme_lines` now rejects negative values.
33
+ - **Legacy marker backward compatibility**: `inject_into_file()` detects and upgrades unescaped markers written by previous versions, preventing duplicate blocks.
34
+
35
+ ### Changed
36
+
37
+ - `models.py` now includes diff dataclasses (`DiffResult`, `ModuleDiff`, `ClassDiff`, `FunctionDiff`, `VariableDiff`) and JSON envelope utilities.
38
+ - `renderer.py` now exports `search_package_structured()` and `render_diff()`.
39
+ - `collector.py` integrates the disk cache automatically for installed packages with version metadata.
40
+ - MCP server `search_api` tool now accepts `kind` and `format` parameters; supports JSON structured output.
41
+ - MCP server `get_api_json` tool now accepts an optional `module_name` for single-module extraction.
42
+ - MCP server `refresh_cache` tool now clears both in-memory (LRU) and disk caches.
43
+ - MCP server adds `diff_api` tool for comparing two API snapshots directly from the IDE.
44
+ - `/lib` skill now documents `--type` filter, `--no-cache`, `--format json`, and diff workflow.
45
+
46
+ ## [0.2.0] - 2026-03-18
47
+
48
+ ### Added
49
+
50
+ - Progressive disclosure CLI flags: `--overview`, `--module`, `--search` for on-demand API inspection.
51
+ - `libctx install` subcommand with `--skills`, `--mcp`, `--all`, and `--target` options.
52
+ - `/lib` skill for Claude Code and GitHub Copilot — on-demand library discovery via slash command.
53
+ - MCP server (`libctx-mcp`) for VS Code / Cursor integration with `get_package_overview`, `get_module_api`, `search_api`, and `refresh_cache` tools.
54
+ - `render_module()`, `render_package_overview()`, and `search_package()` public API functions.
55
+ - Optional `[mcp]` extra for MCP server dependencies (requires Python 3.10+).
56
+ - Non-destructive JSON merge for MCP config files (preserves existing entries).
57
+
58
+ ### Changed
59
+
60
+ - CLI restructured as a click Group with `inspect` and `install` subcommands.
61
+
62
+ ## [0.1.0] - 2026-02-13
63
+
64
+ ### Added
65
+
66
+ - Initial release of libcontext.
67
+ - AST-based static analysis of Python packages (no code execution).
68
+ - CLI command `libctx` to generate Markdown context files.
69
+ - Support for inspecting any installed Python package by name.
70
+ - Support for inspecting local package directories by path.
71
+ - Extraction of classes, methods, functions, parameters, type annotations, decorators, and docstrings.
72
+ - Automatic README discovery via `importlib.metadata` and filesystem search.
73
+ - Marker-based injection (`<!-- BEGIN/END LIBCONTEXT -->`) for updating existing files without overwriting.
74
+ - Optional `[tool.libcontext]` configuration in `pyproject.toml` for library authors.
75
+ - Module include/exclude filtering.
76
+ - Private member filtering with `--include-private` override.
77
+ - Multi-package support in a single CLI invocation.
78
+ - Intelligent dunder method filtering (includes useful ones like `__init__`, `__call__`, etc.).
79
+ - Respects `__all__` when defined in modules.
80
+ - Positional-only, keyword-only, `*args`, and `**kwargs` parameter handling.
81
+ - Inner class and decorated class support.
82
+ - README truncation with configurable line limit.
83
+ - Free-form `extra_context` field for library authors.
84
+ - Python API for programmatic usage (`collect_package`, `render_package`).
85
+
86
+ [Unreleased]: https://github.com/Syclaw/libcontext/compare/v0.3.0...HEAD
87
+ [0.3.0]: https://github.com/Syclaw/libcontext/compare/v0.2.0...v0.3.0
88
+ [0.2.0]: https://github.com/Syclaw/libcontext/compare/v0.1.0...v0.2.0
89
+ [0.1.0]: https://github.com/Syclaw/libcontext/releases/tag/v0.1.0
@@ -19,10 +19,10 @@ This document lists all dependencies used by **libcontext** and their respective
19
19
 
20
20
  | Package | Version | License | Description |
21
21
  |---------|---------|---------|-------------|
22
- | [pytest](https://pypi.org/project/pytest/) | >=7.0 | MIT | Testing framework. |
23
- | [pytest-cov](https://pypi.org/project/pytest-cov/) | >=4.0 | MIT | Coverage plugin for pytest. |
24
- | [ruff](https://pypi.org/project/ruff/) | >=0.4.0 | MIT | Fast Python linter and formatter (replaces flake8, isort, black, pyupgrade). |
25
- | [mypy](https://pypi.org/project/mypy/) | >=1.10 | MIT | Static type checker for Python. |
22
+ | [pytest](https://pypi.org/project/pytest/) | >=8.4.2 | MIT | Testing framework. |
23
+ | [pytest-cov](https://pypi.org/project/pytest-cov/) | >=7.0.0 | MIT | Coverage plugin for pytest. |
24
+ | [ruff](https://pypi.org/project/ruff/) | >=0.15.1 | MIT | Fast Python linter and formatter (replaces flake8, isort, black, pyupgrade). |
25
+ | [mypy](https://pypi.org/project/mypy/) | >=1.19.1 | MIT | Static type checker for Python. |
26
26
 
27
27
  ## Build Dependencies
28
28
 
@@ -35,16 +35,22 @@ This document lists all dependencies used by **libcontext** and their respective
35
35
  The following standard library modules are used and require **no additional installation**:
36
36
 
37
37
  - `ast` — Abstract Syntax Trees (core of the inspection engine)
38
+ - `contextlib` — Context managers (cache file handling)
39
+ - `copy` — Deep copy of data structures (stub merging)
40
+ - `dataclasses` — Data model definitions
41
+ - `datetime` — Timestamp handling (cache metadata)
42
+ - `difflib` — Fuzzy matching (similar package name suggestions)
43
+ - `functools` — LRU cache (MCP server in-memory caching)
38
44
  - `importlib.metadata` — Package metadata access
39
45
  - `importlib.util` — Package location discovery
40
- - `dataclasses` — Data model definitions
41
- - `pathlib` — Filesystem path handling
46
+ - `json` — JSON serialization (cache, MCP config, JSON output)
42
47
  - `logging` — Diagnostic logging
48
+ - `os` — OS-level operations (cache directory, file stats)
49
+ - `pathlib` — Filesystem path handling
43
50
  - `sys` — System-specific parameters
44
- - `io` — I/O handling (UTF-8 stdout wrapper)
45
- - `json` — JSON reading/writing (MCP config merge)
46
51
  - `textwrap` — Text formatting (skill content generation)
47
52
  - `tomllib` — TOML parsing (Python 3.11+, replaces `tomli`)
53
+ - `typing` — Type annotations (`Any`)
48
54
 
49
55
  ## License Compatibility
50
56
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libcontext
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Generate optimized LLM context from Python library APIs — CLI, skill, and MCP server
5
5
  Project-URL: Homepage, https://github.com/Syclaw/libcontext
6
6
  Project-URL: Repository, https://github.com/Syclaw/libcontext
@@ -65,7 +65,8 @@ libcontext solves this with **progressive disclosure**: overview first, then dri
65
65
  ## Quick Start
66
66
 
67
67
  ```bash
68
- pip install libcontext
68
+ # Install globally with uv (recommended — available in all projects)
69
+ uv tool install libcontext
69
70
 
70
71
  # Install the /lib skill into your Claude Code project
71
72
  libctx install --skills
@@ -78,7 +79,7 @@ libctx install --skills
78
79
  For VS Code with MCP support:
79
80
 
80
81
  ```bash
81
- pip install libcontext[mcp]
82
+ uv tool install "libcontext[mcp]"
82
83
  libctx install --mcp --target vscode
83
84
  ```
84
85
 
@@ -120,35 +121,67 @@ libctx inspect requests -o .github/copilot-instructions.md
120
121
 
121
122
  # Multiple libraries at once
122
123
  libctx inspect requests httpx pydantic -o context.md
124
+
125
+ # JSON output (programmatic consumption)
126
+ libctx inspect requests --format json
127
+ libctx inspect requests --search Session --format json
128
+
129
+ # Filter search by type
130
+ libctx inspect requests --search Session --type class -q
131
+
132
+ # Compare two API snapshots
133
+ libctx inspect requests --format json > old.json
134
+ # ... upgrade requests ...
135
+ libctx inspect requests --format json > new.json
136
+ libctx diff old.json new.json
137
+
138
+ # Bypass disk cache
139
+ libctx inspect requests --no-cache
140
+
141
+ # Clear all cached API data
142
+ libctx cache clear
123
143
  ```
124
144
 
125
145
  ### AST Analysis
126
146
 
127
- 1. **Parsing** — Reads source files of installed packages using Python's `ast` module. No code is ever executed.
128
- 2. **Extraction** — Classes, functions, methods, parameters, type annotations, decorators, and docstrings.
129
- 3. **Compact rendering** — Structured Markdown optimised for LLM context windows.
130
- 4. **Marker injection** — `<!-- BEGIN/END LIBCONTEXT -->` markers for idempotent file updates.
147
+ 1. **Parsing** — Reads `.py` and `.pyi` source files using Python's `ast` module. No code is ever executed.
148
+ 2. **Stub merging** — Discovers colocated and standalone stub packages; merges signatures from stubs with docstrings from sources.
149
+ 3. **Extraction** — Classes, functions, methods, parameters, type annotations, decorators, type aliases, and docstrings.
150
+ 4. **Compact rendering** — Structured Markdown (or JSON) optimised for LLM context windows.
151
+ 5. **Disk cache** — Results are cached on disk and revalidated via `(version, mtime, file_count)` to avoid re-parsing unchanged packages.
131
152
 
132
153
  ## Installation
133
154
 
134
- ```bash
135
- pip install libcontext
136
- ```
155
+ ### Global install (recommended)
137
156
 
138
- With MCP server support (requires Python 3.10+):
157
+ Install once, use across all projects — no per-project dependency needed:
139
158
 
140
159
  ```bash
141
- pip install libcontext[mcp]
160
+ uv tool install libcontext # CLI only
161
+ uv tool install "libcontext[mcp]" # with MCP server (requires Python 3.10+)
142
162
  ```
143
163
 
144
- Or with [uv](https://docs.astral.sh/uv/):
164
+ Update later with `uv tool upgrade libcontext`.
165
+
166
+ > **One-off usage without installing:** `uvx --from libcontext libctx inspect requests`
167
+
168
+ ### Per-project install
169
+
170
+ If you prefer to add libcontext as a project dependency:
145
171
 
146
172
  ```bash
147
173
  uv add libcontext # basic
148
174
  uv add libcontext[mcp] # with MCP server
149
175
  ```
150
176
 
151
- For development:
177
+ Or with pip:
178
+
179
+ ```bash
180
+ pip install libcontext
181
+ pip install libcontext[mcp]
182
+ ```
183
+
184
+ ### Development
152
185
 
153
186
  ```bash
154
187
  git clone https://github.com/Syclaw/libcontext.git
@@ -206,8 +239,10 @@ After `libctx install --mcp`, the MCP server provides tools:
206
239
 
207
240
  - `get_package_overview` — structural overview of a package
208
241
  - `get_module_api` — detailed API for a single module
209
- - `search_api` — search for classes, functions, or methods
210
- - `refresh_cache` — clear the session cache
242
+ - `search_api` — search by name or docstring (with optional `kind` filter and `format` for JSON output)
243
+ - `get_api_json` — full package or single-module API as structured JSON
244
+ - `diff_api` — compare two API snapshots and report changes with breaking change detection
245
+ - `refresh_cache` — clear both in-memory and disk caches
211
246
 
212
247
  ## Python API
213
248
 
@@ -234,6 +269,29 @@ for mod in pkg.non_empty_modules:
234
269
 
235
270
  # Search — find specific classes or functions
236
271
  print(search_package(pkg, "Session"))
272
+
273
+ # Search with type filter
274
+ print(search_package(pkg, "Session", kind="class"))
275
+ ```
276
+
277
+ ```python
278
+ import dataclasses, json
279
+ from libcontext import collect_package, diff_packages, render_diff
280
+ from libcontext.models import PackageInfo, _serialize_envelope
281
+
282
+ # JSON serialization (roundtrip-safe)
283
+ pkg = collect_package("requests")
284
+ data = _serialize_envelope(dataclasses.asdict(pkg))
285
+ print(json.dumps(data, indent=2))
286
+
287
+ # Reconstruct from JSON
288
+ pkg_restored = PackageInfo.from_dict(data["data"])
289
+
290
+ # API diff between versions
291
+ old_pkg = PackageInfo.from_dict(old_data)
292
+ new_pkg = PackageInfo.from_dict(new_data)
293
+ result = diff_packages(old_pkg, new_pkg)
294
+ print(render_diff(result))
237
295
  ```
238
296
 
239
297
  ## Configuration (Optional)
@@ -256,12 +314,14 @@ All async operations use httpx internally.
256
314
 
257
315
  | Module | Role |
258
316
  |---|---|
259
- | `models.py` | Dataclasses representing Python components |
260
- | `inspector.py` | Static AST analysis — signatures, docstrings, decorators |
261
- | `collector.py` | Package discovery and module collection |
317
+ | `models.py` | Dataclasses for packages, modules, classes, functions, and diff results |
318
+ | `inspector.py` | Static AST analysis — signatures, docstrings, decorators, type aliases |
319
+ | `collector.py` | Package discovery, module collection, stub merging, and disk cache integration |
262
320
  | `config.py` | Reads `[tool.libcontext]` from pyproject.toml |
263
- | `renderer.py` | LLM-optimised Markdown generation |
264
- | `cli.py` | CLI entry point with `inspect` and `install` subcommands |
321
+ | `renderer.py` | LLM-optimised Markdown generation (full, overview, module, search, diff) |
322
+ | `diff.py` | API diff between two package versions with breaking change detection |
323
+ | `cache.py` | Persistent disk cache with mtime/file-count invalidation and LRU eviction |
324
+ | `cli.py` | CLI entry point — `inspect`, `install`, `diff`, and `cache` subcommands |
265
325
  | `mcp_server.py` | MCP server for VS Code / Cursor integration (optional) |
266
326
 
267
327
  ## Development
@@ -36,7 +36,8 @@ libcontext solves this with **progressive disclosure**: overview first, then dri
36
36
  ## Quick Start
37
37
 
38
38
  ```bash
39
- pip install libcontext
39
+ # Install globally with uv (recommended — available in all projects)
40
+ uv tool install libcontext
40
41
 
41
42
  # Install the /lib skill into your Claude Code project
42
43
  libctx install --skills
@@ -49,7 +50,7 @@ libctx install --skills
49
50
  For VS Code with MCP support:
50
51
 
51
52
  ```bash
52
- pip install libcontext[mcp]
53
+ uv tool install "libcontext[mcp]"
53
54
  libctx install --mcp --target vscode
54
55
  ```
55
56
 
@@ -91,35 +92,67 @@ libctx inspect requests -o .github/copilot-instructions.md
91
92
 
92
93
  # Multiple libraries at once
93
94
  libctx inspect requests httpx pydantic -o context.md
95
+
96
+ # JSON output (programmatic consumption)
97
+ libctx inspect requests --format json
98
+ libctx inspect requests --search Session --format json
99
+
100
+ # Filter search by type
101
+ libctx inspect requests --search Session --type class -q
102
+
103
+ # Compare two API snapshots
104
+ libctx inspect requests --format json > old.json
105
+ # ... upgrade requests ...
106
+ libctx inspect requests --format json > new.json
107
+ libctx diff old.json new.json
108
+
109
+ # Bypass disk cache
110
+ libctx inspect requests --no-cache
111
+
112
+ # Clear all cached API data
113
+ libctx cache clear
94
114
  ```
95
115
 
96
116
  ### AST Analysis
97
117
 
98
- 1. **Parsing** — Reads source files of installed packages using Python's `ast` module. No code is ever executed.
99
- 2. **Extraction** — Classes, functions, methods, parameters, type annotations, decorators, and docstrings.
100
- 3. **Compact rendering** — Structured Markdown optimised for LLM context windows.
101
- 4. **Marker injection** — `<!-- BEGIN/END LIBCONTEXT -->` markers for idempotent file updates.
118
+ 1. **Parsing** — Reads `.py` and `.pyi` source files using Python's `ast` module. No code is ever executed.
119
+ 2. **Stub merging** — Discovers colocated and standalone stub packages; merges signatures from stubs with docstrings from sources.
120
+ 3. **Extraction** — Classes, functions, methods, parameters, type annotations, decorators, type aliases, and docstrings.
121
+ 4. **Compact rendering** — Structured Markdown (or JSON) optimised for LLM context windows.
122
+ 5. **Disk cache** — Results are cached on disk and revalidated via `(version, mtime, file_count)` to avoid re-parsing unchanged packages.
102
123
 
103
124
  ## Installation
104
125
 
105
- ```bash
106
- pip install libcontext
107
- ```
126
+ ### Global install (recommended)
108
127
 
109
- With MCP server support (requires Python 3.10+):
128
+ Install once, use across all projects — no per-project dependency needed:
110
129
 
111
130
  ```bash
112
- pip install libcontext[mcp]
131
+ uv tool install libcontext # CLI only
132
+ uv tool install "libcontext[mcp]" # with MCP server (requires Python 3.10+)
113
133
  ```
114
134
 
115
- Or with [uv](https://docs.astral.sh/uv/):
135
+ Update later with `uv tool upgrade libcontext`.
136
+
137
+ > **One-off usage without installing:** `uvx --from libcontext libctx inspect requests`
138
+
139
+ ### Per-project install
140
+
141
+ If you prefer to add libcontext as a project dependency:
116
142
 
117
143
  ```bash
118
144
  uv add libcontext # basic
119
145
  uv add libcontext[mcp] # with MCP server
120
146
  ```
121
147
 
122
- For development:
148
+ Or with pip:
149
+
150
+ ```bash
151
+ pip install libcontext
152
+ pip install libcontext[mcp]
153
+ ```
154
+
155
+ ### Development
123
156
 
124
157
  ```bash
125
158
  git clone https://github.com/Syclaw/libcontext.git
@@ -177,8 +210,10 @@ After `libctx install --mcp`, the MCP server provides tools:
177
210
 
178
211
  - `get_package_overview` — structural overview of a package
179
212
  - `get_module_api` — detailed API for a single module
180
- - `search_api` — search for classes, functions, or methods
181
- - `refresh_cache` — clear the session cache
213
+ - `search_api` — search by name or docstring (with optional `kind` filter and `format` for JSON output)
214
+ - `get_api_json` — full package or single-module API as structured JSON
215
+ - `diff_api` — compare two API snapshots and report changes with breaking change detection
216
+ - `refresh_cache` — clear both in-memory and disk caches
182
217
 
183
218
  ## Python API
184
219
 
@@ -205,6 +240,29 @@ for mod in pkg.non_empty_modules:
205
240
 
206
241
  # Search — find specific classes or functions
207
242
  print(search_package(pkg, "Session"))
243
+
244
+ # Search with type filter
245
+ print(search_package(pkg, "Session", kind="class"))
246
+ ```
247
+
248
+ ```python
249
+ import dataclasses, json
250
+ from libcontext import collect_package, diff_packages, render_diff
251
+ from libcontext.models import PackageInfo, _serialize_envelope
252
+
253
+ # JSON serialization (roundtrip-safe)
254
+ pkg = collect_package("requests")
255
+ data = _serialize_envelope(dataclasses.asdict(pkg))
256
+ print(json.dumps(data, indent=2))
257
+
258
+ # Reconstruct from JSON
259
+ pkg_restored = PackageInfo.from_dict(data["data"])
260
+
261
+ # API diff between versions
262
+ old_pkg = PackageInfo.from_dict(old_data)
263
+ new_pkg = PackageInfo.from_dict(new_data)
264
+ result = diff_packages(old_pkg, new_pkg)
265
+ print(render_diff(result))
208
266
  ```
209
267
 
210
268
  ## Configuration (Optional)
@@ -227,12 +285,14 @@ All async operations use httpx internally.
227
285
 
228
286
  | Module | Role |
229
287
  |---|---|
230
- | `models.py` | Dataclasses representing Python components |
231
- | `inspector.py` | Static AST analysis — signatures, docstrings, decorators |
232
- | `collector.py` | Package discovery and module collection |
288
+ | `models.py` | Dataclasses for packages, modules, classes, functions, and diff results |
289
+ | `inspector.py` | Static AST analysis — signatures, docstrings, decorators, type aliases |
290
+ | `collector.py` | Package discovery, module collection, stub merging, and disk cache integration |
233
291
  | `config.py` | Reads `[tool.libcontext]` from pyproject.toml |
234
- | `renderer.py` | LLM-optimised Markdown generation |
235
- | `cli.py` | CLI entry point with `inspect` and `install` subcommands |
292
+ | `renderer.py` | LLM-optimised Markdown generation (full, overview, module, search, diff) |
293
+ | `diff.py` | API diff between two package versions with breaking change detection |
294
+ | `cache.py` | Persistent disk cache with mtime/file-count invalidation and LRU eviction |
295
+ | `cli.py` | CLI entry point — `inspect`, `install`, `diff`, and `cache` subcommands |
236
296
  | `mcp_server.py` | MCP server for VS Code / Cursor integration (optional) |
237
297
 
238
298
  ## Development
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "libcontext"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Generate optimized LLM context from Python library APIs — CLI, skill, and MCP server"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -22,8 +22,9 @@ from __future__ import annotations
22
22
  import importlib.metadata
23
23
  import logging
24
24
 
25
- from .collector import collect_package, find_package_path
25
+ from .collector import collect_package, find_package_path, suggest_similar_packages
26
26
  from .config import LibcontextConfig
27
+ from .diff import diff_packages
27
28
  from .exceptions import (
28
29
  ConfigError,
29
30
  InspectionError,
@@ -32,19 +33,26 @@ from .exceptions import (
32
33
  )
33
34
  from .inspector import inspect_file, inspect_source
34
35
  from .models import (
36
+ ClassDiff,
35
37
  ClassInfo,
38
+ DiffResult,
39
+ FunctionDiff,
36
40
  FunctionInfo,
41
+ ModuleDiff,
37
42
  ModuleInfo,
38
43
  PackageInfo,
39
44
  ParameterInfo,
45
+ VariableDiff,
40
46
  VariableInfo,
41
47
  )
42
48
  from .renderer import (
43
49
  inject_into_file,
50
+ render_diff,
44
51
  render_module,
45
52
  render_package,
46
53
  render_package_overview,
47
54
  search_package,
55
+ search_package_structured,
48
56
  )
49
57
 
50
58
  # Library best practice: add NullHandler to prevent "No handlers could be found"
@@ -57,24 +65,33 @@ except importlib.metadata.PackageNotFoundError:
57
65
  __version__ = "0.0.0-dev"
58
66
 
59
67
  __all__ = [
68
+ "ClassDiff",
60
69
  "ClassInfo",
61
70
  "ConfigError",
71
+ "DiffResult",
72
+ "FunctionDiff",
62
73
  "FunctionInfo",
63
74
  "InspectionError",
64
75
  "LibcontextConfig",
65
76
  "LibcontextError",
77
+ "ModuleDiff",
66
78
  "ModuleInfo",
67
79
  "PackageInfo",
68
80
  "PackageNotFoundError",
69
81
  "ParameterInfo",
82
+ "VariableDiff",
70
83
  "VariableInfo",
71
84
  "collect_package",
85
+ "diff_packages",
72
86
  "find_package_path",
73
87
  "inject_into_file",
74
88
  "inspect_file",
75
89
  "inspect_source",
90
+ "render_diff",
76
91
  "render_module",
77
92
  "render_package",
78
93
  "render_package_overview",
79
94
  "search_package",
95
+ "search_package_structured",
96
+ "suggest_similar_packages",
80
97
  ]