sciogen 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. sciogen-0.1.0/.gitignore +37 -0
  2. sciogen-0.1.0/LICENSE +21 -0
  3. sciogen-0.1.0/PKG-INFO +217 -0
  4. sciogen-0.1.0/README.md +181 -0
  5. sciogen-0.1.0/docs/api.md +127 -0
  6. sciogen-0.1.0/docs/architecture.md +229 -0
  7. sciogen-0.1.0/docs/cli.md +83 -0
  8. sciogen-0.1.0/docs/mcp.md +56 -0
  9. sciogen-0.1.0/docs/quickstart.md +100 -0
  10. sciogen-0.1.0/docs/schema.md +77 -0
  11. sciogen-0.1.0/pyproject.toml +68 -0
  12. sciogen-0.1.0/sciogen/__init__.py +24 -0
  13. sciogen-0.1.0/sciogen/api.py +151 -0
  14. sciogen-0.1.0/sciogen/cli/__init__.py +1 -0
  15. sciogen-0.1.0/sciogen/cli/banner.py +19 -0
  16. sciogen-0.1.0/sciogen/cli/console.py +10 -0
  17. sciogen-0.1.0/sciogen/cli/explore/__init__.py +57 -0
  18. sciogen-0.1.0/sciogen/cli/explore/template.html +341 -0
  19. sciogen-0.1.0/sciogen/cli/main.py +322 -0
  20. sciogen-0.1.0/sciogen/config.py +82 -0
  21. sciogen-0.1.0/sciogen/discovery.py +125 -0
  22. sciogen-0.1.0/sciogen/embed/__init__.py +51 -0
  23. sciogen-0.1.0/sciogen/embed/hashing.py +53 -0
  24. sciogen-0.1.0/sciogen/embed/nomic.py +34 -0
  25. sciogen-0.1.0/sciogen/index/__init__.py +5 -0
  26. sciogen-0.1.0/sciogen/index/pipeline.py +363 -0
  27. sciogen-0.1.0/sciogen/ir.py +182 -0
  28. sciogen-0.1.0/sciogen/mcp/__init__.py +1 -0
  29. sciogen-0.1.0/sciogen/mcp/server.py +94 -0
  30. sciogen-0.1.0/sciogen/normalize/__init__.py +32 -0
  31. sciogen-0.1.0/sciogen/normalize/base.py +121 -0
  32. sciogen-0.1.0/sciogen/normalize/generic.py +18 -0
  33. sciogen-0.1.0/sciogen/normalize/javascript.py +365 -0
  34. sciogen-0.1.0/sciogen/normalize/python.py +358 -0
  35. sciogen-0.1.0/sciogen/parsing/__init__.py +1 -0
  36. sciogen-0.1.0/sciogen/parsing/languages.py +67 -0
  37. sciogen-0.1.0/sciogen/parsing/parser.py +46 -0
  38. sciogen-0.1.0/sciogen/query/__init__.py +27 -0
  39. sciogen-0.1.0/sciogen/query/engine.py +326 -0
  40. sciogen-0.1.0/sciogen/query/results.py +172 -0
  41. sciogen-0.1.0/sciogen/resolve/__init__.py +5 -0
  42. sciogen-0.1.0/sciogen/resolve/resolver.py +398 -0
  43. sciogen-0.1.0/sciogen/stores/__init__.py +1 -0
  44. sciogen-0.1.0/sciogen/stores/graph.py +316 -0
  45. sciogen-0.1.0/sciogen/stores/meta.py +324 -0
  46. sciogen-0.1.0/sciogen/stores/vectors.py +108 -0
  47. sciogen-0.1.0/site/index.html +862 -0
  48. sciogen-0.1.0/site/public/logo.png +0 -0
  49. sciogen-0.1.0/tests/conftest.py +95 -0
  50. sciogen-0.1.0/tests/test_cli.py +58 -0
  51. sciogen-0.1.0/tests/test_discovery.py +63 -0
  52. sciogen-0.1.0/tests/test_normalize_python.py +146 -0
  53. sciogen-0.1.0/tests/test_pipeline_and_query.py +213 -0
  54. sciogen-0.1.0/tests/test_resolver.py +148 -0
