semtree 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.
- semtree-0.1.0/.github/workflows/ci.yml +54 -0
- semtree-0.1.0/.github/workflows/release.yml +70 -0
- semtree-0.1.0/.gitignore +57 -0
- semtree-0.1.0/LICENSE +21 -0
- semtree-0.1.0/PKG-INFO +359 -0
- semtree-0.1.0/README.md +293 -0
- semtree-0.1.0/pyproject.toml +86 -0
- semtree-0.1.0/src/semtree/__init__.py +4 -0
- semtree-0.1.0/src/semtree/cli.py +359 -0
- semtree-0.1.0/src/semtree/config.py +130 -0
- semtree-0.1.0/src/semtree/context/__init__.py +1 -0
- semtree-0.1.0/src/semtree/context/budget.py +84 -0
- semtree-0.1.0/src/semtree/context/builder.py +139 -0
- semtree-0.1.0/src/semtree/context/levels.py +127 -0
- semtree-0.1.0/src/semtree/db/__init__.py +1 -0
- semtree-0.1.0/src/semtree/db/schema.py +120 -0
- semtree-0.1.0/src/semtree/db/store.py +367 -0
- semtree-0.1.0/src/semtree/indexer/__init__.py +1 -0
- semtree-0.1.0/src/semtree/indexer/coordinator.py +180 -0
- semtree-0.1.0/src/semtree/indexer/docstrings.py +205 -0
- semtree-0.1.0/src/semtree/indexer/extractor.py +407 -0
- semtree-0.1.0/src/semtree/indexer/gitblame.py +88 -0
- semtree-0.1.0/src/semtree/indexer/hasher.py +34 -0
- semtree-0.1.0/src/semtree/indexer/parser.py +107 -0
- semtree-0.1.0/src/semtree/indexer/walker.py +134 -0
- semtree-0.1.0/src/semtree/log.py +56 -0
- semtree-0.1.0/src/semtree/mcp.py +160 -0
- semtree-0.1.0/src/semtree/memory/__init__.py +1 -0
- semtree-0.1.0/src/semtree/memory/lite.py +80 -0
- semtree-0.1.0/src/semtree/retrieval/__init__.py +1 -0
- semtree-0.1.0/src/semtree/retrieval/intent.py +188 -0
- semtree-0.1.0/src/semtree/retrieval/policy.py +125 -0
- semtree-0.1.0/src/semtree/retrieval/search.py +119 -0
- semtree-0.1.0/src/semtree/scripts/__init__.py +1 -0
- semtree-0.1.0/src/semtree/scripts/setup.py +211 -0
- semtree-0.1.0/tests/__init__.py +0 -0
- semtree-0.1.0/tests/conftest.py +60 -0
- semtree-0.1.0/tests/test_context.py +187 -0
- semtree-0.1.0/tests/test_coverage.py +1004 -0
- semtree-0.1.0/tests/test_indexer.py +283 -0
- semtree-0.1.0/tests/test_integration.py +162 -0
- semtree-0.1.0/tests/test_retrieval.py +182 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main", "develop"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main"]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
- name: Install ruff
|
|
18
|
+
run: pip install ruff
|
|
19
|
+
- name: Run ruff check
|
|
20
|
+
run: ruff check src/ tests/
|
|
21
|
+
|
|
22
|
+
test:
|
|
23
|
+
runs-on: ${{ matrix.os }}
|
|
24
|
+
strategy:
|
|
25
|
+
fail-fast: false
|
|
26
|
+
matrix:
|
|
27
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
28
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
29
|
+
exclude:
|
|
30
|
+
- os: macos-latest
|
|
31
|
+
python-version: "3.13"
|
|
32
|
+
- os: windows-latest
|
|
33
|
+
python-version: "3.13"
|
|
34
|
+
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
|
|
38
|
+
- uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: ${{ matrix.python-version }}
|
|
41
|
+
|
|
42
|
+
- name: Install semtree with dev dependencies
|
|
43
|
+
run: pip install -e ".[dev]"
|
|
44
|
+
|
|
45
|
+
- name: Run pytest with coverage
|
|
46
|
+
run: pytest tests/ -v --cov=semtree --cov-report=xml --cov-report=term-missing
|
|
47
|
+
|
|
48
|
+
- name: Upload coverage to Codecov
|
|
49
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
|
|
50
|
+
uses: codecov/codecov-action@v4
|
|
51
|
+
with:
|
|
52
|
+
files: ./coverage.xml
|
|
53
|
+
flags: unittests
|
|
54
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
|
|
20
|
+
- name: Install build tools
|
|
21
|
+
run: pip install hatch build
|
|
22
|
+
|
|
23
|
+
- name: Build distribution packages
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- uses: actions/upload-artifact@v4
|
|
27
|
+
with:
|
|
28
|
+
name: dist
|
|
29
|
+
path: dist/
|
|
30
|
+
|
|
31
|
+
publish:
|
|
32
|
+
needs: build
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
environment:
|
|
35
|
+
name: pypi
|
|
36
|
+
url: https://pypi.org/p/semtree
|
|
37
|
+
permissions:
|
|
38
|
+
id-token: write
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/download-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: dist
|
|
44
|
+
path: dist/
|
|
45
|
+
|
|
46
|
+
- name: Publish to PyPI
|
|
47
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
48
|
+
|
|
49
|
+
github-release:
|
|
50
|
+
needs: build
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
permissions:
|
|
53
|
+
contents: write
|
|
54
|
+
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- uses: actions/download-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: dist
|
|
61
|
+
path: dist/
|
|
62
|
+
|
|
63
|
+
- name: Create GitHub Release
|
|
64
|
+
env:
|
|
65
|
+
GH_TOKEN: ${{ github.token }}
|
|
66
|
+
run: |
|
|
67
|
+
TAG_NAME="${GITHUB_REF_NAME}"
|
|
68
|
+
gh release create "$TAG_NAME" dist/* \
|
|
69
|
+
--title "semtree $TAG_NAME" \
|
|
70
|
+
--generate-notes
|
semtree-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
eggs/
|
|
11
|
+
parts/
|
|
12
|
+
var/
|
|
13
|
+
sdist/
|
|
14
|
+
wheels/
|
|
15
|
+
lib64/
|
|
16
|
+
.installed.cfg
|
|
17
|
+
MANIFEST
|
|
18
|
+
.eggs/
|
|
19
|
+
|
|
20
|
+
# Virtual environments
|
|
21
|
+
.venv/
|
|
22
|
+
venv/
|
|
23
|
+
env/
|
|
24
|
+
ENV/
|
|
25
|
+
|
|
26
|
+
# Testing
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.coverage
|
|
29
|
+
.coverage.*
|
|
30
|
+
htmlcov/
|
|
31
|
+
coverage.xml
|
|
32
|
+
*.cover
|
|
33
|
+
.hypothesis/
|
|
34
|
+
|
|
35
|
+
# Build
|
|
36
|
+
.hatch/
|
|
37
|
+
*.whl
|
|
38
|
+
|
|
39
|
+
# semtree index
|
|
40
|
+
.ctx/
|
|
41
|
+
|
|
42
|
+
# IDE
|
|
43
|
+
.idea/
|
|
44
|
+
.vscode/
|
|
45
|
+
*.swp
|
|
46
|
+
*.swo
|
|
47
|
+
.DS_Store
|
|
48
|
+
|
|
49
|
+
# Logs
|
|
50
|
+
*.log
|
|
51
|
+
*.jsonl
|
|
52
|
+
|
|
53
|
+
# Secrets
|
|
54
|
+
.env
|
|
55
|
+
.env.*
|
|
56
|
+
*.pem
|
|
57
|
+
*.key
|
semtree-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nikolas de Hor
|
|
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.
|
semtree-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: semtree
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Semantic code trees for AI assistants. Index once, feed smart context to Claude, Cursor, and Copilot.
|
|
5
|
+
Project-URL: Homepage, https://github.com/nikolasdehor/semtree
|
|
6
|
+
Project-URL: Repository, https://github.com/nikolasdehor/semtree
|
|
7
|
+
Project-URL: Issues, https://github.com/nikolasdehor/semtree/issues
|
|
8
|
+
Author: Nikolas de Hor
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,claude,code-intelligence,context,copilot,cursor,mcp,tree-sitter
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: click>=8.0
|
|
23
|
+
Requires-Dist: pathspec>=0.12
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: mcp<2.0,>=1.0; extra == 'all'
|
|
26
|
+
Requires-Dist: tiktoken>=0.6; extra == 'all'
|
|
27
|
+
Requires-Dist: tree-sitter-c>=0.23; extra == 'all'
|
|
28
|
+
Requires-Dist: tree-sitter-cpp>=0.23; extra == 'all'
|
|
29
|
+
Requires-Dist: tree-sitter-go>=0.23; extra == 'all'
|
|
30
|
+
Requires-Dist: tree-sitter-java>=0.23; extra == 'all'
|
|
31
|
+
Requires-Dist: tree-sitter-javascript>=0.23; extra == 'all'
|
|
32
|
+
Requires-Dist: tree-sitter-python>=0.23; extra == 'all'
|
|
33
|
+
Requires-Dist: tree-sitter-rust>=0.23; extra == 'all'
|
|
34
|
+
Requires-Dist: tree-sitter-typescript>=0.23; extra == 'all'
|
|
35
|
+
Requires-Dist: tree-sitter>=0.25; extra == 'all'
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: mcp<2.0,>=1.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
41
|
+
Requires-Dist: tiktoken>=0.6; extra == 'dev'
|
|
42
|
+
Requires-Dist: tree-sitter-c>=0.23; extra == 'dev'
|
|
43
|
+
Requires-Dist: tree-sitter-cpp>=0.23; extra == 'dev'
|
|
44
|
+
Requires-Dist: tree-sitter-go>=0.23; extra == 'dev'
|
|
45
|
+
Requires-Dist: tree-sitter-java>=0.23; extra == 'dev'
|
|
46
|
+
Requires-Dist: tree-sitter-javascript>=0.23; extra == 'dev'
|
|
47
|
+
Requires-Dist: tree-sitter-python>=0.23; extra == 'dev'
|
|
48
|
+
Requires-Dist: tree-sitter-rust>=0.23; extra == 'dev'
|
|
49
|
+
Requires-Dist: tree-sitter-typescript>=0.23; extra == 'dev'
|
|
50
|
+
Requires-Dist: tree-sitter>=0.25; extra == 'dev'
|
|
51
|
+
Provides-Extra: mcp
|
|
52
|
+
Requires-Dist: mcp<2.0,>=1.0; extra == 'mcp'
|
|
53
|
+
Provides-Extra: parse
|
|
54
|
+
Requires-Dist: tree-sitter-c>=0.23; extra == 'parse'
|
|
55
|
+
Requires-Dist: tree-sitter-cpp>=0.23; extra == 'parse'
|
|
56
|
+
Requires-Dist: tree-sitter-go>=0.23; extra == 'parse'
|
|
57
|
+
Requires-Dist: tree-sitter-java>=0.23; extra == 'parse'
|
|
58
|
+
Requires-Dist: tree-sitter-javascript>=0.23; extra == 'parse'
|
|
59
|
+
Requires-Dist: tree-sitter-python>=0.23; extra == 'parse'
|
|
60
|
+
Requires-Dist: tree-sitter-rust>=0.23; extra == 'parse'
|
|
61
|
+
Requires-Dist: tree-sitter-typescript>=0.23; extra == 'parse'
|
|
62
|
+
Requires-Dist: tree-sitter>=0.25; extra == 'parse'
|
|
63
|
+
Provides-Extra: tokens
|
|
64
|
+
Requires-Dist: tiktoken>=0.6; extra == 'tokens'
|
|
65
|
+
Description-Content-Type: text/markdown
|
|
66
|
+
|
|
67
|
+
<p align="center">
|
|
68
|
+
<img src="https://img.shields.io/badge/semtree-semantic%20code%20trees-0d1117?style=for-the-badge&labelColor=0d1117&color=6e40c9" alt="semtree" height="48">
|
|
69
|
+
</p>
|
|
70
|
+
|
|
71
|
+
<p align="center">
|
|
72
|
+
<strong>Semantic code trees for AI assistants</strong>
|
|
73
|
+
</p>
|
|
74
|
+
|
|
75
|
+
<p align="center">
|
|
76
|
+
<a href="https://pypi.org/project/semtree/"><img src="https://img.shields.io/pypi/v/semtree?color=6e40c9&label=PyPI" alt="PyPI version"></a>
|
|
77
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11%2B-3776ab?logo=python&logoColor=white" alt="Python 3.11+"></a>
|
|
78
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-22c55e" alt="License MIT"></a>
|
|
79
|
+
<a href="https://github.com/nikolasdehor/semtree/actions/workflows/ci.yml"><img src="https://github.com/nikolasdehor/semtree/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
80
|
+
<img src="https://img.shields.io/github/stars/nikolasdehor/semtree?style=flat&color=6e40c9" alt="Stars">
|
|
81
|
+
</p>
|
|
82
|
+
|
|
83
|
+
<p align="center">
|
|
84
|
+
<a href="#quick-start">Quick Start</a> ·
|
|
85
|
+
<a href="#features">Features</a> ·
|
|
86
|
+
<a href="#cli-commands">CLI</a> ·
|
|
87
|
+
<a href="#mcp-integration">MCP</a> ·
|
|
88
|
+
<a href="#why-semtree-vs-context-lens">Comparison</a>
|
|
89
|
+
</p>
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
semtree indexes your codebase with tree-sitter, extracts symbols and docstrings across Python, JavaScript/TypeScript, Go, Rust, Java, C/C++, and more, and delivers token-optimized context to AI coding assistants. It exposes three MCP tools (`index_project`, `get_context`, `search_symbols`) that Claude Code, Cursor, Copilot, and Codex can call directly - and an intent classifier that selects the right retrieval strategy based on what you are trying to do.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Quick Start
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install "semtree[all]"
|
|
101
|
+
semtree index
|
|
102
|
+
semtree setup --target all
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The `setup` command writes config files for every assistant automatically (see [MCP Integration](#mcp-integration)).
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Token Savings
|
|
110
|
+
|
|
111
|
+
Feeding raw source files to an AI assistant wastes context. semtree extracts only the symbols relevant to your task.
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
Before 45,000 tokens (entire src/ directory pasted into context)
|
|
115
|
+
After 6,000 tokens (semtree context "add rate limiting to the API")
|
|
116
|
+
|
|
117
|
+
Savings: ~87%
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The context budget is configurable (default: 8,000 tokens). Pass `--budget` on the CLI or set `default_token_budget` in `.ctx/semtree.json`.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Features
|
|
125
|
+
|
|
126
|
+
**Multi-language symbol extraction**
|
|
127
|
+
tree-sitter parses Python, JavaScript, TypeScript, Go, Rust, Java, C, and C++. Docstrings, signatures, and git metadata are extracted for every function, class, method, constant, and type definition.
|
|
128
|
+
|
|
129
|
+
**Intent-aware retrieval**
|
|
130
|
+
The intent classifier scores your query using weighted signals (keyword overlap, structural cues, file-path hints) to select the optimal retrieval strategy - not a simple regex match.
|
|
131
|
+
|
|
132
|
+
**Token-budgeted context builder**
|
|
133
|
+
Context output is shaped to a configurable token budget. The detail level (0 = minimal signatures, 3 = full docstrings + git context) is chosen automatically or overridden per call.
|
|
134
|
+
|
|
135
|
+
**MCP auto-configuration**
|
|
136
|
+
`semtree setup` writes `.claude/mcp.json`, `.cursor/mcp.json`, `.vscode/settings.json`, and `AGENTS.md` in one command. Three MCP tools are immediately available to connected assistants.
|
|
137
|
+
|
|
138
|
+
**Project memory**
|
|
139
|
+
Store rules, references, and notes directly in the index database. Memory entries are included in context output so your AI assistant carries persistent project-specific knowledge.
|
|
140
|
+
|
|
141
|
+
**Git temporal context**
|
|
142
|
+
Every symbol is annotated with the git author and date from `git blame`. Assistants can see who last touched a function and when.
|
|
143
|
+
|
|
144
|
+
**Concurrent-safe indexing**
|
|
145
|
+
A lock file prevents two concurrent processes from corrupting the SQLite database. Incremental indexing uses SHA-1 hashes to skip unchanged files.
|
|
146
|
+
|
|
147
|
+
**Hook debounce**
|
|
148
|
+
The file-watcher integration applies a 2-second cooldown so rapid consecutive saves do not trigger redundant re-indexing.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Why semtree vs context-lens
|
|
153
|
+
|
|
154
|
+
| Feature | semtree | context-lens |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| Multi-language docstrings (Python, JS/TS, Go, Rust) | Yes | Python only |
|
|
157
|
+
| MCP auto-config (.claude/mcp.json) | Yes | Manual |
|
|
158
|
+
| Hook debounce (2s cooldown) | Yes | No (fires every write) |
|
|
159
|
+
| Git temporal context (author, date) | Yes | No |
|
|
160
|
+
| Intent detection confidence | Weighted scoring | Regex 30% |
|
|
161
|
+
| Typed store returns | Dataclasses | Raw sqlite3.Row |
|
|
162
|
+
| Modular CLI | Click groups | 1000-line monolith |
|
|
163
|
+
| Concurrent-safe indexing | Lock file | No protection |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Architecture
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
CLI (semtree)
|
|
171
|
+
|
|
|
172
|
+
v
|
|
173
|
+
Indexer (coordinator.py)
|
|
174
|
+
walk -> SHA-1 hash -> tree-sitter parse -> extract symbols -> git blame
|
|
175
|
+
|
|
|
176
|
+
v
|
|
177
|
+
SQLite (.ctx/index.db)
|
|
178
|
+
files | symbols (FTS5) | memory
|
|
179
|
+
|
|
|
180
|
+
v
|
|
181
|
+
Retrieval (retrieval/)
|
|
182
|
+
intent classifier -> search.py -> policy.py
|
|
183
|
+
|
|
|
184
|
+
v
|
|
185
|
+
Context Builder (context/builder.py)
|
|
186
|
+
budget.py + levels.py -> Markdown output
|
|
187
|
+
|
|
|
188
|
+
v
|
|
189
|
+
MCP Server (mcp.py)
|
|
190
|
+
index_project | get_context | search_symbols
|
|
191
|
+
|
|
|
192
|
+
v
|
|
193
|
+
AI Assistant (Claude Code / Cursor / Copilot / Codex)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## CLI Commands
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
semtree index Index the project (incremental by default)
|
|
202
|
+
semtree index --force Re-index all files, ignoring cache
|
|
203
|
+
|
|
204
|
+
semtree context "QUERY" Build context for a task, print to stdout
|
|
205
|
+
semtree context "QUERY" -b 4000 Limit context to 4,000 tokens
|
|
206
|
+
semtree context "QUERY" -l 0 Override detail level (0=minimal, 3=full)
|
|
207
|
+
semtree context "QUERY" -f FILE Restrict context to a single file
|
|
208
|
+
semtree context "QUERY" -o FILE Write context to a file instead of stdout
|
|
209
|
+
|
|
210
|
+
semtree search "QUERY" Search symbols by name or keyword
|
|
211
|
+
semtree search "QUERY" -k class Filter by kind (function|class|method|const|type|var)
|
|
212
|
+
semtree search "QUERY" --json Output results as JSON
|
|
213
|
+
|
|
214
|
+
semtree status Show index stats (files, symbols, last updated)
|
|
215
|
+
|
|
216
|
+
semtree memory add rule KEY VAL Store a project rule in the index
|
|
217
|
+
semtree memory add ref KEY VAL Store a file or URL reference
|
|
218
|
+
semtree memory add note KEY VAL Store a freeform note
|
|
219
|
+
semtree memory list List all memory entries
|
|
220
|
+
semtree memory list -k rule List only rules
|
|
221
|
+
semtree memory remove rule KEY Remove a memory entry
|
|
222
|
+
|
|
223
|
+
semtree setup --target all Configure all AI assistants (writes config files)
|
|
224
|
+
semtree setup --target claude Configure Claude Code only
|
|
225
|
+
semtree setup --dry-run Preview setup changes without writing
|
|
226
|
+
|
|
227
|
+
semtree config Print current config as JSON
|
|
228
|
+
semtree config --init Write default config to .ctx/semtree.json
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## MCP Integration
|
|
234
|
+
|
|
235
|
+
### Automatic (recommended)
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
semtree setup --target claude
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
This creates or updates `.claude/mcp.json` in your project root with the `semtree-mcp` server entry. Restart Claude Code and the three MCP tools appear automatically.
|
|
242
|
+
|
|
243
|
+
### Manual
|
|
244
|
+
|
|
245
|
+
Add to `.claude/mcp.json`:
|
|
246
|
+
|
|
247
|
+
```json
|
|
248
|
+
{
|
|
249
|
+
"mcpServers": {
|
|
250
|
+
"semtree": {
|
|
251
|
+
"command": "semtree-mcp",
|
|
252
|
+
"args": [],
|
|
253
|
+
"env": {
|
|
254
|
+
"SEMTREE_ROOT": "/path/to/your/project"
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Available MCP Tools
|
|
262
|
+
|
|
263
|
+
| Tool | Description |
|
|
264
|
+
|---|---|
|
|
265
|
+
| `index_project` | Index (or re-index) the project. Returns file and symbol counts. |
|
|
266
|
+
| `get_context` | Build a context string for a task query within a token budget. |
|
|
267
|
+
| `search_symbols` | Search symbols by name or keyword with optional kind filter. |
|
|
268
|
+
|
|
269
|
+
### Other Assistants
|
|
270
|
+
|
|
271
|
+
`semtree setup --target cursor` writes `.cursor/mcp.json`.
|
|
272
|
+
|
|
273
|
+
`semtree setup --target copilot` adds a context instruction to `.vscode/settings.json`.
|
|
274
|
+
|
|
275
|
+
`semtree setup --target codex` appends a context block to `AGENTS.md` (or `CODEX.md`).
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Configuration
|
|
280
|
+
|
|
281
|
+
semtree reads `.ctx/semtree.json` in the project root. Run `semtree config --init` to write a config file with all defaults.
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"include_extensions": [".py", ".js", ".ts", ".tsx", ".jsx",
|
|
286
|
+
".go", ".rs", ".java", ".c", ".cpp",
|
|
287
|
+
".h", ".hpp", ".rb", ".php", ".swift",
|
|
288
|
+
".kt", ".cs", ".md", ".yaml", ".toml", ".json"],
|
|
289
|
+
"exclude_dirs": [".git", "node_modules", "__pycache__", ".venv",
|
|
290
|
+
"dist", "build", "target", ".ctx"],
|
|
291
|
+
"max_file_size_kb": 512,
|
|
292
|
+
"use_gitignore": true,
|
|
293
|
+
"default_token_budget": 8000,
|
|
294
|
+
"git_context": true,
|
|
295
|
+
"mcp_host": "127.0.0.1",
|
|
296
|
+
"mcp_port": 5137
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
| Key | Default | Description |
|
|
301
|
+
|---|---|---|
|
|
302
|
+
| `include_extensions` | (list above) | File extensions to index |
|
|
303
|
+
| `exclude_dirs` | (list above) | Directories to skip |
|
|
304
|
+
| `max_file_size_kb` | `512` | Skip files larger than this |
|
|
305
|
+
| `use_gitignore` | `true` | Respect `.gitignore` patterns |
|
|
306
|
+
| `default_token_budget` | `8000` | Default token limit for context output |
|
|
307
|
+
| `git_context` | `true` | Annotate symbols with git author and date |
|
|
308
|
+
| `mcp_host` | `127.0.0.1` | MCP server bind host |
|
|
309
|
+
| `mcp_port` | `5137` | MCP server port |
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Installation
|
|
314
|
+
|
|
315
|
+
Install with all optional dependencies (recommended):
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
pip install "semtree[all]"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Install only what you need:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
pip install semtree # CLI only (no parsing, no tokens, no MCP)
|
|
325
|
+
pip install "semtree[parse]" # + tree-sitter parsers (required for indexing)
|
|
326
|
+
pip install "semtree[tokens]" # + tiktoken (accurate token counting)
|
|
327
|
+
pip install "semtree[mcp]" # + MCP server support
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Requirements: Python 3.11+, SQLite 3.35+ (bundled with Python).
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Project Layout
|
|
335
|
+
|
|
336
|
+
After the first `semtree index`, a `.ctx/` directory is created in your project root:
|
|
337
|
+
|
|
338
|
+
```
|
|
339
|
+
.ctx/
|
|
340
|
+
index.db SQLite database (files, symbols with FTS5, memory)
|
|
341
|
+
semtree.json Config (created by semtree config --init)
|
|
342
|
+
indexing.lock Lock file preventing concurrent writes
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Add `.ctx/index.db` to `.gitignore` if you do not want to commit the index.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
MIT. See [LICENSE](LICENSE).
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
<p align="center">
|
|
356
|
+
Built by <a href="https://github.com/nikolasdehor">Nikolas de Hor</a>
|
|
357
|
+
<br>
|
|
358
|
+
<sub>Feed smart context to your AI assistant, not raw files</sub>
|
|
359
|
+
</p>
|