rag-your-code 0.4.1__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 (39) hide show
  1. rag_your_code-0.4.1/LICENSE +21 -0
  2. rag_your_code-0.4.1/PKG-INFO +237 -0
  3. rag_your_code-0.4.1/README.md +210 -0
  4. rag_your_code-0.4.1/pyproject.toml +53 -0
  5. rag_your_code-0.4.1/setup.cfg +4 -0
  6. rag_your_code-0.4.1/src/rag_your_code.egg-info/PKG-INFO +237 -0
  7. rag_your_code-0.4.1/src/rag_your_code.egg-info/SOURCES.txt +37 -0
  8. rag_your_code-0.4.1/src/rag_your_code.egg-info/dependency_links.txt +1 -0
  9. rag_your_code-0.4.1/src/rag_your_code.egg-info/entry_points.txt +2 -0
  10. rag_your_code-0.4.1/src/rag_your_code.egg-info/requires.txt +6 -0
  11. rag_your_code-0.4.1/src/rag_your_code.egg-info/top_level.txt +1 -0
  12. rag_your_code-0.4.1/src/ragyourcode/__init__.py +6 -0
  13. rag_your_code-0.4.1/src/ragyourcode/agentic.py +55 -0
  14. rag_your_code-0.4.1/src/ragyourcode/annotate.py +35 -0
  15. rag_your_code-0.4.1/src/ragyourcode/cli.py +575 -0
  16. rag_your_code-0.4.1/src/ragyourcode/config.py +572 -0
  17. rag_your_code-0.4.1/src/ragyourcode/descriptions.py +248 -0
  18. rag_your_code-0.4.1/src/ragyourcode/embeddings.py +60 -0
  19. rag_your_code-0.4.1/src/ragyourcode/graph.py +198 -0
  20. rag_your_code-0.4.1/src/ragyourcode/indexer.py +411 -0
  21. rag_your_code-0.4.1/src/ragyourcode/models.py +86 -0
  22. rag_your_code-0.4.1/src/ragyourcode/parser.py +485 -0
  23. rag_your_code-0.4.1/src/ragyourcode/py.typed +0 -0
  24. rag_your_code-0.4.1/src/ragyourcode/search.py +131 -0
  25. rag_your_code-0.4.1/tests/test_agent_protocol.py +95 -0
  26. rag_your_code-0.4.1/tests/test_agentic.py +29 -0
  27. rag_your_code-0.4.1/tests/test_config.py +336 -0
  28. rag_your_code-0.4.1/tests/test_descriptions.py +342 -0
  29. rag_your_code-0.4.1/tests/test_e2e_cli.py +106 -0
  30. rag_your_code-0.4.1/tests/test_golden.py +31 -0
  31. rag_your_code-0.4.1/tests/test_graph_incremental.py +114 -0
  32. rag_your_code-0.4.1/tests/test_language_fixtures.py +110 -0
  33. rag_your_code-0.4.1/tests/test_large_repo.py +19 -0
  34. rag_your_code-0.4.1/tests/test_metadata.py +138 -0
  35. rag_your_code-0.4.1/tests/test_multilanguage.py +25 -0
  36. rag_your_code-0.4.1/tests/test_parser_edges.py +12 -0
  37. rag_your_code-0.4.1/tests/test_ragyourcode.py +109 -0
  38. rag_your_code-0.4.1/tests/test_resilience.py +116 -0
  39. rag_your_code-0.4.1/tests/test_retrieval_correctness.py +113 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rag-your-code contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: rag-your-code
