sampler-cli 0.4.4__tar.gz → 0.4.5__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.
- sampler_cli-0.4.5/PKG-INFO +234 -0
- sampler_cli-0.4.5/README.md +184 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/pyproject.toml +4 -4
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/__init__.py +1 -1
- sampler_cli-0.4.5/src/sampler_cli.egg-info/PKG-INFO +234 -0
- sampler_cli-0.4.4/PKG-INFO +0 -210
- sampler_cli-0.4.4/README.md +0 -160
- sampler_cli-0.4.4/src/sampler_cli.egg-info/PKG-INFO +0 -210
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/LICENSE +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/setup.cfg +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/__main__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/cli/__init__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/cli/main.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/cli/render.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/config.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/db.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/embeddings.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/__init__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/builder.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/discover.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/embedder.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/imports.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/__init__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/base.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/go.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/python.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/typescript.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/vue.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/store.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/mcp/__init__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/mcp/server.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/models.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/query/__init__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/query/engine.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/query/semantic.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/__init__.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/bus.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/canvas.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/discover_emit.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/engine.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/events.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/headline.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/layout_algo.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/live.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/pipeline.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/SOURCES.txt +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/dependency_links.txt +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/entry_points.txt +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/requires.txt +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/top_level.txt +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_canvas_graph.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_cli.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_config.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_db.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_discover.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_embeddings.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_events.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_go_parser.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_headline.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_imports.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_index_query.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_python_parser.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_relationships.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_render_bars.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_semantic.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_smoke.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_stale_code.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_typescript_parser.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_viz_engine.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_viz_layout.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_viz_pipeline.py +0 -0
- {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_vue_parser.py +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sampler-cli
|
|
3
|
+
Version: 0.4.5
|
|
4
|
+
Summary: Token-efficient CLI for indexing and searching code symbols (Python-first, designed for minimal LLM/agent context size)
|
|
5
|
+
Author: Samuel Ignacio Carmona Rodriguez
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/SamuelCarmona83/sampler-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/SamuelCarmona83/sampler-cli
|
|
9
|
+
Project-URL: Issues, https://github.com/SamuelCarmona83/sampler-cli/issues
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: typer>=0.12.0
|
|
21
|
+
Requires-Dist: rich>=13.7.0
|
|
22
|
+
Requires-Dist: tree-sitter>=0.21.0
|
|
23
|
+
Requires-Dist: tree-sitter-python>=0.23.0
|
|
24
|
+
Requires-Dist: tree-sitter-go>=0.23.0
|
|
25
|
+
Requires-Dist: tree-sitter-typescript>=0.23.0
|
|
26
|
+
Requires-Dist: gitignore-parser>=0.1.11
|
|
27
|
+
Requires-Dist: pydantic>=2.6.0
|
|
28
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: numpy>=1.26.0; extra == "dev"
|
|
35
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == "dev"
|
|
36
|
+
Requires-Dist: fastembed>=0.2.0; extra == "dev"
|
|
37
|
+
Provides-Extra: mcp
|
|
38
|
+
Requires-Dist: fastmcp>=0.1.0; extra == "mcp"
|
|
39
|
+
Provides-Extra: semantic
|
|
40
|
+
Requires-Dist: numpy>=1.26.0; extra == "semantic"
|
|
41
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == "semantic"
|
|
42
|
+
Provides-Extra: embeddings
|
|
43
|
+
Requires-Dist: fastembed>=0.2.0; extra == "embeddings"
|
|
44
|
+
Requires-Dist: numpy>=1.26.0; extra == "embeddings"
|
|
45
|
+
Provides-Extra: ollama-embeddings
|
|
46
|
+
Requires-Dist: ollama>=0.3.0; extra == "ollama-embeddings"
|
|
47
|
+
Provides-Extra: openai-embeddings
|
|
48
|
+
Requires-Dist: openai>=1.0.0; extra == "openai-embeddings"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img src="./assets/sampler.png" alt="Sampler logo" width="220">
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<h1 align="center">Sampler</h1>
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<strong>Token-efficient CLI for indexing and searching code symbols across projects.</strong><br>
|
|
59
|
+
Compact output. Short paths. Low-noise symbol views.
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<a href="https://pypi.org/project/sampler-cli/"><img src="https://img.shields.io/pypi/v/sampler-cli" alt="PyPI version"></a>
|
|
64
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+">
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
> *The code isn't the problem. The problem is the distance between you and the code.*
|
|
70
|
+
>
|
|
71
|
+
> Sampler closes that distance. One index. One query. The right symbol, the right relationship, the right context — delivered without the noise. Because in a world drowning in repositories, the person who finds what matters first is the person who moves the work forward.
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install sampler-cli
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Development:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install -e '.[dev]'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Semantic stack (TF-IDF + local hash fallback):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install -e '.[semantic]'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Quick Start
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
sampler init
|
|
95
|
+
sampler project add myproj /absolute/path/to/project --language auto
|
|
96
|
+
sampler index myproj
|
|
97
|
+
sampler search retry --project myproj
|
|
98
|
+
sampler symbols myproj
|
|
99
|
+
sampler overview src/main.py
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Commands
|
|
103
|
+
|
|
104
|
+
### Core
|
|
105
|
+
|
|
106
|
+
| Command | Description |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `sampler version [--plain]` | Show version |
|
|
109
|
+
| `sampler init` | Initialize Sampler config and data directory |
|
|
110
|
+
| `sampler index <project>` | Index a project's symbols and relationships |
|
|
111
|
+
| `sampler search <query>` | Search symbols across a project |
|
|
112
|
+
| `sampler search-all <query>` | Search across all indexed projects |
|
|
113
|
+
| `sampler symbols <project>` | List symbols in a project |
|
|
114
|
+
| `sampler overview <filepath>` | Show symbol overview for a file |
|
|
115
|
+
|
|
116
|
+
**Search options:** `--project`, `--type`, `--limit`, `--semantic`, `--style plain|bars`
|
|
117
|
+
|
|
118
|
+
### Relationships
|
|
119
|
+
|
|
120
|
+
| Command | Description |
|
|
121
|
+
| --- | --- |
|
|
122
|
+
| `sampler callers <symbol>` | Find callers of a symbol |
|
|
123
|
+
| `sampler usages <symbol>` | Find usages of a symbol |
|
|
124
|
+
| `sampler related <symbol>` | Find related symbols |
|
|
125
|
+
|
|
126
|
+
Symbols can also be selected as `<path>:<symbol>`, e.g. `app/utils/helpers.py:format_kda`.
|
|
127
|
+
|
|
128
|
+
### Project Management
|
|
129
|
+
|
|
130
|
+
| Command | Description |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `sampler project add <name> <path> --language <lang>` | Add a project |
|
|
133
|
+
| `sampler project update <name>` | Update project path or language |
|
|
134
|
+
| `sampler project list` | List projects |
|
|
135
|
+
| `sampler project deps <name>` | Show project dependencies |
|
|
136
|
+
| `sampler project remove <name>` | Remove a project |
|
|
137
|
+
|
|
138
|
+
Languages: `python`, `go`, `typescript`, `javascript`, `vue`, `auto`.
|
|
139
|
+
|
|
140
|
+
### Config & Analysis
|
|
141
|
+
|
|
142
|
+
| Command | Description |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| `sampler config show` | Show current config |
|
|
145
|
+
| `sampler config embeddings` | Configure embedding provider |
|
|
146
|
+
| `sampler embed <project>` | Precompute embeddings |
|
|
147
|
+
| `sampler stale-code <project>` | Find candidate stale code |
|
|
148
|
+
|
|
149
|
+
## Embeddings & Semantic Search
|
|
150
|
+
|
|
151
|
+
`sampler search --semantic` uses a pluggable adapter pattern:
|
|
152
|
+
|
|
153
|
+
- **Default:** `bge-small` (BAAI/bge-small-en-v1.5 via fastembed — local ONNX, ~384 dim)
|
|
154
|
+
- **Built-ins:** `hash` (deterministic fallback), `ollama`, `nomic`, `openai`, `fastembed`
|
|
155
|
+
- **Lexical primary:** TF-IDF (sklearn, on-the-fly, no pre-embedding required)
|
|
156
|
+
- **Final fallback:** hash fingerprint (always available)
|
|
157
|
+
|
|
158
|
+
Configure in `~/.sampler/config.yaml` or via `sampler config embeddings`:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
embeddings:
|
|
162
|
+
provider: "bge-small"
|
|
163
|
+
# provider: "ollama"
|
|
164
|
+
# model: "nomic-embed-text"
|
|
165
|
+
# base_url: "http://localhost:11434"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Install extras:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pip install 'sampler-cli[embeddings]' # BGE (recommended)
|
|
172
|
+
pip install 'sampler-cli[ollama-embeddings]'
|
|
173
|
+
pip install 'sampler-cli[openai-embeddings]'
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Run `sampler embed <project>` to precompute vectors for the active provider. Change providers? Re-run `embed` after updating config.
|
|
177
|
+
|
|
178
|
+
Offline or air-gapped: set `provider: hash`, or rely on TF-IDF + hash with the `[semantic]` extra.
|
|
179
|
+
|
|
180
|
+
## Language Support
|
|
181
|
+
|
|
182
|
+
| Language | Parser |
|
|
183
|
+
| --- | --- |
|
|
184
|
+
| Python | stdlib AST |
|
|
185
|
+
| Go | tree-sitter-go |
|
|
186
|
+
| TypeScript / JavaScript | tree-sitter-typescript |
|
|
187
|
+
| Vue | Extracts `<script>` / `<script setup>`, delegates to TS/JS parser |
|
|
188
|
+
| Auto | Per-file detection for monorepos and multi-language projects |
|
|
189
|
+
|
|
190
|
+
## Stale Code Detection
|
|
191
|
+
|
|
192
|
+
`sampler stale-code <project>` finds functions that may no longer be needed:
|
|
193
|
+
|
|
194
|
+
- Called only from test files
|
|
195
|
+
- Zero non-test callers in the project call graph
|
|
196
|
+
- Defined in production code
|
|
197
|
+
|
|
198
|
+
Supported test patterns:
|
|
199
|
+
|
|
200
|
+
- Python: `tests/`, `test_*.py`, `*_test.py`
|
|
201
|
+
- Go: `*_test.go`
|
|
202
|
+
- TypeScript / JavaScript / Vue: `__tests__/`, `test/`, `spec/`, `*.test.*`, `*.spec.*`
|
|
203
|
+
|
|
204
|
+
This is a heuristic signal, not a guarantee of dead code.
|
|
205
|
+
|
|
206
|
+
## Examples
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
$ sampler search worker --project myproj
|
|
210
|
+
myproj:src/tasks/celery_app.py:70 function on_worker_ready def on_worker_ready(sender)
|
|
211
|
+
|
|
212
|
+
$ sampler related ConfigManager --project myproj --style bars
|
|
213
|
+
myproj:src/config.py:24-105 class ConfigManager [parent]
|
|
214
|
+
...
|
|
215
|
+
|
|
216
|
+
$ sampler stale-code myproj
|
|
217
|
+
myproj:src/utils/retry.py:12-28 function retry_request test_callers=2 non_test_callers=0 [tests.test_retry.test_retry_request]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Data Location
|
|
221
|
+
|
|
222
|
+
- Config: `~/.sampler/config.yaml`
|
|
223
|
+
- Database: `~/.sampler/graph.db`
|
|
224
|
+
|
|
225
|
+
## Running Tests
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
pytest -q
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Notes
|
|
232
|
+
|
|
233
|
+
- Compact output is the default by design — built for agent workflows and fast human scanning.
|
|
234
|
+
- For roadmap details, see [TODO.md](TODO.md) and [PLAN.md](PLAN.md).
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./assets/sampler.png" alt="Sampler logo" width="220">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Sampler</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Token-efficient CLI for indexing and searching code symbols across projects.</strong><br>
|
|
9
|
+
Compact output. Short paths. Low-noise symbol views.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://pypi.org/project/sampler-cli/"><img src="https://img.shields.io/pypi/v/sampler-cli" alt="PyPI version"></a>
|
|
14
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+">
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
> *The code isn't the problem. The problem is the distance between you and the code.*
|
|
20
|
+
>
|
|
21
|
+
> Sampler closes that distance. One index. One query. The right symbol, the right relationship, the right context — delivered without the noise. Because in a world drowning in repositories, the person who finds what matters first is the person who moves the work forward.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install sampler-cli
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Development:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install -e '.[dev]'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Semantic stack (TF-IDF + local hash fallback):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install -e '.[semantic]'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
sampler init
|
|
45
|
+
sampler project add myproj /absolute/path/to/project --language auto
|
|
46
|
+
sampler index myproj
|
|
47
|
+
sampler search retry --project myproj
|
|
48
|
+
sampler symbols myproj
|
|
49
|
+
sampler overview src/main.py
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Commands
|
|
53
|
+
|
|
54
|
+
### Core
|
|
55
|
+
|
|
56
|
+
| Command | Description |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| `sampler version [--plain]` | Show version |
|
|
59
|
+
| `sampler init` | Initialize Sampler config and data directory |
|
|
60
|
+
| `sampler index <project>` | Index a project's symbols and relationships |
|
|
61
|
+
| `sampler search <query>` | Search symbols across a project |
|
|
62
|
+
| `sampler search-all <query>` | Search across all indexed projects |
|
|
63
|
+
| `sampler symbols <project>` | List symbols in a project |
|
|
64
|
+
| `sampler overview <filepath>` | Show symbol overview for a file |
|
|
65
|
+
|
|
66
|
+
**Search options:** `--project`, `--type`, `--limit`, `--semantic`, `--style plain|bars`
|
|
67
|
+
|
|
68
|
+
### Relationships
|
|
69
|
+
|
|
70
|
+
| Command | Description |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `sampler callers <symbol>` | Find callers of a symbol |
|
|
73
|
+
| `sampler usages <symbol>` | Find usages of a symbol |
|
|
74
|
+
| `sampler related <symbol>` | Find related symbols |
|
|
75
|
+
|
|
76
|
+
Symbols can also be selected as `<path>:<symbol>`, e.g. `app/utils/helpers.py:format_kda`.
|
|
77
|
+
|
|
78
|
+
### Project Management
|
|
79
|
+
|
|
80
|
+
| Command | Description |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `sampler project add <name> <path> --language <lang>` | Add a project |
|
|
83
|
+
| `sampler project update <name>` | Update project path or language |
|
|
84
|
+
| `sampler project list` | List projects |
|
|
85
|
+
| `sampler project deps <name>` | Show project dependencies |
|
|
86
|
+
| `sampler project remove <name>` | Remove a project |
|
|
87
|
+
|
|
88
|
+
Languages: `python`, `go`, `typescript`, `javascript`, `vue`, `auto`.
|
|
89
|
+
|
|
90
|
+
### Config & Analysis
|
|
91
|
+
|
|
92
|
+
| Command | Description |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| `sampler config show` | Show current config |
|
|
95
|
+
| `sampler config embeddings` | Configure embedding provider |
|
|
96
|
+
| `sampler embed <project>` | Precompute embeddings |
|
|
97
|
+
| `sampler stale-code <project>` | Find candidate stale code |
|
|
98
|
+
|
|
99
|
+
## Embeddings & Semantic Search
|
|
100
|
+
|
|
101
|
+
`sampler search --semantic` uses a pluggable adapter pattern:
|
|
102
|
+
|
|
103
|
+
- **Default:** `bge-small` (BAAI/bge-small-en-v1.5 via fastembed — local ONNX, ~384 dim)
|
|
104
|
+
- **Built-ins:** `hash` (deterministic fallback), `ollama`, `nomic`, `openai`, `fastembed`
|
|
105
|
+
- **Lexical primary:** TF-IDF (sklearn, on-the-fly, no pre-embedding required)
|
|
106
|
+
- **Final fallback:** hash fingerprint (always available)
|
|
107
|
+
|
|
108
|
+
Configure in `~/.sampler/config.yaml` or via `sampler config embeddings`:
|
|
109
|
+
|
|
110
|
+
```yaml
|
|
111
|
+
embeddings:
|
|
112
|
+
provider: "bge-small"
|
|
113
|
+
# provider: "ollama"
|
|
114
|
+
# model: "nomic-embed-text"
|
|
115
|
+
# base_url: "http://localhost:11434"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Install extras:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pip install 'sampler-cli[embeddings]' # BGE (recommended)
|
|
122
|
+
pip install 'sampler-cli[ollama-embeddings]'
|
|
123
|
+
pip install 'sampler-cli[openai-embeddings]'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Run `sampler embed <project>` to precompute vectors for the active provider. Change providers? Re-run `embed` after updating config.
|
|
127
|
+
|
|
128
|
+
Offline or air-gapped: set `provider: hash`, or rely on TF-IDF + hash with the `[semantic]` extra.
|
|
129
|
+
|
|
130
|
+
## Language Support
|
|
131
|
+
|
|
132
|
+
| Language | Parser |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| Python | stdlib AST |
|
|
135
|
+
| Go | tree-sitter-go |
|
|
136
|
+
| TypeScript / JavaScript | tree-sitter-typescript |
|
|
137
|
+
| Vue | Extracts `<script>` / `<script setup>`, delegates to TS/JS parser |
|
|
138
|
+
| Auto | Per-file detection for monorepos and multi-language projects |
|
|
139
|
+
|
|
140
|
+
## Stale Code Detection
|
|
141
|
+
|
|
142
|
+
`sampler stale-code <project>` finds functions that may no longer be needed:
|
|
143
|
+
|
|
144
|
+
- Called only from test files
|
|
145
|
+
- Zero non-test callers in the project call graph
|
|
146
|
+
- Defined in production code
|
|
147
|
+
|
|
148
|
+
Supported test patterns:
|
|
149
|
+
|
|
150
|
+
- Python: `tests/`, `test_*.py`, `*_test.py`
|
|
151
|
+
- Go: `*_test.go`
|
|
152
|
+
- TypeScript / JavaScript / Vue: `__tests__/`, `test/`, `spec/`, `*.test.*`, `*.spec.*`
|
|
153
|
+
|
|
154
|
+
This is a heuristic signal, not a guarantee of dead code.
|
|
155
|
+
|
|
156
|
+
## Examples
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
$ sampler search worker --project myproj
|
|
160
|
+
myproj:src/tasks/celery_app.py:70 function on_worker_ready def on_worker_ready(sender)
|
|
161
|
+
|
|
162
|
+
$ sampler related ConfigManager --project myproj --style bars
|
|
163
|
+
myproj:src/config.py:24-105 class ConfigManager [parent]
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
$ sampler stale-code myproj
|
|
167
|
+
myproj:src/utils/retry.py:12-28 function retry_request test_callers=2 non_test_callers=0 [tests.test_retry.test_retry_request]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Data Location
|
|
171
|
+
|
|
172
|
+
- Config: `~/.sampler/config.yaml`
|
|
173
|
+
- Database: `~/.sampler/graph.db`
|
|
174
|
+
|
|
175
|
+
## Running Tests
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pytest -q
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Notes
|
|
182
|
+
|
|
183
|
+
- Compact output is the default by design — built for agent workflows and fast human scanning.
|
|
184
|
+
- For roadmap details, see [TODO.md](TODO.md) and [PLAN.md](PLAN.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sampler-cli"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.5"
|
|
4
4
|
description = "Token-efficient CLI for indexing and searching code symbols (Python-first, designed for minimal LLM/agent context size)"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -69,6 +69,6 @@ pythonpath = ["src"]
|
|
|
69
69
|
testpaths = ["tests"]
|
|
70
70
|
|
|
71
71
|
[project.urls]
|
|
72
|
-
Homepage = "https://github.com/
|
|
73
|
-
Repository = "https://github.com/
|
|
74
|
-
Issues = "https://github.com/
|
|
72
|
+
Homepage = "https://github.com/SamuelCarmona83/sampler-cli"
|
|
73
|
+
Repository = "https://github.com/SamuelCarmona83/sampler-cli"
|
|
74
|
+
Issues = "https://github.com/SamuelCarmona83/sampler-cli/issues"
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sampler-cli
|
|
3
|
+
Version: 0.4.5
|
|
4
|
+
Summary: Token-efficient CLI for indexing and searching code symbols (Python-first, designed for minimal LLM/agent context size)
|
|
5
|
+
Author: Samuel Ignacio Carmona Rodriguez
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/SamuelCarmona83/sampler-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/SamuelCarmona83/sampler-cli
|
|
9
|
+
Project-URL: Issues, https://github.com/SamuelCarmona83/sampler-cli/issues
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: typer>=0.12.0
|
|
21
|
+
Requires-Dist: rich>=13.7.0
|
|
22
|
+
Requires-Dist: tree-sitter>=0.21.0
|
|
23
|
+
Requires-Dist: tree-sitter-python>=0.23.0
|
|
24
|
+
Requires-Dist: tree-sitter-go>=0.23.0
|
|
25
|
+
Requires-Dist: tree-sitter-typescript>=0.23.0
|
|
26
|
+
Requires-Dist: gitignore-parser>=0.1.11
|
|
27
|
+
Requires-Dist: pydantic>=2.6.0
|
|
28
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: numpy>=1.26.0; extra == "dev"
|
|
35
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == "dev"
|
|
36
|
+
Requires-Dist: fastembed>=0.2.0; extra == "dev"
|
|
37
|
+
Provides-Extra: mcp
|
|
38
|
+
Requires-Dist: fastmcp>=0.1.0; extra == "mcp"
|
|
39
|
+
Provides-Extra: semantic
|
|
40
|
+
Requires-Dist: numpy>=1.26.0; extra == "semantic"
|
|
41
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == "semantic"
|
|
42
|
+
Provides-Extra: embeddings
|
|
43
|
+
Requires-Dist: fastembed>=0.2.0; extra == "embeddings"
|
|
44
|
+
Requires-Dist: numpy>=1.26.0; extra == "embeddings"
|
|
45
|
+
Provides-Extra: ollama-embeddings
|
|
46
|
+
Requires-Dist: ollama>=0.3.0; extra == "ollama-embeddings"
|
|
47
|
+
Provides-Extra: openai-embeddings
|
|
48
|
+
Requires-Dist: openai>=1.0.0; extra == "openai-embeddings"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img src="./assets/sampler.png" alt="Sampler logo" width="220">
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<h1 align="center">Sampler</h1>
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<strong>Token-efficient CLI for indexing and searching code symbols across projects.</strong><br>
|
|
59
|
+
Compact output. Short paths. Low-noise symbol views.
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<a href="https://pypi.org/project/sampler-cli/"><img src="https://img.shields.io/pypi/v/sampler-cli" alt="PyPI version"></a>
|
|
64
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+">
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
> *The code isn't the problem. The problem is the distance between you and the code.*
|
|
70
|
+
>
|
|
71
|
+
> Sampler closes that distance. One index. One query. The right symbol, the right relationship, the right context — delivered without the noise. Because in a world drowning in repositories, the person who finds what matters first is the person who moves the work forward.
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install sampler-cli
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Development:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install -e '.[dev]'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Semantic stack (TF-IDF + local hash fallback):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install -e '.[semantic]'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Quick Start
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
sampler init
|
|
95
|
+
sampler project add myproj /absolute/path/to/project --language auto
|
|
96
|
+
sampler index myproj
|
|
97
|
+
sampler search retry --project myproj
|
|
98
|
+
sampler symbols myproj
|
|
99
|
+
sampler overview src/main.py
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Commands
|
|
103
|
+
|
|
104
|
+
### Core
|
|
105
|
+
|
|
106
|
+
| Command | Description |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `sampler version [--plain]` | Show version |
|
|
109
|
+
| `sampler init` | Initialize Sampler config and data directory |
|
|
110
|
+
| `sampler index <project>` | Index a project's symbols and relationships |
|
|
111
|
+
| `sampler search <query>` | Search symbols across a project |
|
|
112
|
+
| `sampler search-all <query>` | Search across all indexed projects |
|
|
113
|
+
| `sampler symbols <project>` | List symbols in a project |
|
|
114
|
+
| `sampler overview <filepath>` | Show symbol overview for a file |
|
|
115
|
+
|
|
116
|
+
**Search options:** `--project`, `--type`, `--limit`, `--semantic`, `--style plain|bars`
|
|
117
|
+
|
|
118
|
+
### Relationships
|
|
119
|
+
|
|
120
|
+
| Command | Description |
|
|
121
|
+
| --- | --- |
|
|
122
|
+
| `sampler callers <symbol>` | Find callers of a symbol |
|
|
123
|
+
| `sampler usages <symbol>` | Find usages of a symbol |
|
|
124
|
+
| `sampler related <symbol>` | Find related symbols |
|
|
125
|
+
|
|
126
|
+
Symbols can also be selected as `<path>:<symbol>`, e.g. `app/utils/helpers.py:format_kda`.
|
|
127
|
+
|
|
128
|
+
### Project Management
|
|
129
|
+
|
|
130
|
+
| Command | Description |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `sampler project add <name> <path> --language <lang>` | Add a project |
|
|
133
|
+
| `sampler project update <name>` | Update project path or language |
|
|
134
|
+
| `sampler project list` | List projects |
|
|
135
|
+
| `sampler project deps <name>` | Show project dependencies |
|
|
136
|
+
| `sampler project remove <name>` | Remove a project |
|
|
137
|
+
|
|
138
|
+
Languages: `python`, `go`, `typescript`, `javascript`, `vue`, `auto`.
|
|
139
|
+
|
|
140
|
+
### Config & Analysis
|
|
141
|
+
|
|
142
|
+
| Command | Description |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| `sampler config show` | Show current config |
|
|
145
|
+
| `sampler config embeddings` | Configure embedding provider |
|
|
146
|
+
| `sampler embed <project>` | Precompute embeddings |
|
|
147
|
+
| `sampler stale-code <project>` | Find candidate stale code |
|
|
148
|
+
|
|
149
|
+
## Embeddings & Semantic Search
|
|
150
|
+
|
|
151
|
+
`sampler search --semantic` uses a pluggable adapter pattern:
|
|
152
|
+
|
|
153
|
+
- **Default:** `bge-small` (BAAI/bge-small-en-v1.5 via fastembed — local ONNX, ~384 dim)
|
|
154
|
+
- **Built-ins:** `hash` (deterministic fallback), `ollama`, `nomic`, `openai`, `fastembed`
|
|
155
|
+
- **Lexical primary:** TF-IDF (sklearn, on-the-fly, no pre-embedding required)
|
|
156
|
+
- **Final fallback:** hash fingerprint (always available)
|
|
157
|
+
|
|
158
|
+
Configure in `~/.sampler/config.yaml` or via `sampler config embeddings`:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
embeddings:
|
|
162
|
+
provider: "bge-small"
|
|
163
|
+
# provider: "ollama"
|
|
164
|
+
# model: "nomic-embed-text"
|
|
165
|
+
# base_url: "http://localhost:11434"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Install extras:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pip install 'sampler-cli[embeddings]' # BGE (recommended)
|
|
172
|
+
pip install 'sampler-cli[ollama-embeddings]'
|
|
173
|
+
pip install 'sampler-cli[openai-embeddings]'
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Run `sampler embed <project>` to precompute vectors for the active provider. Change providers? Re-run `embed` after updating config.
|
|
177
|
+
|
|
178
|
+
Offline or air-gapped: set `provider: hash`, or rely on TF-IDF + hash with the `[semantic]` extra.
|
|
179
|
+
|
|
180
|
+
## Language Support
|
|
181
|
+
|
|
182
|
+
| Language | Parser |
|
|
183
|
+
| --- | --- |
|
|
184
|
+
| Python | stdlib AST |
|
|
185
|
+
| Go | tree-sitter-go |
|
|
186
|
+
| TypeScript / JavaScript | tree-sitter-typescript |
|
|
187
|
+
| Vue | Extracts `<script>` / `<script setup>`, delegates to TS/JS parser |
|
|
188
|
+
| Auto | Per-file detection for monorepos and multi-language projects |
|
|
189
|
+
|
|
190
|
+
## Stale Code Detection
|
|
191
|
+
|
|
192
|
+
`sampler stale-code <project>` finds functions that may no longer be needed:
|
|
193
|
+
|
|
194
|
+
- Called only from test files
|
|
195
|
+
- Zero non-test callers in the project call graph
|
|
196
|
+
- Defined in production code
|
|
197
|
+
|
|
198
|
+
Supported test patterns:
|
|
199
|
+
|
|
200
|
+
- Python: `tests/`, `test_*.py`, `*_test.py`
|
|
201
|
+
- Go: `*_test.go`
|
|
202
|
+
- TypeScript / JavaScript / Vue: `__tests__/`, `test/`, `spec/`, `*.test.*`, `*.spec.*`
|
|
203
|
+
|
|
204
|
+
This is a heuristic signal, not a guarantee of dead code.
|
|
205
|
+
|
|
206
|
+
## Examples
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
$ sampler search worker --project myproj
|
|
210
|
+
myproj:src/tasks/celery_app.py:70 function on_worker_ready def on_worker_ready(sender)
|
|
211
|
+
|
|
212
|
+
$ sampler related ConfigManager --project myproj --style bars
|
|
213
|
+
myproj:src/config.py:24-105 class ConfigManager [parent]
|
|
214
|
+
...
|
|
215
|
+
|
|
216
|
+
$ sampler stale-code myproj
|
|
217
|
+
myproj:src/utils/retry.py:12-28 function retry_request test_callers=2 non_test_callers=0 [tests.test_retry.test_retry_request]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Data Location
|
|
221
|
+
|
|
222
|
+
- Config: `~/.sampler/config.yaml`
|
|
223
|
+
- Database: `~/.sampler/graph.db`
|
|
224
|
+
|
|
225
|
+
## Running Tests
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
pytest -q
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Notes
|
|
232
|
+
|
|
233
|
+
- Compact output is the default by design — built for agent workflows and fast human scanning.
|
|
234
|
+
- For roadmap details, see [TODO.md](TODO.md) and [PLAN.md](PLAN.md).
|