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.
Files changed (72) hide show
  1. sampler_cli-0.4.5/PKG-INFO +234 -0
  2. sampler_cli-0.4.5/README.md +184 -0
  3. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/pyproject.toml +4 -4
  4. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/__init__.py +1 -1
  5. sampler_cli-0.4.5/src/sampler_cli.egg-info/PKG-INFO +234 -0
  6. sampler_cli-0.4.4/PKG-INFO +0 -210
  7. sampler_cli-0.4.4/README.md +0 -160
  8. sampler_cli-0.4.4/src/sampler_cli.egg-info/PKG-INFO +0 -210
  9. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/LICENSE +0 -0
  10. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/setup.cfg +0 -0
  11. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/__main__.py +0 -0
  12. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/cli/__init__.py +0 -0
  13. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/cli/main.py +0 -0
  14. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/cli/render.py +0 -0
  15. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/config.py +0 -0
  16. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/db.py +0 -0
  17. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/embeddings.py +0 -0
  18. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/__init__.py +0 -0
  19. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/builder.py +0 -0
  20. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/discover.py +0 -0
  21. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/embedder.py +0 -0
  22. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/imports.py +0 -0
  23. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/__init__.py +0 -0
  24. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/base.py +0 -0
  25. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/go.py +0 -0
  26. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/python.py +0 -0
  27. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/typescript.py +0 -0
  28. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/parsers/vue.py +0 -0
  29. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/indexer/store.py +0 -0
  30. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/mcp/__init__.py +0 -0
  31. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/mcp/server.py +0 -0
  32. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/models.py +0 -0
  33. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/query/__init__.py +0 -0
  34. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/query/engine.py +0 -0
  35. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/query/semantic.py +0 -0
  36. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/__init__.py +0 -0
  37. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/bus.py +0 -0
  38. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/canvas.py +0 -0
  39. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/discover_emit.py +0 -0
  40. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/engine.py +0 -0
  41. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/events.py +0 -0
  42. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/headline.py +0 -0
  43. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/layout_algo.py +0 -0
  44. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/live.py +0 -0
  45. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler/viz/pipeline.py +0 -0
  46. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/SOURCES.txt +0 -0
  47. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/dependency_links.txt +0 -0
  48. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/entry_points.txt +0 -0
  49. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/requires.txt +0 -0
  50. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/src/sampler_cli.egg-info/top_level.txt +0 -0
  51. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_canvas_graph.py +0 -0
  52. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_cli.py +0 -0
  53. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_config.py +0 -0
  54. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_db.py +0 -0
  55. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_discover.py +0 -0
  56. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_embeddings.py +0 -0
  57. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_events.py +0 -0
  58. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_go_parser.py +0 -0
  59. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_headline.py +0 -0
  60. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_imports.py +0 -0
  61. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_index_query.py +0 -0
  62. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_python_parser.py +0 -0
  63. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_relationships.py +0 -0
  64. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_render_bars.py +0 -0
  65. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_semantic.py +0 -0
  66. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_smoke.py +0 -0
  67. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_stale_code.py +0 -0
  68. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_typescript_parser.py +0 -0
  69. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_viz_engine.py +0 -0
  70. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_viz_layout.py +0 -0
  71. {sampler_cli-0.4.4 → sampler_cli-0.4.5}/tests/test_viz_pipeline.py +0 -0
  72. {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.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/sicr0/sampler-cli"
73
- Repository = "https://github.com/sicr0/sampler-cli"
74
- Issues = "https://github.com/sicr0/sampler-cli/issues"
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"
@@ -1,3 +1,3 @@
1
1
  __all__ = ["__version__"]
2
2
 
3
- __version__ = "0.4.4"
3
+ __version__ = "0.4.5"
@@ -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).