@@ -0,0 +1,37 @@
1
+ # sciogen index (generated per-project; never committed)
2
+ .sciogen/
3
+
4
+ # Python build / packaging
5
+ build/
6
+ dist/
7
+ *.egg-info/
8
+ __pycache__/
9
+ *.py[cod]
10
+ *.egg
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # Test / tooling caches
18
+ .pytest_cache/
19
+ .mypy_cache/
20
+ .ruff_cache/
21
+ .coverage
22
+ htmlcov/
23
+
24
+ # Local tool settings
25
+ .claude/settings.local.json
26
+
27
+ # OS / editor
28
+ .DS_Store
29
+ Thumbs.db
30
+ *.swp
31
+ .idea/
32
+ .vscode/
33
+
34
+ #MD Files
35
+ CLAUDE.md
36
+ RELEASING.md
37
+ site/_artifact_body.html
sciogen-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 sciogen 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.
sciogen-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: sciogen
3
+ Version: 0.1.0
4
+ Summary: Codebase intelligence layer — a queryable knowledge graph over your code.
5
+ Project-URL: Homepage, https://github.com/ayanbag/sciogen
6
+ Project-URL: Repository, https://github.com/ayanbag/sciogen
7
+ Project-URL: Documentation, https://github.com/ayanbag/sciogen/tree/main/docs
8
+ Project-URL: Issues, https://github.com/ayanbag/sciogen/issues
9
+ Author: sciogen contributors
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: code-search,knowledge-graph,mcp,static-analysis,tree-sitter
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: chromadb>=0.5
22
+ Requires-Dist: kuzu>=0.7
23
+ Requires-Dist: mcp>=1.0
24
+ Requires-Dist: rich>=13.7
25
+ Requires-Dist: tree-sitter-language-pack<1.0,>=0.6
26
+ Requires-Dist: tree-sitter<0.26,>=0.22
27
+ Requires-Dist: typer>=0.12
28
+ Requires-Dist: watchdog>=4.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-timeout; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Provides-Extra: embeddings
33
+ Requires-Dist: einops; extra == 'embeddings'
34
+ Requires-Dist: sentence-transformers>=3.0; extra == 'embeddings'
35
+ Description-Content-Type: text/markdown
36
+
37
+ <img src="site/public/logo.png" alt="Image" width="100%" />
38
+
39
+ <div align="center">
40
+ <p>
41
+ <a href="https://pypi.org/project/sciogen/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sciogen.svg"></a>
42
+ <a href="https://pypi.org/project/sciogen/"><img alt="Python versions" src="https://img.shields.io/pypi/pyversions/sciogen.svg"></a>
43
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
44
+ </p>
45
+ </div>
46
+
47
+ **Codebase intelligence layer** — a queryable knowledge graph over your code.
48
+
49
+ sciogen parses a codebase once, resolves every reference to the exact definition it
50
+ points to, and materializes the result into an embedded triple store. After that,
51
+ questions like *"who calls `AuthService.login`?"*, *"what breaks if I change
52
+ `UserModel.find_by_email`?"*, or *"where is the password hashing logic?"* are
53
+ sub-second index lookups that return **typed objects with file/line locations** —
54
+ not grep results, not raw source dumps.
55
+
56
+ sciogen is a **static analysis and indexing tool**. It never calls an LLM, never
57
+ counts tokens, and has no concept of a context window. It is to codebases what
58
+ Elasticsearch is to documents: precomputed, queryable structure.
59
+
60
+ ```
61
+ pip install sciogen
62
+ sciogen index .
63
+ ```
64
+
65
+ ```
66
+ ███████╗ ██████╗██╗ ██████╗ ██████╗ ███████╗███╗ ██╗
67
+ ██╔════╝██╔════╝██║██╔═══██╗██╔════╝ ██╔════╝████╗ ██║
68
+ ███████╗██║ ██║██║ ██║██║ ███╗█████╗ ██╔██╗ ██║
69
+ ╚════██║██║ ██║██║ ██║██║ ██║██╔══╝ ██║╚██╗██║
70
+ ███████║╚██████╗██║╚██████╔╝╚██████╔╝███████╗██║ ╚████║
71
+ ╚══════╝ ╚═════╝╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝
72
+ Codebase Intelligence Layer v0.1.0
73
+
74
+ ✓ Scanning project structure...
75
+ ✓ Reading 143 files...
76
+ ✓ Parsing Python, TypeScript...
77
+ ✓ Building knowledge graph...
78
+ ✓ Embedding 1,204 symbols...
79
+ ✓ Linking dependencies...
80
+ ✓ Done! 1,204 nodes · 3,456 edges · indexed in 4.2s
81
+ Ready. Your codebase is now queryable.
82
+ ```
83
+
84
+ ## Why
85
+
86
+ A coding agent understands a codebase by **reading files** — and files are the
87
+ wrong granularity. To learn one function's callers it reads thousands of lines
88
+ of source into its context window, burning tokens on noise. sciogen precomputes
89
+ the structure once, so the same answer is a handful of typed records with exact
90
+ `file:line` locations.
91
+
92
+ You run `sciogen index .` once. The knowledge graph is written to a `.sciogen/`
93
+ directory **inside the codebase**. From then on, an agent working in that repo
94
+ reads the graph instead of the raw files — the callers of a symbol, the blast
95
+ radius of a change, where a concept lives — for a fraction of the tokens a
96
+ file-by-file crawl would cost. sciogen itself never calls an LLM and is unaware
97
+ of tokens; the savings are a consequence of returning structure instead of
98
+ source.
99
+
100
+ ```
101
+ index once ─────────────► .sciogen/ (graph stored in the repo)
102
+ (sciogen index .) │
103
+
104
+ agent asks: "who calls login?" → typed records + file:line
105
+ agent asks: "what breaks if …?" → impact subgraph, not 40 files
106
+ ```
107
+
108
+ ## The two ways it's used
109
+
110
+ **You — from the terminal.** `sciogen index .` builds the graph; `sciogen
111
+ explore` opens it as an interactive browser GUI to inspect the codebase
112
+ visually.
113
+
114
+ **Your coding agent — over MCP.** `sciogen mcp .` exposes the graph to any
115
+ agent (Claude Code, etc.) through the Model Context Protocol, so it can query
116
+ callers, dependencies, impact, and semantic search directly instead of reading
117
+ files. See [docs/mcp.md](docs/mcp.md).
118
+
119
+ ## What the graph gives an agent
120
+
121
+ - **Exact call graphs** — a call to `login()` resolves to
122
+ `src/auth/service.py:AuthService.login`, not the string `"login"`. References
123
+ static analysis cannot prove (dynamic dispatch, injected dependencies) are kept
124
+ with a **low confidence score** rather than silently dropped, so the caller
125
+ chooses how much to trust each edge.
126
+ - **Impact analysis** — everything that may break if a symbol changes:
127
+ transitive callers with hop counts, subclasses, implementors, tests, mutators —
128
+ and the same for a whole PR at once from a unified diff.
129
+ - **Semantic + hybrid search** — local embeddings at four granularities (file,
130
+ class, function, chunk); hybrid mode expands vector hits through the graph.
131
+ - **Incremental by design** — SHA256 differ with a stat fast path; a single-file
132
+ change re-indexes in under a second, and dependent files are re-linked without
133
+ being re-parsed.
134
+ - **Interactive visualization** — `sciogen explore` renders the graph in your
135
+ browser from one self-contained HTML file. No server.
136
+
137
+ ## Getting started
138
+
139
+ ```bash
140
+ pip install sciogen
141
+ # optional, for real code-optimized semantic search (larger, one model download):
142
+ pip install "sciogen[embeddings]"
143
+
144
+ cd your-project
145
+ sciogen index . # build the graph (stored in ./.sciogen; incremental after)
146
+ sciogen explore # inspect it visually in the browser
147
+ sciogen mcp . # serve it to your coding agent over MCP
148
+ ```
149
+
150
+ Add `.sciogen/` to your `.gitignore` — it's machine-local and regenerable.
151
+
152
+ You can also query directly from the terminal for a quick look:
153
+
154
+ ```bash
155
+ sciogen search "password hashing" # semantic search
156
+ sciogen callers AuthService.login # who calls this?
157
+ sciogen impact UserModel.find_by_email # what breaks if this changes?
158
+ sciogen deps src/auth/service.py # imports, transitive deps
159
+ ```
160
+
161
+ See [docs/cli.md](docs/cli.md) for every command.
162
+
163
+ ## Architecture in one paragraph
164
+
165
+ `sciogen index` runs a five-stage pipeline per file: **tree-sitter** parses
166
+ (100+ languages, one API), a **normalizer** converts the language-specific AST
167
+ into a universal IR (only this layer knows languages), the **symbol resolver**
168
+ traces every reference to its exact definition with a confidence score, the
169
+ **graph builder** materializes typed nodes/edges into **KuzuDB** (Cypher), and a
170
+ **SHA256 differ** backed by **SQLite** makes re-runs incremental. Embeddings of
171
+ normalized symbol summaries (never raw code) go to **ChromaDB** at four
172
+ granularities. Queries are deterministic: structural queries hit KuzuDB, semantic
173
+ queries hit ChromaDB, hybrid uses vector hits as seeds for graph expansion. The
174
+ full design — including the performance architecture (parallel parsing, batched
175
+ transactional writes, embed deduplication, incremental re-resolution) — is in
176
+ [docs/architecture.md](docs/architecture.md).
177
+
178
+ ## Storage
179
+
180
+ Everything is embedded — no servers, no ports, one `.sciogen/` directory:
181
+
182
+ | Store | Role |
183
+ |-------|------|
184
+ | KuzuDB | Graph topology — nodes, typed edges, confidence scores |
185
+ | ChromaDB | Vector embeddings at file/class/function/chunk granularity |
186
+ | SQLite | File hashes, symbol table, reference records, schema version |
187
+
188
+ Add `.sciogen/` to your `.gitignore`.
189
+
190
+ ## Documentation
191
+
192
+ | Doc | Contents |
193
+ |-----|----------|
194
+ | [docs/quickstart.md](docs/quickstart.md) | Install, first index, first queries |
195
+ | [docs/cli.md](docs/cli.md) | Every command and flag |
196
+ | [docs/mcp.md](docs/mcp.md) | MCP tools and agent setup — how an agent consumes the graph |
197
+ | [docs/schema.md](docs/schema.md) | Node types, edge types, confidence model |
198
+ | [docs/architecture.md](docs/architecture.md) | The two phases, every design decision, performance architecture |
199
+ | [docs/api.md](docs/api.md) | Embedded Python API — only if you're building tooling *on top of* sciogen |
200
+
201
+ ## Supported languages
202
+
203
+ Full symbol extraction: **Python**, **JavaScript**, **TypeScript/TSX**.
204
+ File-level indexing (parse check + file search): Go, Rust, Java, Ruby, PHP, C,
205
+ C++, C#, Kotlin, Swift, Scala, Lua. Adding full support for a language means
206
+ writing one normalizer — see [docs/architecture.md](docs/architecture.md#ast-normalizer).
207
+
208
+ ## Development
209
+
210
+ ```bash
211
+ git clone <repo> && cd sciogen
212
+ python -m venv .venv && .venv/Scripts/activate # or bin/activate
213
+ pip install -e ".[dev]"
214
+ pytest
215
+ ```
216
+
217
+ MIT license.
@@ -0,0 +1,181 @@
1
+ <img src="site/public/logo.png" alt="Image" width="100%" />
2
+
3
+ <div align="center">
4
+ <p>
5
+ <a href="https://pypi.org/project/sciogen/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sciogen.svg"></a>
6
+ <a href="https://pypi.org/project/sciogen/"><img alt="Python versions" src="https://img.shields.io/pypi/pyversions/sciogen.svg"></a>
7
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
8
+ </p>
9
+ </div>
10
+
11
+ **Codebase intelligence layer** — a queryable knowledge graph over your code.
12
+
13
+ sciogen parses a codebase once, resolves every reference to the exact definition it
14
+ points to, and materializes the result into an embedded triple store. After that,
15
+ questions like *"who calls `AuthService.login`?"*, *"what breaks if I change
16
+ `UserModel.find_by_email`?"*, or *"where is the password hashing logic?"* are
17
+ sub-second index lookups that return **typed objects with file/line locations** —
18
+ not grep results, not raw source dumps.
19
+
20
+ sciogen is a **static analysis and indexing tool**. It never calls an LLM, never
21
+ counts tokens, and has no concept of a context window. It is to codebases what
22
+ Elasticsearch is to documents: precomputed, queryable structure.
23
+
24
+ ```
25
+ pip install sciogen
26
+ sciogen index .
27
+ ```
28
+
29
+ ```
30
+ ███████╗ ██████╗██╗ ██████╗ ██████╗ ███████╗███╗ ██╗
31
+ ██╔════╝██╔════╝██║██╔═══██╗██╔════╝ ██╔════╝████╗ ██║
32
+ ███████╗██║ ██║██║ ██║██║ ███╗█████╗ ██╔██╗ ██║
33
+ ╚════██║██║ ██║██║ ██║██║ ██║██╔══╝ ██║╚██╗██║
34
+ ███████║╚██████╗██║╚██████╔╝╚██████╔╝███████╗██║ ╚████║
35
+ ╚══════╝ ╚═════╝╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝
36
+ Codebase Intelligence Layer v0.1.0
37
+
38
+ ✓ Scanning project structure...
39
+ ✓ Reading 143 files...
40
+ ✓ Parsing Python, TypeScript...
41
+ ✓ Building knowledge graph...
42
+ ✓ Embedding 1,204 symbols...
43
+ ✓ Linking dependencies...
44
+ ✓ Done! 1,204 nodes · 3,456 edges · indexed in 4.2s
45
+ Ready. Your codebase is now queryable.
46
+ ```
47
+
48
+ ## Why
49
+
50
+ A coding agent understands a codebase by **reading files** — and files are the
51
+ wrong granularity. To learn one function's callers it reads thousands of lines
52
+ of source into its context window, burning tokens on noise. sciogen precomputes
53
+ the structure once, so the same answer is a handful of typed records with exact
54
+ `file:line` locations.
55
+
56
+ You run `sciogen index .` once. The knowledge graph is written to a `.sciogen/`
57
+ directory **inside the codebase**. From then on, an agent working in that repo
58
+ reads the graph instead of the raw files — the callers of a symbol, the blast
59
+ radius of a change, where a concept lives — for a fraction of the tokens a
60
+ file-by-file crawl would cost. sciogen itself never calls an LLM and is unaware
61
+ of tokens; the savings are a consequence of returning structure instead of
62
+ source.
63
+
64
+ ```
65
+ index once ─────────────► .sciogen/ (graph stored in the repo)
66
+ (sciogen index .) │
67
+
68
+ agent asks: "who calls login?" → typed records + file:line
69
+ agent asks: "what breaks if …?" → impact subgraph, not 40 files
70
+ ```
71
+
72
+ ## The two ways it's used
73
+
74
+ **You — from the terminal.** `sciogen index .` builds the graph; `sciogen
75
+ explore` opens it as an interactive browser GUI to inspect the codebase
76
+ visually.
77
+
78
+ **Your coding agent — over MCP.** `sciogen mcp .` exposes the graph to any
79
+ agent (Claude Code, etc.) through the Model Context Protocol, so it can query
80
+ callers, dependencies, impact, and semantic search directly instead of reading
81
+ files. See [docs/mcp.md](docs/mcp.md).
82
+
83
+ ## What the graph gives an agent
84
+
85
+ - **Exact call graphs** — a call to `login()` resolves to
86
+ `src/auth/service.py:AuthService.login`, not the string `"login"`. References
87
+ static analysis cannot prove (dynamic dispatch, injected dependencies) are kept
88
+ with a **low confidence score** rather than silently dropped, so the caller
89
+ chooses how much to trust each edge.
90
+ - **Impact analysis** — everything that may break if a symbol changes:
91
+ transitive callers with hop counts, subclasses, implementors, tests, mutators —
92
+ and the same for a whole PR at once from a unified diff.
93
+ - **Semantic + hybrid search** — local embeddings at four granularities (file,
94
+ class, function, chunk); hybrid mode expands vector hits through the graph.
95
+ - **Incremental by design** — SHA256 differ with a stat fast path; a single-file
96
+ change re-indexes in under a second, and dependent files are re-linked without
97
+ being re-parsed.
98
+ - **Interactive visualization** — `sciogen explore` renders the graph in your
99
+ browser from one self-contained HTML file. No server.
100
+
101
+ ## Getting started
102
+
103
+ ```bash
104
+ pip install sciogen
105
+ # optional, for real code-optimized semantic search (larger, one model download):
106
+ pip install "sciogen[embeddings]"
107
+
108
+ cd your-project
109
+ sciogen index . # build the graph (stored in ./.sciogen; incremental after)
110
+ sciogen explore # inspect it visually in the browser
111
+ sciogen mcp . # serve it to your coding agent over MCP
112
+ ```
113
+
114
+ Add `.sciogen/` to your `.gitignore` — it's machine-local and regenerable.
115
+
116
+ You can also query directly from the terminal for a quick look:
117
+
118
+ ```bash
119
+ sciogen search "password hashing" # semantic search
120
+ sciogen callers AuthService.login # who calls this?
121
+ sciogen impact UserModel.find_by_email # what breaks if this changes?
122
+ sciogen deps src/auth/service.py # imports, transitive deps
123
+ ```
124
+
125
+ See [docs/cli.md](docs/cli.md) for every command.
126
+
127
+ ## Architecture in one paragraph
128
+
129
+ `sciogen index` runs a five-stage pipeline per file: **tree-sitter** parses
130
+ (100+ languages, one API), a **normalizer** converts the language-specific AST
131
+ into a universal IR (only this layer knows languages), the **symbol resolver**
132
+ traces every reference to its exact definition with a confidence score, the
133
+ **graph builder** materializes typed nodes/edges into **KuzuDB** (Cypher), and a
134
+ **SHA256 differ** backed by **SQLite** makes re-runs incremental. Embeddings of
135
+ normalized symbol summaries (never raw code) go to **ChromaDB** at four
136
+ granularities. Queries are deterministic: structural queries hit KuzuDB, semantic
137
+ queries hit ChromaDB, hybrid uses vector hits as seeds for graph expansion. The
138
+ full design — including the performance architecture (parallel parsing, batched
139
+ transactional writes, embed deduplication, incremental re-resolution) — is in
140
+ [docs/architecture.md](docs/architecture.md).
141
+
142
+ ## Storage
143
+
144
+ Everything is embedded — no servers, no ports, one `.sciogen/` directory:
145
+
146
+ | Store | Role |
147
+ |-------|------|
148
+ | KuzuDB | Graph topology — nodes, typed edges, confidence scores |
149
+ | ChromaDB | Vector embeddings at file/class/function/chunk granularity |
150
+ | SQLite | File hashes, symbol table, reference records, schema version |
151
+
152
+ Add `.sciogen/` to your `.gitignore`.
153
+
154
+ ## Documentation
155
+
156
+ | Doc | Contents |
157
+ |-----|----------|
158
+ | [docs/quickstart.md](docs/quickstart.md) | Install, first index, first queries |
159
+ | [docs/cli.md](docs/cli.md) | Every command and flag |
160
+ | [docs/mcp.md](docs/mcp.md) | MCP tools and agent setup — how an agent consumes the graph |
161
+ | [docs/schema.md](docs/schema.md) | Node types, edge types, confidence model |
162
+ | [docs/architecture.md](docs/architecture.md) | The two phases, every design decision, performance architecture |
163
+ | [docs/api.md](docs/api.md) | Embedded Python API — only if you're building tooling *on top of* sciogen |
164
+
165
+ ## Supported languages
166
+
167
+ Full symbol extraction: **Python**, **JavaScript**, **TypeScript/TSX**.
168
+ File-level indexing (parse check + file search): Go, Rust, Java, Ruby, PHP, C,
169
+ C++, C#, Kotlin, Swift, Scala, Lua. Adding full support for a language means
170
+ writing one normalizer — see [docs/architecture.md](docs/architecture.md#ast-normalizer).
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ git clone <repo> && cd sciogen
176
+ python -m venv .venv && .venv/Scripts/activate # or bin/activate
177
+ pip install -e ".[dev]"
178
+ pytest
179
+ ```
180
+
181
+ MIT license.
@@ -0,0 +1,127 @@
1
+ # Python API
2
+
3
+ The whole library is one facade class, `SciogenGraph`, reached through
4
+ `sciogen.open()`. The CLI and MCP server are thin adapters over it.
5
+
6
+ ```python
7
+ import sciogen
8
+
9
+ graph = sciogen.open("path/to/repo") # opens (creates) the .sciogen index
10
+ graph.index() # incremental build; returns IndexStats
11
+ ```
12
+
13
+ `SciogenGraph` is a context manager; stores open lazily on first use.
14
+
15
+ ```python
16
+ with sciogen.open(".") as graph:
17
+ graph.index()
18
+ info = graph.get_symbol("AuthService.login")
19
+ ```
20
+
21
+ ## Indexing
22
+
23
+ ### `graph.index(reporter=None, rebuild=False) -> IndexStats`
24
+
25
+ Build or incrementally update the index. `rebuild=True` wipes `.sciogen/` first.
26
+ `reporter` is an optional progress sink (the CLI passes a Rich adapter; omit for
27
+ silence).
28
+
29
+ ```python
30
+ stats = graph.index()
31
+ stats.nodes, stats.edges, stats.seconds
32
+ stats.files_indexed, stats.files_unchanged, stats.files_deleted, stats.files_failed
33
+ stats.errors # list[(path, error_message)]
34
+ ```
35
+
36
+ ## Structural queries
37
+
38
+ All return typed dataclasses with `.to_dict()`. Every node reference carries an
39
+ exact `file` / `line_start` / `line_end`.
40
+
41
+ ### `get_symbol(name, file=None) -> SymbolInfo`
42
+
43
+ ```python
44
+ info = graph.get_symbol("AuthService.login")
45
+ info.node.kind # "FunctionNode"
46
+ info.node.file # "src/auth/service.py"
47
+ info.node.params # ["self", "username: str", "password: str"]
48
+ info.node.line_start
49
+ info.relations # [Relation(kind, other, direction, confidence), ...]
50
+ ```
51
+
52
+ Pass `file=` to disambiguate a name defined in several places. Raises
53
+ `sciogen.query.engine.SymbolNotFound` if nothing matches.
54
+
55
+ ### `get_callers(symbol, depth=1, min_confidence=0.0) -> ImpactGraph`
56
+
57
+ ```python
58
+ result = graph.get_callers("hash_password", depth=2)
59
+ for item in result.impacted: # sorted by (hops, -confidence)
60
+ item.node.id, item.hops, item.confidence, item.relation
61
+ ```
62
+
63
+ `confidence` is the path confidence — the weakest edge along the best path.
64
+
65
+ ### `analyze_impact(symbol, max_depth=5, min_confidence=0.0) -> ImpactGraph`
66
+
67
+ Everything that may break if `symbol` changes: transitive callers (up to
68
+ `max_depth`) plus one-hop subclasses, implementors, tests, and mutators.
69
+
70
+ ### `get_dependencies(file) -> DependencyInfo`
71
+
72
+ ```python
73
+ deps = graph.get_dependencies("src/auth/service.py")
74
+ deps.direct_files # files directly imported
75
+ deps.transitive_files # reachable beyond direct
76
+ deps.external_modules # third-party / stdlib module names
77
+ ```
78
+
79
+ ### `get_diff_impact(unified_diff) -> DiffImpact`
80
+
81
+ Feed a unified diff; get the union impact of every symbol it touches.
82
+
83
+ ```python
84
+ result = graph.get_diff_impact(open("pr.diff").read())
85
+ result.changed_symbols # symbols whose lines the diff overlaps
86
+ result.unmatched_files # files in the diff not in the index
87
+ result.impact # ImpactGraph over all changed symbols at once
88
+ ```
89
+
90
+ ## Semantic & hybrid queries
91
+
92
+ ### `search(query, mode="semantic", granularity=None, k=10) -> SearchResults`
93
+
94
+ ```python
95
+ graph.search("password hashing logic")
96
+ graph.search("all code related to auth", mode="hybrid")
97
+ graph.search("classes that manage sessions", granularity="class")
98
+
99
+ for hit in results.hits:
100
+ hit.node, hit.score, hit.granularity, hit.via # via: "semantic" | "graph"
101
+ ```
102
+
103
+ `hybrid` mode uses vector hits as seeds and expands through the graph;
104
+ graph-expanded hits are marked `via="graph"`.
105
+
106
+ ### `get_context_for_task(description, k=15) -> ContextBundle`
107
+
108
+ Broad intent → curated subgraph.
109
+
110
+ ```python
111
+ bundle = graph.get_context_for_task("add rate limiting to login")
112
+ bundle.files # ranked most-relevant first
113
+ bundle.symbols # SearchHit list
114
+ ```
115
+
116
+ ## Result types
117
+
118
+ All defined in `sciogen.query.results`, all plain dataclasses with `.to_dict()`:
119
+ `SymbolNode`, `SymbolInfo`, `Relation`, `ImpactedSymbol`, `ImpactGraph`,
120
+ `DependencyInfo`, `SearchHit`, `SearchResults`, `DiffImpact`, `ContextBundle`.
121
+
122
+ ## Notes
123
+
124
+ - Query results are memoized in an LRU keyed by the index version; a re-index
125
+ invalidates the whole cache at once.
126
+ - Queries never return raw source code — only typed nodes with locations. The
127
+ caller decides whether to open the file.