libcontext 0.2.0__tar.gz → 0.4.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.
- {libcontext-0.2.0 → libcontext-0.4.0}/.github/workflows/ci.yml +18 -27
- {libcontext-0.2.0 → libcontext-0.4.0}/.gitignore +5 -0
- libcontext-0.4.0/CHANGELOG.md +100 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/DEPENDENCIES.md +14 -8
- {libcontext-0.2.0 → libcontext-0.4.0}/PKG-INFO +81 -21
- {libcontext-0.2.0 → libcontext-0.4.0}/README.md +80 -20
- {libcontext-0.2.0 → libcontext-0.4.0}/pyproject.toml +1 -1
- {libcontext-0.2.0 → libcontext-0.4.0}/src/libcontext/__init__.py +20 -1
- libcontext-0.4.0/src/libcontext/_envsetup.py +334 -0
- libcontext-0.4.0/src/libcontext/_security.py +184 -0
- libcontext-0.4.0/src/libcontext/cache.py +282 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/src/libcontext/cli.py +295 -40
- libcontext-0.4.0/src/libcontext/collector.py +730 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/src/libcontext/config.py +4 -0
- libcontext-0.4.0/src/libcontext/diff.py +294 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/src/libcontext/exceptions.py +26 -5
- {libcontext-0.2.0 → libcontext-0.4.0}/src/libcontext/inspector.py +70 -2
- libcontext-0.4.0/src/libcontext/mcp_server.py +298 -0
- libcontext-0.4.0/src/libcontext/models.py +378 -0
- libcontext-0.4.0/src/libcontext/renderer.py +1206 -0
- libcontext-0.4.0/tests/test_cache.py +384 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/tests/test_cli.py +395 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/tests/test_collector.py +512 -12
- {libcontext-0.2.0 → libcontext-0.4.0}/tests/test_config.py +11 -0
- libcontext-0.4.0/tests/test_diff.py +546 -0
- libcontext-0.4.0/tests/test_envsetup.py +276 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/tests/test_inspector.py +187 -1
- {libcontext-0.2.0 → libcontext-0.4.0}/tests/test_mcp_server.py +154 -1
- libcontext-0.4.0/tests/test_models.py +336 -0
- libcontext-0.4.0/tests/test_renderer.py +1432 -0
- libcontext-0.4.0/tests/test_security.py +215 -0
- libcontext-0.2.0/CHANGELOG.md +0 -52
- libcontext-0.2.0/src/libcontext/collector.py +0 -286
- libcontext-0.2.0/src/libcontext/mcp_server.py +0 -164
- libcontext-0.2.0/src/libcontext/models.py +0 -92
- libcontext-0.2.0/src/libcontext/renderer.py +0 -484
- libcontext-0.2.0/tests/test_renderer.py +0 -463
- {libcontext-0.2.0 → libcontext-0.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/.github/workflows/release.yml +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/CONTRIBUTING.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/LICENSE +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/SECURITY.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/docs/adr/001-progressive-disclosure-over-always-on-context.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/docs/adr/002-skill-plus-cli-as-primary-integration.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/docs/adr/004-ast-only-inspection.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/docs/adr/README.md +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/src/libcontext/py.typed +0 -0
- {libcontext-0.2.0 → libcontext-0.4.0}/tests/__init__.py +0 -0
- {libcontext-0.2.0 → libcontext-0.4.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
|
-
|
|
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
|
-
|
|
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:
|
|
80
|
-
uses:
|
|
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:
|
|
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
|
|
@@ -0,0 +1,100 @@
|
|
|
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.4.0] - 2026-03-23
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Auto-detect project venv**: libcontext now automatically detects `.venv/` or `venv/` in the current directory and uses it for package discovery. This fixes the core issue where `uv tool install libcontext` could not see packages from project environments.
|
|
15
|
+
- **`--python` CLI option**: explicit override for targeting a specific Python interpreter or venv directory (e.g. `--python /path/to/other/venv`).
|
|
16
|
+
- **`LIBCONTEXT_PYTHON` env var**: configure the MCP server's target environment via environment variable or `--python` argument.
|
|
17
|
+
- **`EnvironmentSetupError` exception**: raised when a target environment cannot be resolved or queried.
|
|
18
|
+
- **Cache namespacing by environment**: packages from different environments get separate cache entries, preventing cross-environment cache collisions.
|
|
19
|
+
|
|
20
|
+
## [0.3.0] - 2026-03-23
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **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.
|
|
25
|
+
- **Stub file support**: `.pyi` stub files are discovered (colocated and standalone stub packages) and merged with `.py` sources — signatures from stubs, docstrings from sources.
|
|
26
|
+
- **Overload grouping**: `@typing.overload`-decorated functions are grouped into a single entry showing all signatures in one code block.
|
|
27
|
+
- **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.
|
|
28
|
+
- **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.
|
|
29
|
+
- **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.
|
|
30
|
+
- **Search enhancements**: `--type` filter (`class`, `function`, `variable`, `alias`); docstring search with preview annotations.
|
|
31
|
+
- **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.
|
|
32
|
+
|
|
33
|
+
### Security
|
|
34
|
+
|
|
35
|
+
- **Path traversal prevention**: cache filenames are sanitised via regex allowlist — crafted package names like `../../etc/passwd` can no longer escape the cache directory.
|
|
36
|
+
- **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.
|
|
37
|
+
- **File size guard**: source files exceeding 10 MiB are skipped during both collection and inspection, preventing memory exhaustion from generated or malicious files.
|
|
38
|
+
- **HTML marker escaping**: package names are escaped before insertion into `<!-- BEGIN/END LIBCONTEXT -->` markers, preventing comment injection and downstream prompt injection.
|
|
39
|
+
- **Output truncation**: all MCP tool responses are capped at 120k characters (~30k tokens) with an explicit truncation notice, preventing context window saturation.
|
|
40
|
+
- **Search result cap**: `search_package()` and `search_package_structured()` return at most 100 results by default, with a configurable `max_results` parameter.
|
|
41
|
+
- **JSON input size limit**: the `diff` command (CLI and MCP) rejects inputs exceeding 50 MiB before deserialisation, preventing JSON-based denial of service.
|
|
42
|
+
- **Config bounds validation**: `max_readme_lines` now rejects negative values.
|
|
43
|
+
- **Legacy marker backward compatibility**: `inject_into_file()` detects and upgrades unescaped markers written by previous versions, preventing duplicate blocks.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- `models.py` now includes diff dataclasses (`DiffResult`, `ModuleDiff`, `ClassDiff`, `FunctionDiff`, `VariableDiff`) and JSON envelope utilities.
|
|
48
|
+
- `renderer.py` now exports `search_package_structured()` and `render_diff()`.
|
|
49
|
+
- `collector.py` integrates the disk cache automatically for installed packages with version metadata.
|
|
50
|
+
- MCP server `search_api` tool now accepts `kind` and `format` parameters; supports JSON structured output.
|
|
51
|
+
- MCP server `get_api_json` tool now accepts an optional `module_name` for single-module extraction.
|
|
52
|
+
- MCP server `refresh_cache` tool now clears both in-memory (LRU) and disk caches.
|
|
53
|
+
- MCP server adds `diff_api` tool for comparing two API snapshots directly from the IDE.
|
|
54
|
+
- `/lib` skill now documents `--type` filter, `--no-cache`, `--format json`, and diff workflow.
|
|
55
|
+
|
|
56
|
+
## [0.2.0] - 2026-03-18
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- Progressive disclosure CLI flags: `--overview`, `--module`, `--search` for on-demand API inspection.
|
|
61
|
+
- `libctx install` subcommand with `--skills`, `--mcp`, `--all`, and `--target` options.
|
|
62
|
+
- `/lib` skill for Claude Code and GitHub Copilot — on-demand library discovery via slash command.
|
|
63
|
+
- MCP server (`libctx-mcp`) for VS Code / Cursor integration with `get_package_overview`, `get_module_api`, `search_api`, and `refresh_cache` tools.
|
|
64
|
+
- `render_module()`, `render_package_overview()`, and `search_package()` public API functions.
|
|
65
|
+
- Optional `[mcp]` extra for MCP server dependencies (requires Python 3.10+).
|
|
66
|
+
- Non-destructive JSON merge for MCP config files (preserves existing entries).
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
|
|
70
|
+
- CLI restructured as a click Group with `inspect` and `install` subcommands.
|
|
71
|
+
|
|
72
|
+
## [0.1.0] - 2026-02-13
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
|
|
76
|
+
- Initial release of libcontext.
|
|
77
|
+
- AST-based static analysis of Python packages (no code execution).
|
|
78
|
+
- CLI command `libctx` to generate Markdown context files.
|
|
79
|
+
- Support for inspecting any installed Python package by name.
|
|
80
|
+
- Support for inspecting local package directories by path.
|
|
81
|
+
- Extraction of classes, methods, functions, parameters, type annotations, decorators, and docstrings.
|
|
82
|
+
- Automatic README discovery via `importlib.metadata` and filesystem search.
|
|
83
|
+
- Marker-based injection (`<!-- BEGIN/END LIBCONTEXT -->`) for updating existing files without overwriting.
|
|
84
|
+
- Optional `[tool.libcontext]` configuration in `pyproject.toml` for library authors.
|
|
85
|
+
- Module include/exclude filtering.
|
|
86
|
+
- Private member filtering with `--include-private` override.
|
|
87
|
+
- Multi-package support in a single CLI invocation.
|
|
88
|
+
- Intelligent dunder method filtering (includes useful ones like `__init__`, `__call__`, etc.).
|
|
89
|
+
- Respects `__all__` when defined in modules.
|
|
90
|
+
- Positional-only, keyword-only, `*args`, and `**kwargs` parameter handling.
|
|
91
|
+
- Inner class and decorated class support.
|
|
92
|
+
- README truncation with configurable line limit.
|
|
93
|
+
- Free-form `extra_context` field for library authors.
|
|
94
|
+
- Python API for programmatic usage (`collect_package`, `render_package`).
|
|
95
|
+
|
|
96
|
+
[Unreleased]: https://github.com/Syclaw/libcontext/compare/v0.4.0...HEAD
|
|
97
|
+
[0.4.0]: https://github.com/Syclaw/libcontext/compare/v0.3.0...v0.4.0
|
|
98
|
+
[0.3.0]: https://github.com/Syclaw/libcontext/compare/v0.2.0...v0.3.0
|
|
99
|
+
[0.2.0]: https://github.com/Syclaw/libcontext/compare/v0.1.0...v0.2.0
|
|
100
|
+
[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/) | >=
|
|
23
|
-
| [pytest-cov](https://pypi.org/project/pytest-cov/) | >=
|
|
24
|
-
| [ruff](https://pypi.org/project/ruff/) | >=0.
|
|
25
|
-
| [mypy](https://pypi.org/project/mypy/) | >=1.
|
|
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
|
-
- `
|
|
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.
|
|
3
|
+
Version: 0.4.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
|
-
|
|
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
|
-
|
|
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
|
|
128
|
-
2. **
|
|
129
|
-
3. **
|
|
130
|
-
4. **
|
|
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
|
-
|
|
135
|
-
pip install libcontext
|
|
136
|
-
```
|
|
155
|
+
### Global install (recommended)
|
|
137
156
|
|
|
138
|
-
|
|
157
|
+
Install once, use across all projects — no per-project dependency needed:
|
|
139
158
|
|
|
140
159
|
```bash
|
|
141
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
210
|
-
- `
|
|
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
|
|
260
|
-
| `inspector.py` | Static AST analysis — signatures, docstrings, decorators |
|
|
261
|
-
| `collector.py` | Package discovery
|
|
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
|
-
| `
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
99
|
-
2. **
|
|
100
|
-
3. **
|
|
101
|
-
4. **
|
|
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
|
-
|
|
106
|
-
pip install libcontext
|
|
107
|
-
```
|
|
126
|
+
### Global install (recommended)
|
|
108
127
|
|
|
109
|
-
|
|
128
|
+
Install once, use across all projects — no per-project dependency needed:
|
|
110
129
|
|
|
111
130
|
```bash
|
|
112
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
181
|
-
- `
|
|
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
|
|
231
|
-
| `inspector.py` | Static AST analysis — signatures, docstrings, decorators |
|
|
232
|
-
| `collector.py` | Package discovery
|
|
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
|
-
| `
|
|
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
|
|
@@ -22,29 +22,38 @@ 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,
|
|
30
|
+
EnvironmentSetupError,
|
|
29
31
|
InspectionError,
|
|
30
32
|
LibcontextError,
|
|
31
33
|
PackageNotFoundError,
|
|
32
34
|
)
|
|
33
35
|
from .inspector import inspect_file, inspect_source
|
|
34
36
|
from .models import (
|
|
37
|
+
ClassDiff,
|
|
35
38
|
ClassInfo,
|
|
39
|
+
DiffResult,
|
|
40
|
+
FunctionDiff,
|
|
36
41
|
FunctionInfo,
|
|
42
|
+
ModuleDiff,
|
|
37
43
|
ModuleInfo,
|
|
38
44
|
PackageInfo,
|
|
39
45
|
ParameterInfo,
|
|
46
|
+
VariableDiff,
|
|
40
47
|
VariableInfo,
|
|
41
48
|
)
|
|
42
49
|
from .renderer import (
|
|
43
50
|
inject_into_file,
|
|
51
|
+
render_diff,
|
|
44
52
|
render_module,
|
|
45
53
|
render_package,
|
|
46
54
|
render_package_overview,
|
|
47
55
|
search_package,
|
|
56
|
+
search_package_structured,
|
|
48
57
|
)
|
|
49
58
|
|
|
50
59
|
# Library best practice: add NullHandler to prevent "No handlers could be found"
|
|
@@ -57,24 +66,34 @@ except importlib.metadata.PackageNotFoundError:
|
|
|
57
66
|
__version__ = "0.0.0-dev"
|
|
58
67
|
|
|
59
68
|
__all__ = [
|
|
69
|
+
"ClassDiff",
|
|
60
70
|
"ClassInfo",
|
|
61
71
|
"ConfigError",
|
|
72
|
+
"DiffResult",
|
|
73
|
+
"EnvironmentSetupError",
|
|
74
|
+
"FunctionDiff",
|
|
62
75
|
"FunctionInfo",
|
|
63
76
|
"InspectionError",
|
|
64
77
|
"LibcontextConfig",
|
|
65
78
|
"LibcontextError",
|
|
79
|
+
"ModuleDiff",
|
|
66
80
|
"ModuleInfo",
|
|
67
81
|
"PackageInfo",
|
|
68
82
|
"PackageNotFoundError",
|
|
69
83
|
"ParameterInfo",
|
|
84
|
+
"VariableDiff",
|
|
70
85
|
"VariableInfo",
|
|
71
86
|
"collect_package",
|
|
87
|
+
"diff_packages",
|
|
72
88
|
"find_package_path",
|
|
73
89
|
"inject_into_file",
|
|
74
90
|
"inspect_file",
|
|
75
91
|
"inspect_source",
|
|
92
|
+
"render_diff",
|
|
76
93
|
"render_module",
|
|
77
94
|
"render_package",
|
|
78
95
|
"render_package_overview",
|
|
79
96
|
"search_package",
|
|
97
|
+
"search_package_structured",
|
|
98
|
+
"suggest_similar_packages",
|
|
80
99
|
]
|