3
+ Version: 0.4.1
4
+ Summary: A local, explainable RAG index for codebases and coding agents
5
+ Author: rag-your-code contributors
6
+ License-Expression: MIT
7
+ Keywords: rag,code-search,retrieval,indexing,graphrag,offline,explainable,agent
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Topic :: Text Processing :: Indexing
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7; extra == "dev"
25
+ Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # RAG Your Code
29
+
30
+ `rag-your-code` is the **R** in RAG: a local, explainable retrieval index over a
31
+ codebase. The generation half stays in your agent. It scans functions, methods
32
+ and classes across Python and fourteen other languages, assigns stable serial
33
+ numbers, and answers queries with a file, a line range, the terms that matched,
34
+ and the source itself.
35
+
36
+ No network calls and no runtime dependencies, by design rather than by
37
+ omission — it is meant to run over a private repository on a machine with the
38
+ network turned off, and to produce an index you can read.
39
+
40
+ ## What the embedding does, and what it does not
41
+
42
+ This matters more than any feature list, so it is stated up front rather than
43
+ in a footnote.
44
+
45
+ The embedder is a **signed feature hash**: it hashes tokens into 384 buckets.
46
+ Cosine similarity over those vectors is therefore a normalised measure of
47
+ *token overlap*, and it carries no semantics whatever:
48
+
49
+ | pair | cosine |
50
+ |---|---|
51
+ | `retry failed card charge` vs itself | 1.0000 |
52
+ | `sum two numbers` vs `add a pair of integers` | **0.0000** |
53
+ | `计算两个数的和` vs `sum two numbers` | **0.0000** |
54
+ | `sum two numbers` vs `delete the user database table` | 0.0000 |
55
+
56
+ A trained embedding model scores row 2 around 0.8. Here a synonym pair and an
57
+ unrelated pair are indistinguishable, because zero shared tokens is zero either
58
+ way.
59
+
60
+ Retrieval works anyway, because **identifiers and docstrings are already
61
+ natural language**: `retry_charge` contains the words *retry* and *charge*. But
62
+ it reaches only concepts someone wrote down. Two mechanisms close the rest of
63
+ the gap, and neither of them is a model:
64
+
65
+ - **Your agent rewrites the query.** It has the conversation; turning "重试扣款"
66
+ into `retry charge payment gateway` costs it nothing.
67
+ - **Your agent writes the descriptions** (see below), which puts the missing
68
+ vocabulary into the index once instead of into every query.
69
+
70
+ ## Quick start
71
+
72
+ ```bash
73
+ # Not on PyPI. Take the wheel from the latest release, or install the source:
74
+ # https://github.com/skymanbp/rag-your-code/releases
75
+ pip install ./rag_your_code-0.4.0-py3-none-any.whl
76
+ # ... or, from a clone: python -m pip install -e .
77
+
78
+ rag-your-code index .
79
+ rag-your-code search "where are HTTP retries handled" --json
80
+ rag-your-code search "what calls the retry handler" --graph --hops 1 --json
81
+ rag-your-code annotate
82
+ ```
83
+
84
+ The index and annotations are written under `.rag-your-code/`; source files are
85
+ never modified. Use `--json` when feeding results to an agent.
86
+
87
+ For a large repository prefer `rag-your-code index . --compact`. Later
88
+ `index` runs and the agent's `refresh` reuse unchanged files and preserve
89
+ global serials; `--full` discards the cache.
90
+
91
+ ## Agent-authored descriptions
92
+
93
+ Every unit carries a description, and that description is indexed. By default
94
+ it is generated without a model: the identifier humanised, the parameter and
95
+ callee names listed, the docstring appended. That introduces no vocabulary the
96
+ source did not already contain, which is exactly why retrieval cannot reach a
97
+ concept nobody wrote down.
98
+
99
+ The agent already reading this index can supply those words:
100
+
101
+ ```bash
102
+ rag-your-code describe status # coverage, and what is pending
103
+ rag-your-code describe export --limit 20 # a batch, with source and a brief
104
+ rag-your-code describe import written.json # store what the agent wrote
105
+ rag-your-code index . # apply it
106
+ ```
107
+
108
+ or, in the JSON-lines protocol, `describe_pending` and `describe_put` — which
109
+ take effect in the same session, without a refresh.
110
+
111
+ Measured on the fixture repository, replacing one generated sentence with an
112
+ agent-written bilingual one:
113
+
114
+ | query | generated description | agent description |
115
+ |---|---|---|
116
+ | `exponential backoff` | no lexical evidence | **#1**, 1.0172 |
117
+ | `double billing safety` | no lexical evidence | **#1**, 0.3404 |
118
+ | `支付网关超时` | no lexical evidence | **#1**, 0.8632 |
119
+
120
+ **What this is:** it moves the semantic work from query time to index time.
121
+ Matching stays lexical — a description saying `retry` still cannot answer a
122
+ query saying `resend` unless the description also says so. It is LLM-authored
123
+ keyword expansion, and its reach is bounded by how many ways of saying the
124
+ thing the agent thought to write down.
125
+
126
+ Descriptions live in `rag-your-code.descriptions.json` at the repository root
127
+ and are meant to be committed, so one person's pass benefits everyone who
128
+ clones. Each is keyed by unit id **and a digest of the unit's source**: when
129
+ the code changes the description is not applied, the unit returns to the
130
+ pending queue, and retrieval falls back to the generated sentence. A
131
+ description that outlived its code would be a confident wrong answer, which is
132
+ the one thing this index is built not to give.
133
+
134
+ ## Configuration
135
+
136
+ Twelve settings live in `rag-your-code.toml` at the repository root:
137
+
138
+ ```bash
139
+ rag-your-code config init # a commented file, all defaults
140
+ rag-your-code config list # effective values and their source
141
+ rag-your-code config set index.ignore '["vendor", "generated"]'
142
+ rag-your-code config set search.vector_weight 0.25
143
+ ```
144
+
145
+ Resolution is CLI flag > file > built-in default. There is no environment
146
+ layer: an index is an artifact of a repository, not of a shell.
147
+
148
+ | section | settings |
149
+ |---|---|
150
+ | `[index]` | `ignore`, `suffixes`, `max_file_bytes` |
151
+ | `[embedding]` | `dimensions` |
152
+ | `[search]` | `vector_weight`, `limit`, `max_chars` |
153
+ | `[agent]` | `max_open_bytes`, `max_open_chars` |
154
+ | `[describe]` | `languages`, `batch`, `max_chars` |
155
+
156
+ An unknown key or an out-of-range value is an error, not a shrug — a setting
157
+ that is silently dropped is indistinguishable from one that had no effect.
158
+ `index.suffixes` may only name suffixes the parser has rules for, because a
159
+ suffix it cannot read is walked, parsed to nothing, and reported as a clean
160
+ index of zero units.
161
+
162
+ The four settings under `[index]` and `[embedding]` determine what an index
163
+ *contains*, so a digest of them is recorded in the index and a change forces a
164
+ full rebuild. The rest take effect immediately and never invalidate anything.
165
+
166
+ ## Agent protocol
167
+
168
+ `rag-your-code agent --root PATH` reads JSON lines from stdin and writes JSON
169
+ lines to stdout:
170
+
171
+ ```json
172
+ {"action":"search","query":"database transaction rollback","limit":5}
173
+ {"action":"research","query":"trace payment retry behavior","max_steps":2}
174
+ {"action":"neighbors","id":"payments.py:4:retry_charge","hops":1}
175
+ {"action":"open","path":"payments.py","start_line":1,"end_line":80}
176
+ {"action":"describe_pending","limit":20}
177
+ {"action":"describe_put","descriptions":[{"id":"payments.py:4:retry_charge","text":"..."}]}
178
+ {"action":"refresh"}
179
+ {"action":"stats"}
180
+ ```
181
+
182
+ No single request can end the session: numeric fields saturate at their bounds,
183
+ `open` is bounded in both lines and bytes, and anything unanticipated is
184
+ reported in-band with its exception type. Streams are pinned to UTF-8 rather
185
+ than following the OS codepage.
186
+
187
+ The bundled Claude plugin skill documents the recommended workflow: index at
188
+ session start, retrieve narrowly, inspect returned source, describe what is
189
+ pending, and re-index after substantial changes.
190
+
191
+ ## Design notes
192
+
193
+ - Python uses the standard-library AST, so nested functions, methods, calls,
194
+ imports, signatures and source line ranges are precise.
195
+ - Other languages use a line-oriented declaration scanner: a per-language rule
196
+ table matched one line at a time, then a span closer (brace balance, Ruby's
197
+ `end`, or the next declaration). Because a pattern never sees a second line,
198
+ the reported line number is the scanner's own loop index and cannot drift,
199
+ and a declaration cannot swallow the ones after it. Fourteen languages are
200
+ covered and graded against source-controlled fixtures in
201
+ `tests/fixtures/languages/`; `SPEC.md` there states what counts as a unit.
202
+ - Retrieval combines lexical overlap and cosine similarity. Every result is
203
+ explainable: you can read why it matched.
204
+ - Schema 2 supports incremental per-file reuse, repository-global serials,
205
+ graph edges, and optional compact float32 vector storage (`index --compact`).
206
+ - GRAG expands bounded `calls`/`imports`/`contains` neighbours with edge-path
207
+ evidence, and omits an edge it cannot resolve rather than guessing one. ARAG
208
+ exposes bounded, observable `research`, `neighbors`, `open` and `refresh`.
209
+ - The generated `RAG[00001] ...` comments live in a sidecar Markdown file,
210
+ which avoids rewriting your code while preserving the numbered layer that
211
+ gets embedded.
212
+
213
+ ## What lives where
214
+
215
+ | path | authored or generated | committed |
216
+ |---|---|---|
217
+ | `rag-your-code.toml` | authored | yes |
218
+ | `rag-your-code.descriptions.json` | authored by your agent | yes |
219
+ | `.rag-your-code/` (index, vectors, annotations) | generated | no |
220
+
221
+ Nothing authored lives under `.rag-your-code/`: that directory is what people
222
+ delete to clear the cache.
223
+
224
+ ## Development
225
+
226
+ ```bash
227
+ python -m pip install -e ".[dev]"
228
+ pytest -q
229
+ ```
230
+
231
+ No runtime dependencies; `pytest` and, below Python 3.11, `tomli` come from the
232
+ `dev` extra. CI covers Python 3.10 through 3.13 on Linux and Windows and
233
+ installs the built wheel into a clean environment to check that the workflow
234
+ the bundled skill documents actually runs from a published artifact. See
235
+ [CONTRIBUTING.md](CONTRIBUTING.md) for what the golden set and the language
236
+ fixtures are protecting, and [docs/ROADMAP.md](docs/ROADMAP.md) for what is
237
+ deliberately not here yet.
@@ -0,0 +1,210 @@
1
+ # RAG Your Code
2
+
3
+ `rag-your-code` is the **R** in RAG: a local, explainable retrieval index over a
4
+ codebase. The generation half stays in your agent. It scans functions, methods
5
+ and classes across Python and fourteen other languages, assigns stable serial
6
+ numbers, and answers queries with a file, a line range, the terms that matched,
7
+ and the source itself.
8
+
9
+ No network calls and no runtime dependencies, by design rather than by
10
+ omission — it is meant to run over a private repository on a machine with the
11
+ network turned off, and to produce an index you can read.
12
+
13
+ ## What the embedding does, and what it does not
14
+
15
+ This matters more than any feature list, so it is stated up front rather than
16
+ in a footnote.
17
+
18
+ The embedder is a **signed feature hash**: it hashes tokens into 384 buckets.
19
+ Cosine similarity over those vectors is therefore a normalised measure of
20
+ *token overlap*, and it carries no semantics whatever:
21
+
22
+ | pair | cosine |
23
+ |---|---|
24
+ | `retry failed card charge` vs itself | 1.0000 |
25
+ | `sum two numbers` vs `add a pair of integers` | **0.0000** |
26
+ | `计算两个数的和` vs `sum two numbers` | **0.0000** |
27
+ | `sum two numbers` vs `delete the user database table` | 0.0000 |
28
+
29
+ A trained embedding model scores row 2 around 0.8. Here a synonym pair and an
30
+ unrelated pair are indistinguishable, because zero shared tokens is zero either
31
+ way.
32
+
33
+ Retrieval works anyway, because **identifiers and docstrings are already
34
+ natural language**: `retry_charge` contains the words *retry* and *charge*. But
35
+ it reaches only concepts someone wrote down. Two mechanisms close the rest of
36
+ the gap, and neither of them is a model:
37
+
38
+ - **Your agent rewrites the query.** It has the conversation; turning "重试扣款"
39
+ into `retry charge payment gateway` costs it nothing.
40
+ - **Your agent writes the descriptions** (see below), which puts the missing
41
+ vocabulary into the index once instead of into every query.
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ # Not on PyPI. Take the wheel from the latest release, or install the source:
47
+ # https://github.com/skymanbp/rag-your-code/releases
48
+ pip install ./rag_your_code-0.4.0-py3-none-any.whl
49
+ # ... or, from a clone: python -m pip install -e .
50
+
51
+ rag-your-code index .
52
+ rag-your-code search "where are HTTP retries handled" --json
53
+ rag-your-code search "what calls the retry handler" --graph --hops 1 --json
54
+ rag-your-code annotate
55
+ ```
56
+
57
+ The index and annotations are written under `.rag-your-code/`; source files are
58
+ never modified. Use `--json` when feeding results to an agent.
59
+
60
+ For a large repository prefer `rag-your-code index . --compact`. Later
61
+ `index` runs and the agent's `refresh` reuse unchanged files and preserve
62
+ global serials; `--full` discards the cache.
63
+
64
+ ## Agent-authored descriptions
65
+
66
+ Every unit carries a description, and that description is indexed. By default
67
+ it is generated without a model: the identifier humanised, the parameter and
68
+ callee names listed, the docstring appended. That introduces no vocabulary the
69
+ source did not already contain, which is exactly why retrieval cannot reach a
70
+ concept nobody wrote down.
71
+
72
+ The agent already reading this index can supply those words:
73
+
74
+ ```bash
75
+ rag-your-code describe status # coverage, and what is pending
76
+ rag-your-code describe export --limit 20 # a batch, with source and a brief
77
+ rag-your-code describe import written.json # store what the agent wrote
78
+ rag-your-code index . # apply it
79
+ ```
80
+
81
+ or, in the JSON-lines protocol, `describe_pending` and `describe_put` — which
82
+ take effect in the same session, without a refresh.
83
+
84
+ Measured on the fixture repository, replacing one generated sentence with an
85
+ agent-written bilingual one:
86
+
87
+ | query | generated description | agent description |
88
+ |---|---|---|
89
+ | `exponential backoff` | no lexical evidence | **#1**, 1.0172 |
90
+ | `double billing safety` | no lexical evidence | **#1**, 0.3404 |
91
+ | `支付网关超时` | no lexical evidence | **#1**, 0.8632 |
92
+
93
+ **What this is:** it moves the semantic work from query time to index time.
94
+ Matching stays lexical — a description saying `retry` still cannot answer a
95
+ query saying `resend` unless the description also says so. It is LLM-authored
96
+ keyword expansion, and its reach is bounded by how many ways of saying the
97
+ thing the agent thought to write down.
98
+
99
+ Descriptions live in `rag-your-code.descriptions.json` at the repository root
100
+ and are meant to be committed, so one person's pass benefits everyone who
101
+ clones. Each is keyed by unit id **and a digest of the unit's source**: when
102
+ the code changes the description is not applied, the unit returns to the
103
+ pending queue, and retrieval falls back to the generated sentence. A
104
+ description that outlived its code would be a confident wrong answer, which is
105
+ the one thing this index is built not to give.
106
+
107
+ ## Configuration
108
+
109
+ Twelve settings live in `rag-your-code.toml` at the repository root:
110
+
111
+ ```bash
112
+ rag-your-code config init # a commented file, all defaults
113
+ rag-your-code config list # effective values and their source
114
+ rag-your-code config set index.ignore '["vendor", "generated"]'
115
+ rag-your-code config set search.vector_weight 0.25
116
+ ```
117
+
118
+ Resolution is CLI flag > file > built-in default. There is no environment
119
+ layer: an index is an artifact of a repository, not of a shell.
120
+
121
+ | section | settings |
122
+ |---|---|
123
+ | `[index]` | `ignore`, `suffixes`, `max_file_bytes` |
124
+ | `[embedding]` | `dimensions` |
125
+ | `[search]` | `vector_weight`, `limit`, `max_chars` |
126
+ | `[agent]` | `max_open_bytes`, `max_open_chars` |
127
+ | `[describe]` | `languages`, `batch`, `max_chars` |
128
+
129
+ An unknown key or an out-of-range value is an error, not a shrug — a setting
130
+ that is silently dropped is indistinguishable from one that had no effect.
131
+ `index.suffixes` may only name suffixes the parser has rules for, because a
132
+ suffix it cannot read is walked, parsed to nothing, and reported as a clean
133
+ index of zero units.
134
+
135
+ The four settings under `[index]` and `[embedding]` determine what an index
136
+ *contains*, so a digest of them is recorded in the index and a change forces a
137
+ full rebuild. The rest take effect immediately and never invalidate anything.
138
+
139
+ ## Agent protocol
140
+
141
+ `rag-your-code agent --root PATH` reads JSON lines from stdin and writes JSON
142
+ lines to stdout:
143
+
144
+ ```json
145
+ {"action":"search","query":"database transaction rollback","limit":5}
146
+ {"action":"research","query":"trace payment retry behavior","max_steps":2}
147
+ {"action":"neighbors","id":"payments.py:4:retry_charge","hops":1}
148
+ {"action":"open","path":"payments.py","start_line":1,"end_line":80}
149
+ {"action":"describe_pending","limit":20}
150
+ {"action":"describe_put","descriptions":[{"id":"payments.py:4:retry_charge","text":"..."}]}
151
+ {"action":"refresh"}
152
+ {"action":"stats"}
153
+ ```
154
+
155
+ No single request can end the session: numeric fields saturate at their bounds,
156
+ `open` is bounded in both lines and bytes, and anything unanticipated is
157
+ reported in-band with its exception type. Streams are pinned to UTF-8 rather
158
+ than following the OS codepage.
159
+
160
+ The bundled Claude plugin skill documents the recommended workflow: index at
161
+ session start, retrieve narrowly, inspect returned source, describe what is
162
+ pending, and re-index after substantial changes.
163
+
164
+ ## Design notes
165
+
166
+ - Python uses the standard-library AST, so nested functions, methods, calls,
167
+ imports, signatures and source line ranges are precise.
168
+ - Other languages use a line-oriented declaration scanner: a per-language rule
169
+ table matched one line at a time, then a span closer (brace balance, Ruby's
170
+ `end`, or the next declaration). Because a pattern never sees a second line,
171
+ the reported line number is the scanner's own loop index and cannot drift,
172
+ and a declaration cannot swallow the ones after it. Fourteen languages are
173
+ covered and graded against source-controlled fixtures in
174
+ `tests/fixtures/languages/`; `SPEC.md` there states what counts as a unit.
175
+ - Retrieval combines lexical overlap and cosine similarity. Every result is
176
+ explainable: you can read why it matched.
177
+ - Schema 2 supports incremental per-file reuse, repository-global serials,
178
+ graph edges, and optional compact float32 vector storage (`index --compact`).
179
+ - GRAG expands bounded `calls`/`imports`/`contains` neighbours with edge-path
180
+ evidence, and omits an edge it cannot resolve rather than guessing one. ARAG
181
+ exposes bounded, observable `research`, `neighbors`, `open` and `refresh`.
182
+ - The generated `RAG[00001] ...` comments live in a sidecar Markdown file,
183
+ which avoids rewriting your code while preserving the numbered layer that
184
+ gets embedded.
185
+
186
+ ## What lives where
187
+
188
+ | path | authored or generated | committed |
189
+ |---|---|---|
190
+ | `rag-your-code.toml` | authored | yes |
191
+ | `rag-your-code.descriptions.json` | authored by your agent | yes |
192
+ | `.rag-your-code/` (index, vectors, annotations) | generated | no |
193
+
194
+ Nothing authored lives under `.rag-your-code/`: that directory is what people
195
+ delete to clear the cache.
196
+
197
+ ## Development
198
+
199
+ ```bash
200
+ python -m pip install -e ".[dev]"
201
+ pytest -q
202
+ ```
203
+
204
+ No runtime dependencies; `pytest` and, below Python 3.11, `tomli` come from the
205
+ `dev` extra. CI covers Python 3.10 through 3.13 on Linux and Windows and
206
+ installs the built wheel into a clean environment to check that the workflow
207
+ the bundled skill documents actually runs from a published artifact. See
208
+ [CONTRIBUTING.md](CONTRIBUTING.md) for what the golden set and the language
209
+ fixtures are protecting, and [docs/ROADMAP.md](docs/ROADMAP.md) for what is
210
+ deliberately not here yet.
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ # 77 is the floor for PEP 639 `license` / `license-files`, which is what puts
3
+ # the MIT text into the built wheel rather than only naming it in metadata.
4
+ requires = ["setuptools>=77"]
5
+ build-backend = "setuptools.build_meta"
6
+
7
+ [project]
8
+ name = "rag-your-code"
9
+ version = "0.4.1"
10
+ description = "A local, explainable RAG index for codebases and coding agents"
11
+ readme = "README.md"
12
+ requires-python = ">=3.10"
13
+ license = "MIT"
14
+ license-files = ["LICENSE"]
15
+ authors = [{name = "rag-your-code contributors"}]
16
+ keywords = ["rag", "code-search", "retrieval", "indexing", "graphrag", "offline", "explainable", "agent"]
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Environment :: Console",
20
+ "Intended Audience :: Developers",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Software Development :: Libraries",
28
+ "Topic :: Text Processing :: Indexing",
29
+ "Typing :: Typed",
30
+ ]
31
+ dependencies = []
32
+
33
+ [project.optional-dependencies]
34
+ # `pytest` is what README and docs/TESTING.md tell a contributor to run, so it
35
+ # has to be declared somewhere installable. `tomli` covers the one test that
36
+ # reads pyproject.toml on 3.10, where `tomllib` does not exist yet.
37
+ dev = [
38
+ "pytest>=7",
39
+ "tomli>=2.0; python_version < '3.11'",
40
+ ]
41
+
42
+ [project.scripts]
43
+ rag-your-code = "ragyourcode.cli:main"
44
+
45
+ [tool.setuptools.packages.find]
46
+ where = ["src"]
47
+
48
+ [tool.setuptools.package-data]
49
+ ragyourcode = ["py.typed"]
50
+
51
+ [tool.pytest.ini_options]
52
+ testpaths = ["tests"]
53
+ pythonpath = ["src", "."]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+