seschat 0.1.0b2__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Adit
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,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: seschat
3
+ Version: 0.1.0b2
4
+ Summary: A repository intelligence tool: scans a codebase, parses its structure with tree-sitter, indexes it in SQLite, and answers questions about it via hybrid keyword+semantic RAG. Ships as a CLI today.
5
+ Author: Adit
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/YOUR_GITHUB_USERNAME/seschat
8
+ Project-URL: Repository, https://github.com/YOUR_GITHUB_USERNAME/seschat
9
+ Project-URL: Issues, https://github.com/YOUR_GITHUB_USERNAME/seschat/issues
10
+ Keywords: cli,rag,code-search,tree-sitter,llm,developer-tools,sqlite,embeddings
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Documentation
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: typer>=0.12.0
26
+ Requires-Dist: tree-sitter>=0.23.0
27
+ Requires-Dist: tree-sitter-language-pack>=0.2.0
28
+ Requires-Dist: ollama>=0.4.0
29
+ Requires-Dist: google-genai>=1.0.0
30
+ Dynamic: license-file
31
+
32
+ # Seschat
33
+
34
+ A CLI that actually understands your codebase. It parses every file into a
35
+ real syntax tree (via tree-sitter, not regex), indexes the result in
36
+ SQLite, and lets you search, semantically browse, and ask questions about
37
+ your repository — grounded in what's actually in the code, not a model's
38
+ best guess.
39
+
40
+ > **Beta.** Seschat works and is actively maintained, but it's early —
41
+ > expect rough edges, and expect the internals to keep moving for a while.
42
+ > See [Known limitations](#known-limitations) below before you point it at
43
+ > anything you depend on. Issues and PRs are welcome.
44
+
45
+ ```bash
46
+ seschat index ./my-project
47
+ seschat ask ./my-project "Where is authentication handled?"
48
+ seschat explain ./my-project src/auth.py
49
+ ```
50
+
51
+ ## Why
52
+
53
+ Most "AI for your codebase" tools quietly let the model do the searching —
54
+ you ask a question, the model reads what it can fit in context, and hopes
55
+ for the best. Seschat splits that apart on purpose: retrieval (keyword
56
+ search, semantic search, structural lookups) happens entirely in Python
57
+ and SQL, *before* the model ever sees a token. The model's only job is to
58
+ read what retrieval already found and write a grounded answer. If you turn
59
+ on `--show-context`, you can see exactly which files were retrieved, by
60
+ which method, and why — nothing about what reaches the model is hidden.
61
+
62
+ ## What it does
63
+
64
+ | Command | What it does | Talks to a model? |
65
+ |---|---|---|
66
+ | `seschat index <path>` | Scans a repo, parses every file's structure (classes, functions, imports, comments) with tree-sitter, stores it in SQLite | No |
67
+ | `seschat query <path> <term>` | Keyword search over that extracted structure | No |
68
+ | `seschat semantic <path> <query>` | Embedding-based similarity search — finds related files even with no shared vocabulary | Embeddings only |
69
+ | `seschat ask <path> "<question>"` | Hybrid keyword + semantic retrieval, then an LLM answers and cites files | Yes |
70
+ | `seschat explain <path> <file>` | Summarizes one file: purpose, responsibilities, key classes/functions, dependencies, suggestions | Yes |
71
+
72
+ Structural parsing currently covers Python, C, C++, Java, Go, Rust, Ruby,
73
+ JavaScript/JSX, TypeScript/TSX, C#, PHP, Kotlin, and Scala. Markdown,
74
+ JSON, YAML, TOML, XML, HTML, CSS, and SCSS are indexed and searchable but
75
+ correctly reported as having no classes or functions — they're not code.
76
+ Anything else still gets counted and flagged rather than silently
77
+ dropped, so `seschat index` never leaves a file unaccounted for.
78
+
79
+ ## Install
80
+
81
+ ```bash
82
+ pip install seschat
83
+ ```
84
+ Requires Python 3.10+.
85
+
86
+ ## Quick start
87
+
88
+ ```bash
89
+ seschat index ./my-project
90
+ seschat query ./my-project Cache
91
+ seschat semantic ./my-project "how does the app handle user login"
92
+ seschat ask ./my-project "Where is authentication handled?"
93
+ seschat explain ./my-project src/auth.py
94
+ ```
95
+
96
+ `index`, `query`, and `semantic` work with nothing beyond `pip install` —
97
+ `semantic` needs an embedding backend, covered below. `ask` and `explain`
98
+ need a chat model.
99
+
100
+ ## Setting up a model backend
101
+
102
+ `ask` and `explain` are local-first with an automatic hosted fallback —
103
+ there's nothing you *must* configure, but pick one:
104
+
105
+ **Local, no API key (Ollama):**
106
+ ```bash
107
+ ollama serve
108
+ ollama pull qwen3:8b
109
+ ```
110
+
111
+ **Hosted (Gemini):**
112
+ ```bash
113
+ export GEMINI_API_KEY=... # https://aistudio.google.com/
114
+ ```
115
+
116
+ Seschat tries Ollama first and falls back to Gemini automatically if it
117
+ isn't running, isn't installed, or doesn't have the model pulled. If
118
+ neither is usable, the error message tells you exactly what to fix rather
119
+ than a raw traceback.
120
+
121
+ ### Embeddings (for `semantic`, and the semantic half of `ask`)
122
+
123
+ Same shape, separate model:
124
+
125
+ ```bash
126
+ ollama pull nomic-embed-text # local
127
+ # or reuse the same GEMINI_API_KEY above for hosted embeddings
128
+ ```
129
+
130
+ If no embedding backend is available when you index, indexing still
131
+ succeeds — you just won't have `seschat semantic`, and `ask` quietly
132
+ falls back to keyword-only retrieval (visible under `--show-context`,
133
+ never silent).
134
+
135
+ Full environment variable reference is in
136
+ [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md).
137
+
138
+ ## How retrieval actually works
139
+
140
+ - **`query`** — plain SQL `LIKE` across extracted file paths, class
141
+ names, function names, imports, and comments. It doesn't see inside
142
+ function bodies or string literals; it only searches what got pulled
143
+ *out* of the file during indexing.
144
+ - **`semantic`** — one embedding vector per file (its structure plus a
145
+ source excerpt), ranked by cosine similarity against your query.
146
+ - **`ask`** — runs both of the above, normalizes each to a 0–1 score, and
147
+ merges them with a weighted sum. Every retrieved file's provenance and
148
+ score is inspectable via `--show-context`.
149
+ - **`explain`** — no retrieval at all. You name the file; it reads that
150
+ file's indexed structure and a fresh copy of its source, and asks the
151
+ model to summarize only that.
152
+
153
+ ## About the name
154
+
155
+ Seschat is Seshat, morphed with chat. Seshat was the
156
+ ancient Egyptian goddess of writing, measurement, and record-keeping —
157
+ credited with inventing writing itself and keeping the pharaoh's library.
158
+ A tool that reads your code, keeps a structured record of it, and lets
159
+ you talk to that record felt like a reasonable namesake. Say it out loud
160
+ and it should land closer to "seshat" than "session-chat."
161
+
162
+ ## Known limitations
163
+
164
+ - **Embeddings are per file, not per function or class.** A large file's
165
+ embedding can dilute a small relevant section inside it. Chunk-level
166
+ embeddings are on the roadmap; they need byte-range tracking in the
167
+ metadata layer first.
168
+ - **Indexing is drop-and-rebuild, not incremental.** Every `seschat
169
+ index` run re-scans and re-embeds the whole repository. Fine for
170
+ small-to-medium repos; slower than it needs to be on large ones you
171
+ re-index often.
172
+ - **Keyword ranking is match-count, not TF-IDF.** It's a cheap proxy for
173
+ relevance, not real ranking.
174
+ - **`.gitignore` support is close, not exact.** Rules are matched with
175
+ `fnmatch`, scoped per directory the way git actually applies them, but
176
+ it doesn't reproduce git's `**` wildcard semantics precisely.
177
+ - **Test your own model setup after installing.** The retrieval and
178
+ prompting logic is well-tested; the two live backends (Ollama, Gemini)
179
+ will behave slightly differently depending on your local setup. Run
180
+ `ask`/`explain`/`semantic` once against a real repo after install to
181
+ confirm your backend is actually reachable, and once with it
182
+ deliberately down to confirm the fallback kicks in.
183
+
184
+ ## Project layout
185
+
186
+ ```
187
+ seschat/
188
+ ├── cli.py # index, query, semantic, ask, explain
189
+ ├── scanner.py # traversal, ignore rules, extension → language mapping
190
+ ├── gitignore.py # scoped .gitignore parsing
191
+ ├── metadata.py # tree-sitter parsing → classes/functions/imports/comments
192
+ ├── db.py # SQLite schema and writes (metadata + embeddings)
193
+ ├── search.py # keyword search plus by-path structure/record lookups
194
+ ├── ask.py # hybrid retrieval → prompt → LLM → answer
195
+ ├── explain.py # file path → metadata + source → prompt → LLM → explanation
196
+ ├── llm.py # the only module that talks to a chat model
197
+ └── embeddings.py # the only module that talks to an embedding model
198
+ ```
199
+
200
+ Every module besides `cli.py` has no idea a CLI framework exists — `cli.py`
201
+ is a thin layer on top of plain function calls.
202
+
203
+ ## What's next
204
+
205
+ A compiler/test-failure assistant, verified test generation, a PR-review
206
+ assistant, architecture diagram generation, and general hardening
207
+ (incremental indexing, a config file, caching) are planned. The full
208
+ history and reasoning behind each stage of this project so far is in
209
+ [`roadmap.md`](roadmap.md), kept around because the "why" behind a
210
+ decision is usually more useful later than the decision itself.
211
+
212
+ ## Contributing
213
+
214
+ Issues and PRs are welcome. This is under active development, so expect
215
+ things to move between releases — check `CHANGELOG.md` for what changed
216
+ and why.
217
+
218
+ ## License
219
+
220
+ MIT — see [`LICENSE`](LICENSE).
@@ -0,0 +1,189 @@
1
+ # Seschat
2
+
3
+ A CLI that actually understands your codebase. It parses every file into a
4
+ real syntax tree (via tree-sitter, not regex), indexes the result in
5
+ SQLite, and lets you search, semantically browse, and ask questions about
6
+ your repository — grounded in what's actually in the code, not a model's
7
+ best guess.
8
+
9
+ > **Beta.** Seschat works and is actively maintained, but it's early —
10
+ > expect rough edges, and expect the internals to keep moving for a while.
11
+ > See [Known limitations](#known-limitations) below before you point it at
12
+ > anything you depend on. Issues and PRs are welcome.
13
+
14
+ ```bash
15
+ seschat index ./my-project
16
+ seschat ask ./my-project "Where is authentication handled?"
17
+ seschat explain ./my-project src/auth.py
18
+ ```
19
+
20
+ ## Why
21
+
22
+ Most "AI for your codebase" tools quietly let the model do the searching —
23
+ you ask a question, the model reads what it can fit in context, and hopes
24
+ for the best. Seschat splits that apart on purpose: retrieval (keyword
25
+ search, semantic search, structural lookups) happens entirely in Python
26
+ and SQL, *before* the model ever sees a token. The model's only job is to
27
+ read what retrieval already found and write a grounded answer. If you turn
28
+ on `--show-context`, you can see exactly which files were retrieved, by
29
+ which method, and why — nothing about what reaches the model is hidden.
30
+
31
+ ## What it does
32
+
33
+ | Command | What it does | Talks to a model? |
34
+ |---|---|---|
35
+ | `seschat index <path>` | Scans a repo, parses every file's structure (classes, functions, imports, comments) with tree-sitter, stores it in SQLite | No |
36
+ | `seschat query <path> <term>` | Keyword search over that extracted structure | No |
37
+ | `seschat semantic <path> <query>` | Embedding-based similarity search — finds related files even with no shared vocabulary | Embeddings only |
38
+ | `seschat ask <path> "<question>"` | Hybrid keyword + semantic retrieval, then an LLM answers and cites files | Yes |
39
+ | `seschat explain <path> <file>` | Summarizes one file: purpose, responsibilities, key classes/functions, dependencies, suggestions | Yes |
40
+
41
+ Structural parsing currently covers Python, C, C++, Java, Go, Rust, Ruby,
42
+ JavaScript/JSX, TypeScript/TSX, C#, PHP, Kotlin, and Scala. Markdown,
43
+ JSON, YAML, TOML, XML, HTML, CSS, and SCSS are indexed and searchable but
44
+ correctly reported as having no classes or functions — they're not code.
45
+ Anything else still gets counted and flagged rather than silently
46
+ dropped, so `seschat index` never leaves a file unaccounted for.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install seschat
52
+ ```
53
+ Requires Python 3.10+.
54
+
55
+ ## Quick start
56
+
57
+ ```bash
58
+ seschat index ./my-project
59
+ seschat query ./my-project Cache
60
+ seschat semantic ./my-project "how does the app handle user login"
61
+ seschat ask ./my-project "Where is authentication handled?"
62
+ seschat explain ./my-project src/auth.py
63
+ ```
64
+
65
+ `index`, `query`, and `semantic` work with nothing beyond `pip install` —
66
+ `semantic` needs an embedding backend, covered below. `ask` and `explain`
67
+ need a chat model.
68
+
69
+ ## Setting up a model backend
70
+
71
+ `ask` and `explain` are local-first with an automatic hosted fallback —
72
+ there's nothing you *must* configure, but pick one:
73
+
74
+ **Local, no API key (Ollama):**
75
+ ```bash
76
+ ollama serve
77
+ ollama pull qwen3:8b
78
+ ```
79
+
80
+ **Hosted (Gemini):**
81
+ ```bash
82
+ export GEMINI_API_KEY=... # https://aistudio.google.com/
83
+ ```
84
+
85
+ Seschat tries Ollama first and falls back to Gemini automatically if it
86
+ isn't running, isn't installed, or doesn't have the model pulled. If
87
+ neither is usable, the error message tells you exactly what to fix rather
88
+ than a raw traceback.
89
+
90
+ ### Embeddings (for `semantic`, and the semantic half of `ask`)
91
+
92
+ Same shape, separate model:
93
+
94
+ ```bash
95
+ ollama pull nomic-embed-text # local
96
+ # or reuse the same GEMINI_API_KEY above for hosted embeddings
97
+ ```
98
+
99
+ If no embedding backend is available when you index, indexing still
100
+ succeeds — you just won't have `seschat semantic`, and `ask` quietly
101
+ falls back to keyword-only retrieval (visible under `--show-context`,
102
+ never silent).
103
+
104
+ Full environment variable reference is in
105
+ [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md).
106
+
107
+ ## How retrieval actually works
108
+
109
+ - **`query`** — plain SQL `LIKE` across extracted file paths, class
110
+ names, function names, imports, and comments. It doesn't see inside
111
+ function bodies or string literals; it only searches what got pulled
112
+ *out* of the file during indexing.
113
+ - **`semantic`** — one embedding vector per file (its structure plus a
114
+ source excerpt), ranked by cosine similarity against your query.
115
+ - **`ask`** — runs both of the above, normalizes each to a 0–1 score, and
116
+ merges them with a weighted sum. Every retrieved file's provenance and
117
+ score is inspectable via `--show-context`.
118
+ - **`explain`** — no retrieval at all. You name the file; it reads that
119
+ file's indexed structure and a fresh copy of its source, and asks the
120
+ model to summarize only that.
121
+
122
+ ## About the name
123
+
124
+ Seschat is Seshat, morphed with chat. Seshat was the
125
+ ancient Egyptian goddess of writing, measurement, and record-keeping —
126
+ credited with inventing writing itself and keeping the pharaoh's library.
127
+ A tool that reads your code, keeps a structured record of it, and lets
128
+ you talk to that record felt like a reasonable namesake. Say it out loud
129
+ and it should land closer to "seshat" than "session-chat."
130
+
131
+ ## Known limitations
132
+
133
+ - **Embeddings are per file, not per function or class.** A large file's
134
+ embedding can dilute a small relevant section inside it. Chunk-level
135
+ embeddings are on the roadmap; they need byte-range tracking in the
136
+ metadata layer first.
137
+ - **Indexing is drop-and-rebuild, not incremental.** Every `seschat
138
+ index` run re-scans and re-embeds the whole repository. Fine for
139
+ small-to-medium repos; slower than it needs to be on large ones you
140
+ re-index often.
141
+ - **Keyword ranking is match-count, not TF-IDF.** It's a cheap proxy for
142
+ relevance, not real ranking.
143
+ - **`.gitignore` support is close, not exact.** Rules are matched with
144
+ `fnmatch`, scoped per directory the way git actually applies them, but
145
+ it doesn't reproduce git's `**` wildcard semantics precisely.
146
+ - **Test your own model setup after installing.** The retrieval and
147
+ prompting logic is well-tested; the two live backends (Ollama, Gemini)
148
+ will behave slightly differently depending on your local setup. Run
149
+ `ask`/`explain`/`semantic` once against a real repo after install to
150
+ confirm your backend is actually reachable, and once with it
151
+ deliberately down to confirm the fallback kicks in.
152
+
153
+ ## Project layout
154
+
155
+ ```
156
+ seschat/
157
+ ├── cli.py # index, query, semantic, ask, explain
158
+ ├── scanner.py # traversal, ignore rules, extension → language mapping
159
+ ├── gitignore.py # scoped .gitignore parsing
160
+ ├── metadata.py # tree-sitter parsing → classes/functions/imports/comments
161
+ ├── db.py # SQLite schema and writes (metadata + embeddings)
162
+ ├── search.py # keyword search plus by-path structure/record lookups
163
+ ├── ask.py # hybrid retrieval → prompt → LLM → answer
164
+ ├── explain.py # file path → metadata + source → prompt → LLM → explanation
165
+ ├── llm.py # the only module that talks to a chat model
166
+ └── embeddings.py # the only module that talks to an embedding model
167
+ ```
168
+
169
+ Every module besides `cli.py` has no idea a CLI framework exists — `cli.py`
170
+ is a thin layer on top of plain function calls.
171
+
172
+ ## What's next
173
+
174
+ A compiler/test-failure assistant, verified test generation, a PR-review
175
+ assistant, architecture diagram generation, and general hardening
176
+ (incremental indexing, a config file, caching) are planned. The full
177
+ history and reasoning behind each stage of this project so far is in
178
+ [`roadmap.md`](roadmap.md), kept around because the "why" behind a
179
+ decision is usually more useful later than the decision itself.
180
+
181
+ ## Contributing
182
+
183
+ Issues and PRs are welcome. This is under active development, so expect
184
+ things to move between releases — check `CHANGELOG.md` for what changed
185
+ and why.
186
+
187
+ ## License
188
+
189
+ MIT — see [`LICENSE`](LICENSE).
@@ -0,0 +1,46 @@
1
+ [project]
2
+ name = "seschat"
3
+ version = "0.1.0b2"
4
+ readme = "README.md"
5
+ description = "A repository intelligence tool: scans a codebase, parses its structure with tree-sitter, indexes it in SQLite, and answers questions about it via hybrid keyword+semantic RAG. Ships as a CLI today."
6
+ requires-python = ">=3.10"
7
+ license = { text = "MIT" }
8
+ authors = [
9
+ { name = "Adit" }
10
+ ]
11
+ keywords = ["cli", "rag", "code-search", "tree-sitter", "llm", "developer-tools", "sqlite", "embeddings"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Environment :: Console",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Software Development :: Documentation",
23
+ "Topic :: Utilities",
24
+ ]
25
+ dependencies = [
26
+ "typer>=0.12.0",
27
+ "tree-sitter>=0.23.0",
28
+ "tree-sitter-language-pack>=0.2.0",
29
+ "ollama>=0.4.0",
30
+ "google-genai>=1.0.0",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/YOUR_GITHUB_USERNAME/seschat"
35
+ Repository = "https://github.com/YOUR_GITHUB_USERNAME/seschat"
36
+ Issues = "https://github.com/YOUR_GITHUB_USERNAME/seschat/issues"
37
+
38
+ [project.scripts]
39
+ seschat = "seschat.cli:main"
40
+
41
+ [build-system]
42
+ requires = ["setuptools>=61.0"]
43
+ build-backend = "setuptools.build_meta"
44
+
45
+ [tool.setuptools.packages.find]
46
+ include = ["seschat*"]
@@ -0,0 +1,3 @@
1
+ """Seschat — a repository intelligence tool."""
2
+
3
+ __version__ = "0.1.0"