codepulse-engine 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.
- codepulse_engine-0.1.0/LICENSE +21 -0
- codepulse_engine-0.1.0/PKG-INFO +191 -0
- codepulse_engine-0.1.0/README.md +140 -0
- codepulse_engine-0.1.0/codepulse/__init__.py +5 -0
- codepulse_engine-0.1.0/codepulse/api/app.py +1336 -0
- codepulse_engine-0.1.0/codepulse/api/errors.py +172 -0
- codepulse_engine-0.1.0/codepulse/api/security.py +189 -0
- codepulse_engine-0.1.0/codepulse/auth.py +406 -0
- codepulse_engine-0.1.0/codepulse/cli.py +1052 -0
- codepulse_engine-0.1.0/codepulse/config.py +475 -0
- codepulse_engine-0.1.0/codepulse/data_location.py +78 -0
- codepulse_engine-0.1.0/codepulse/embeddings/chunker.py +138 -0
- codepulse_engine-0.1.0/codepulse/embeddings/embedder.py +120 -0
- codepulse_engine-0.1.0/codepulse/git_diff.py +201 -0
- codepulse_engine-0.1.0/codepulse/indexer/engine.py +2655 -0
- codepulse_engine-0.1.0/codepulse/indexer/ignore.py +120 -0
- codepulse_engine-0.1.0/codepulse/ingestion_safety.py +169 -0
- codepulse_engine-0.1.0/codepulse/jobs.py +257 -0
- codepulse_engine-0.1.0/codepulse/mcp_server.py +269 -0
- codepulse_engine-0.1.0/codepulse/models.py +140 -0
- codepulse_engine-0.1.0/codepulse/observability.py +130 -0
- codepulse_engine-0.1.0/codepulse/parser/__init__.py +8 -0
- codepulse_engine-0.1.0/codepulse/parser/base.py +58 -0
- codepulse_engine-0.1.0/codepulse/parser/factory.py +37 -0
- codepulse_engine-0.1.0/codepulse/parser/graph.py +502 -0
- codepulse_engine-0.1.0/codepulse/parser/javascript.py +428 -0
- codepulse_engine-0.1.0/codepulse/parser/module_graph.py +232 -0
- codepulse_engine-0.1.0/codepulse/parser/python.py +331 -0
- codepulse_engine-0.1.0/codepulse/rate_limit.py +142 -0
- codepulse_engine-0.1.0/codepulse/repository_identity.py +83 -0
- codepulse_engine-0.1.0/codepulse/search/bm25.py +342 -0
- codepulse_engine-0.1.0/codepulse/search/ranker.py +382 -0
- codepulse_engine-0.1.0/codepulse/search/tokenizer.py +80 -0
- codepulse_engine-0.1.0/codepulse/search/vector.py +357 -0
- codepulse_engine-0.1.0/codepulse/storage/db.py +526 -0
- codepulse_engine-0.1.0/codepulse/storage/migrations.py +347 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/README +1 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/env.py +70 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/script.py.mako +28 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/135a7b064ea7_add_base_classes_and_relationship_type.py +82 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/20fc2d0607e2_add_file_content_hash_and_natural_key_.py +106 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/21a7cb7f1a85_initial_schema.py +105 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/2cd38eb12a7e_add_call_edge_repo_id_isolation_fix.py +112 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/3ba396e9c78f_add_symbol_natural_key_uniqueness.py +80 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/49572f834366_add_embedding_persistence_fields.py +102 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/7c3e5a91d2f4_add_module_edges.py +61 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/a41f0d2c6b8e_canonicalize_repository_urls.py +94 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/b0bdd63949f4_add_api_key_model.py +71 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/b9014c049e33_add_api_key_repository_role.py +65 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/c286d277ea21_add_repository_snapshot_model.py +62 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/de22df2fc3ce_add_index_job_model.py +59 -0
- codepulse_engine-0.1.0/codepulse/storage/schema_migrations/versions/f6e481353553_rename_dependency_to_call_edge_add_confidence.py +80 -0
- codepulse_engine-0.1.0/codepulse/symbol_identity.py +29 -0
- codepulse_engine-0.1.0/codepulse_engine.egg-info/PKG-INFO +191 -0
- codepulse_engine-0.1.0/codepulse_engine.egg-info/SOURCES.txt +123 -0
- codepulse_engine-0.1.0/codepulse_engine.egg-info/dependency_links.txt +1 -0
- codepulse_engine-0.1.0/codepulse_engine.egg-info/entry_points.txt +2 -0
- codepulse_engine-0.1.0/codepulse_engine.egg-info/requires.txt +27 -0
- codepulse_engine-0.1.0/codepulse_engine.egg-info/top_level.txt +1 -0
- codepulse_engine-0.1.0/pyproject.toml +185 -0
- codepulse_engine-0.1.0/setup.cfg +4 -0
- codepulse_engine-0.1.0/tests/test_api.py +128 -0
- codepulse_engine-0.1.0/tests/test_api_authorization.py +415 -0
- codepulse_engine-0.1.0/tests/test_api_key_management.py +308 -0
- codepulse_engine-0.1.0/tests/test_api_keys.py +313 -0
- codepulse_engine-0.1.0/tests/test_autocomplete_and_stats_isolation.py +211 -0
- codepulse_engine-0.1.0/tests/test_benchmark_harness.py +139 -0
- codepulse_engine-0.1.0/tests/test_bm25_vector.py +70 -0
- codepulse_engine-0.1.0/tests/test_call_edge_confidence.py +513 -0
- codepulse_engine-0.1.0/tests/test_call_graph_incremental_update.py +402 -0
- codepulse_engine-0.1.0/tests/test_call_graph_restart_restore.py +275 -0
- codepulse_engine-0.1.0/tests/test_cli.py +435 -0
- codepulse_engine-0.1.0/tests/test_cli_key_create.py +200 -0
- codepulse_engine-0.1.0/tests/test_config.py +293 -0
- codepulse_engine-0.1.0/tests/test_context_bundle.py +376 -0
- codepulse_engine-0.1.0/tests/test_cors.py +148 -0
- codepulse_engine-0.1.0/tests/test_default_database_location.py +178 -0
- codepulse_engine-0.1.0/tests/test_embedding_persistence.py +451 -0
- codepulse_engine-0.1.0/tests/test_error_format.py +288 -0
- codepulse_engine-0.1.0/tests/test_foreign_key_enforcement.py +188 -0
- codepulse_engine-0.1.0/tests/test_full_reindex_purges_stale_rows.py +316 -0
- codepulse_engine-0.1.0/tests/test_git_diff.py +275 -0
- codepulse_engine-0.1.0/tests/test_graph.py +180 -0
- codepulse_engine-0.1.0/tests/test_ignore_discovery.py +354 -0
- codepulse_engine-0.1.0/tests/test_impact_analysis.py +622 -0
- codepulse_engine-0.1.0/tests/test_incremental_indexing.py +947 -0
- codepulse_engine-0.1.0/tests/test_index_jobs.py +284 -0
- codepulse_engine-0.1.0/tests/test_index_persistence_integrity.py +213 -0
- codepulse_engine-0.1.0/tests/test_ingestion_safety.py +185 -0
- codepulse_engine-0.1.0/tests/test_ingestion_safety_endpoint.py +285 -0
- codepulse_engine-0.1.0/tests/test_inheritance_graph.py +638 -0
- codepulse_engine-0.1.0/tests/test_javascript_parser.py +104 -0
- codepulse_engine-0.1.0/tests/test_job_endpoints.py +267 -0
- codepulse_engine-0.1.0/tests/test_mcp_server.py +312 -0
- codepulse_engine-0.1.0/tests/test_migrate_command.py +486 -0
- codepulse_engine-0.1.0/tests/test_migrations.py +1254 -0
- codepulse_engine-0.1.0/tests/test_module_edges_persistence.py +396 -0
- codepulse_engine-0.1.0/tests/test_module_graph.py +401 -0
- codepulse_engine-0.1.0/tests/test_module_structure_endpoint.py +196 -0
- codepulse_engine-0.1.0/tests/test_no_fabricated_metrics.py +188 -0
- codepulse_engine-0.1.0/tests/test_observability.py +243 -0
- codepulse_engine-0.1.0/tests/test_packaging.py +97 -0
- codepulse_engine-0.1.0/tests/test_python_parser.py +134 -0
- codepulse_engine-0.1.0/tests/test_query_embedding_degradation.py +220 -0
- codepulse_engine-0.1.0/tests/test_ranker_and_chunker.py +170 -0
- codepulse_engine-0.1.0/tests/test_rate_limit.py +98 -0
- codepulse_engine-0.1.0/tests/test_rate_limit_middleware.py +202 -0
- codepulse_engine-0.1.0/tests/test_rbac.py +212 -0
- codepulse_engine-0.1.0/tests/test_references.py +305 -0
- codepulse_engine-0.1.0/tests/test_relevance_eval.py +305 -0
- codepulse_engine-0.1.0/tests/test_relevance_external.py +153 -0
- codepulse_engine-0.1.0/tests/test_repository_creation_authorization.py +235 -0
- codepulse_engine-0.1.0/tests/test_repository_file_upsert.py +275 -0
- codepulse_engine-0.1.0/tests/test_repository_identity.py +274 -0
- codepulse_engine-0.1.0/tests/test_repository_listing_and_resolve.py +327 -0
- codepulse_engine-0.1.0/tests/test_repository_scoped_search.py +353 -0
- codepulse_engine-0.1.0/tests/test_restart_idempotency.py +409 -0
- codepulse_engine-0.1.0/tests/test_search_symbol_aggregation.py +248 -0
- codepulse_engine-0.1.0/tests/test_sqlite_vec_semantic_index.py +459 -0
- codepulse_engine-0.1.0/tests/test_symbol_identity.py +322 -0
- codepulse_engine-0.1.0/tests/test_symbol_map_restart_restore.py +224 -0
- codepulse_engine-0.1.0/tests/test_symbol_upsert.py +240 -0
- codepulse_engine-0.1.0/tests/test_tantivy_lexical_index.py +573 -0
- codepulse_engine-0.1.0/tests/test_tokenizer.py +25 -0
- codepulse_engine-0.1.0/tests/test_vector_score_scaling.py +182 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dhairya Chhabra
|
|
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,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codepulse-engine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local-first code intelligence engine: hybrid keyword, semantic and call-graph search and impact analysis for developers and AI agents, over a CLI, a REST API and an MCP server.
|
|
5
|
+
Author: Dhairya Chhabra
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Chh-Dhairya/CodePulse
|
|
8
|
+
Project-URL: Repository, https://github.com/Chh-Dhairya/CodePulse
|
|
9
|
+
Project-URL: Issues, https://github.com/Chh-Dhairya/CodePulse/issues
|
|
10
|
+
Project-URL: Documentation, https://github.com/Chh-Dhairya/CodePulse/tree/HEAD/docs
|
|
11
|
+
Keywords: code search,code intelligence,semantic search,call graph,impact analysis,mcp,model context protocol,tree-sitter,local-first,developer tools
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
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: Topic :: Software Development
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Text Processing :: Indexing
|
|
21
|
+
Requires-Python: <3.13,>=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: fastapi<0.112.0,>=0.111.0
|
|
25
|
+
Requires-Dist: uvicorn[standard]<0.31.0,>=0.30.0
|
|
26
|
+
Requires-Dist: pydantic<2.8.0,>=2.7.0
|
|
27
|
+
Requires-Dist: sqlalchemy<2.1.0,>=2.0.30
|
|
28
|
+
Requires-Dist: alembic<1.14.0,>=1.13.1
|
|
29
|
+
Requires-Dist: tantivy<0.23.0,>=0.22.0
|
|
30
|
+
Requires-Dist: sqlite-vec<0.2.0,>=0.1.9
|
|
31
|
+
Requires-Dist: tree-sitter<0.22.0,>=0.21.0
|
|
32
|
+
Requires-Dist: tree-sitter-languages>=1.10.2
|
|
33
|
+
Requires-Dist: pathspec<1.2.0,>=1.1.0
|
|
34
|
+
Requires-Dist: networkx<4.0,>=3.0
|
|
35
|
+
Requires-Dist: mcp<2.0.0,>=1.9.0
|
|
36
|
+
Requires-Dist: sentence-transformers<3.1.0,>=3.0.0
|
|
37
|
+
Requires-Dist: torch<2.4.0,>=2.3.0
|
|
38
|
+
Requires-Dist: numpy<2
|
|
39
|
+
Requires-Dist: rich<16.0.0,>=15.0.0
|
|
40
|
+
Requires-Dist: prometheus-client<0.21.0,>=0.20.0
|
|
41
|
+
Requires-Dist: httpx<0.28.0,>=0.27.0
|
|
42
|
+
Requires-Dist: structlog<24.2.0,>=24.1.0
|
|
43
|
+
Provides-Extra: dev
|
|
44
|
+
Requires-Dist: pytest>=8.2.0; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-asyncio>=0.23.7; extra == "dev"
|
|
46
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
47
|
+
Requires-Dist: ruff>=0.4.8; extra == "dev"
|
|
48
|
+
Requires-Dist: mypy>=1.10.0; extra == "dev"
|
|
49
|
+
Requires-Dist: setuptools>=68.0; extra == "dev"
|
|
50
|
+
Dynamic: license-file
|
|
51
|
+
|
|
52
|
+
# CodePulse
|
|
53
|
+
|
|
54
|
+
**A local-first code intelligence engine for developers and AI agents.**
|
|
55
|
+
|
|
56
|
+
CodePulse indexes a repository once, then answers questions about it through one shared core, reachable from a CLI, a REST API, or an MCP server:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Index → Retrieve → Explain (structure) → Navigate → Decide (impact) → Act
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **Hybrid retrieval.** Keyword (BM25 via Tantivy), semantic (sentence-transformers embeddings in sqlite-vec) and structural (call graph) signals are fused into one ranking.
|
|
63
|
+
- **Agent-native.** Responses are structured and token-efficient, and they say explicitly when results were truncated or omitted.
|
|
64
|
+
- **Local-first.** Everything runs on your machine: SQLite, embedded indexes, a local embedding model. No external service or API key is needed to index and search.
|
|
65
|
+
|
|
66
|
+
Python and JavaScript/TypeScript sources are parsed (tree-sitter) into symbols, a call graph, and inheritance edges.
|
|
67
|
+
|
|
68
|
+
## Install
|
|
69
|
+
|
|
70
|
+
Requires **Python 3.11 or 3.12** (3.13+ is not supported yet).
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
python -m venv .venv
|
|
74
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
75
|
+
pip install -e ".[dev]"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
This installs a `codepulse` command (`python -m codepulse.cli` works too). The first run downloads the `all-MiniLM-L6-v2` embedding model from Hugging Face (about 90 MB) and caches it. After that CodePulse works offline.
|
|
79
|
+
|
|
80
|
+
## Quick start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
codepulse init . # writes codepulse.toml here
|
|
84
|
+
codepulse index path/to/repo # full index
|
|
85
|
+
codepulse search path/to/repo -q "parse config" # hybrid search (also: -t keyword|semantic)
|
|
86
|
+
codepulse symbol path/to/repo load_config # definition lookup
|
|
87
|
+
codepulse callers path/to/repo load_config # who calls it (direct + transitive)
|
|
88
|
+
codepulse impact path/to/repo load_config # blast radius if it changes
|
|
89
|
+
codepulse status path/to/repo # index freshness
|
|
90
|
+
codepulse doctor # environment diagnostics
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Every query command accepts `--json`. Run `codepulse --help` for the full list: `parse`, `search`, `impact`, `init`, `index`, `update`, `symbol`, `refs`, `callers`, `callees`, `similar`, `status`, `modules`, `doctor`, `migrate`, `key`, `serve`.
|
|
94
|
+
|
|
95
|
+
### Where the database lives
|
|
96
|
+
|
|
97
|
+
By default there is **one database per user**, in your operating system's per-user data directory (`%LOCALAPPDATA%\CodePulse` on Windows, `~/Library/Application Support/CodePulse` on macOS, `$XDG_DATA_HOME/codepulse` or `~/.local/share/codepulse` on Linux), so it does not matter which directory you run a command from and nothing is written into your projects. Set `CODEPULSE_DATA_DIR` to move that directory.
|
|
98
|
+
|
|
99
|
+
Two things override the default:
|
|
100
|
+
|
|
101
|
+
- An explicit setting always wins: `--db-url`, `CODEPULSE_DB_URL`, or `db_url` in `codepulse.toml` (`codepulse init` writes a project-local one).
|
|
102
|
+
- If the directory you run from already contains a `codepulse.db`, that file is used (it was the default before), so existing setups keep working unchanged.
|
|
103
|
+
|
|
104
|
+
Every command prints which database it is using on stderr, and says so when it is about to create a new one. A `codepulse.toml` is picked up only from the directory you run from.
|
|
105
|
+
|
|
106
|
+
### Incremental indexing
|
|
107
|
+
|
|
108
|
+
`codepulse update <repo>` re-indexes using `git diff` when the repository has git history and a prior snapshot exists. Otherwise it falls back to a full index. The call graph is held in memory, so the incremental path only applies inside a long-lived process such as `codepulse serve`. A one-shot CLI run always does a full index and reports `incremental: false`.
|
|
109
|
+
|
|
110
|
+
## REST API
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
codepulse serve # http://127.0.0.1:8000
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Interactive docs are at `/docs`. Health checks are `/health/live` and `/health/ready`; `/metrics` exposes Prometheus metrics. All other endpoints need an `X-API-Key` header.
|
|
117
|
+
|
|
118
|
+
Keys are scoped to repositories and carry a role: `viewer` (search and read) < `indexer` (plus indexing) < `admin` (plus managing keys). Creating a key over REST needs an admin key, so make your first one on the command line:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
codepulse key create --repo path/to/project # role indexer (the default)
|
|
122
|
+
codepulse key create --repo path/to/project --role admin --name ci
|
|
123
|
+
codepulse key create --repo a --repo b --json # several folders; machine-readable
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
It prints the key once (only its hash is stored) and registers the folder if it is not in the database yet, so you can index it with that key right away. At least one `--repo` is required, since a key with no repository can do nothing. Further keys can come from `POST /v1/admin/keys`. A key can index a new repository only if it already holds the `indexer` role (or higher) on some existing repository; the key that creates a repository becomes its `admin`, so it can follow the indexing job and see the result.
|
|
127
|
+
|
|
128
|
+
Main endpoints: `POST /v1/search`, `POST /v1/repositories/index`, `GET /v1/repositories/{id}/index-status`, `GET /v1/symbols/{id}`, `POST /v1/symbols/{id}/impact-analysis`, `POST /v1/symbols/{id}/similar`, `GET /v1/symbols/{id}/references`, `POST /v1/agent/context`. Errors always use one shape: `{"error": {"code", "message", "details"}}`. Requests are rate-limited per key (5 req/s, burst 20, configurable).
|
|
129
|
+
|
|
130
|
+
A local repository is identified by its canonical path (absolute, symlinks and `..` resolved, true case and an uppercase drive letter on Windows, no trailing separator), so `C:\\proj`, `c:/proj/` and `C:\\proj\\sub\\..` are one repository, not three.
|
|
131
|
+
|
|
132
|
+
Local-path ingestion can be restricted to an allow-list with `ingestion_allowed_roots` (or `CODEPULSE_INGESTION_ALLOWED_ROOTS`). Cloning from git URLs is not implemented: the URL is validated (https/ssh, SSRF check) and the request is then rejected with 501.
|
|
133
|
+
|
|
134
|
+
## MCP server
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
export CODEPULSE_MCP_API_KEY=cpk_... # or pass --api-key
|
|
138
|
+
codepulse serve --mcp # stdio transport
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The connection is scoped to the repositories the key can access. The MCP tools call the same functions as the CLI and REST API; there is no separate implementation.
|
|
142
|
+
|
|
143
|
+
## VS Code extension
|
|
144
|
+
|
|
145
|
+
A separate extension (CodeLens, hovers, impact tree, MCP registration) lives in its own repository, [`codepulse-vscode`](https://github.com/Chh-Dhairya/codepulse-vscode). It talks to a running `codepulse serve` using a scoped API key.
|
|
146
|
+
|
|
147
|
+
## Configuration
|
|
148
|
+
|
|
149
|
+
Precedence: CLI flags > `CODEPULSE_*` environment variables > `codepulse.toml` > built-in defaults. Common settings are `db_url`, `embedding_model`, `embedding_device`, `ingestion_allowed_roots`, and the `rate_limit_*` options. See `codepulse/config.py` for the full list.
|
|
150
|
+
|
|
151
|
+
## Upgrading an existing database
|
|
152
|
+
|
|
153
|
+
After updating CodePulse, bring the database up to date with one command:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
codepulse migrate # apply (backs the SQLite file up first)
|
|
157
|
+
codepulse migrate --check # only report: exit 0 up to date, 1 needs migrating, 2 cannot be migrated safely
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
It works on whatever database CodePulse is configured for (`--db-url`, `CODEPULSE_DB_URL`, a `codepulse.toml` in the current directory, or the default `sqlite:///codepulse.db`) and does the safe thing for each case:
|
|
161
|
+
|
|
162
|
+
| The database is | `migrate` |
|
|
163
|
+
|---|---|
|
|
164
|
+
| new (no tables yet) | creates it at the current schema |
|
|
165
|
+
| behind | copies it to `<file>.pre-<revision>-<time>.bak`, then upgrades it |
|
|
166
|
+
| from an older CodePulse and was never tracked | checks its schema against the models; if it matches (tables it does not have yet are simply created, empty), records it as up to date, after a backup |
|
|
167
|
+
| not tracked and its schema differs in any other way (a missing or extra column, an extra table) | refuses, lists what differs, changes nothing |
|
|
168
|
+
| from a newer CodePulse | refuses, changes nothing |
|
|
169
|
+
|
|
170
|
+
Every CodePulse command prints a warning on stderr when the database is behind, and `codepulse doctor` reports the schema state. Until you migrate, CodePulse keeps working; features that need a newer table (for example module structure after a restart) are simply unavailable and a warning is logged. A database CodePulse creates from scratch is tracked from the start, so it can always be upgraded this way. The migration scripts ship inside the package, so this works from an installed copy as well as from a checkout.
|
|
171
|
+
|
|
172
|
+
## Development
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
pytest tests/ -q
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Schema changes go through Alembic (`codepulse/storage/schema_migrations/`; `alembic.ini` in the repository root points at it for `alembic revision`/`alembic upgrade` during development). PostgreSQL, Redis, and distributed workers are intentionally out of scope for now.
|
|
179
|
+
|
|
180
|
+
## Project documents
|
|
181
|
+
|
|
182
|
+
- [`docs/CodePulse_Strategy_and_Roadmap.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/CodePulse_Strategy_and_Roadmap.md): the authoritative strategy, architecture, and milestone plan.
|
|
183
|
+
- [`docs/CODEPULSE_PRODUCT_AND_ARCHITECTURE.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/CODEPULSE_PRODUCT_AND_ARCHITECTURE.md): what CodePulse is and how it is built, as shipped.
|
|
184
|
+
- [`docs/CODEPULSE_CLIENT_STRATEGY.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/CODEPULSE_CLIENT_STRATEGY.md): the plan for the VS Code extension and other clients.
|
|
185
|
+
- [`docs/BACKUP_RESTORE.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/BACKUP_RESTORE.md): backing up and restoring a database.
|
|
186
|
+
- [`docs/ORIGINAL_DESIGN.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/ORIGINAL_DESIGN.md): the original design, kept for history (it describes infrastructure that was never built).
|
|
187
|
+
- [`docs/internal/`](https://github.com/Chh-Dhairya/CodePulse/tree/HEAD/docs/internal/): the working log (`CODEPULSE_PROGRESS.md`: what is built and verified, milestone by milestone) and `CODEPULSE_FUTURE_CHANGES.md` (known limitations and planned improvements).
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT. See [LICENSE](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/LICENSE).
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# CodePulse
|
|
2
|
+
|
|
3
|
+
**A local-first code intelligence engine for developers and AI agents.**
|
|
4
|
+
|
|
5
|
+
CodePulse indexes a repository once, then answers questions about it through one shared core, reachable from a CLI, a REST API, or an MCP server:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Index → Retrieve → Explain (structure) → Navigate → Decide (impact) → Act
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- **Hybrid retrieval.** Keyword (BM25 via Tantivy), semantic (sentence-transformers embeddings in sqlite-vec) and structural (call graph) signals are fused into one ranking.
|
|
12
|
+
- **Agent-native.** Responses are structured and token-efficient, and they say explicitly when results were truncated or omitted.
|
|
13
|
+
- **Local-first.** Everything runs on your machine: SQLite, embedded indexes, a local embedding model. No external service or API key is needed to index and search.
|
|
14
|
+
|
|
15
|
+
Python and JavaScript/TypeScript sources are parsed (tree-sitter) into symbols, a call graph, and inheritance edges.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
Requires **Python 3.11 or 3.12** (3.13+ is not supported yet).
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m venv .venv
|
|
23
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This installs a `codepulse` command (`python -m codepulse.cli` works too). The first run downloads the `all-MiniLM-L6-v2` embedding model from Hugging Face (about 90 MB) and caches it. After that CodePulse works offline.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
codepulse init . # writes codepulse.toml here
|
|
33
|
+
codepulse index path/to/repo # full index
|
|
34
|
+
codepulse search path/to/repo -q "parse config" # hybrid search (also: -t keyword|semantic)
|
|
35
|
+
codepulse symbol path/to/repo load_config # definition lookup
|
|
36
|
+
codepulse callers path/to/repo load_config # who calls it (direct + transitive)
|
|
37
|
+
codepulse impact path/to/repo load_config # blast radius if it changes
|
|
38
|
+
codepulse status path/to/repo # index freshness
|
|
39
|
+
codepulse doctor # environment diagnostics
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Every query command accepts `--json`. Run `codepulse --help` for the full list: `parse`, `search`, `impact`, `init`, `index`, `update`, `symbol`, `refs`, `callers`, `callees`, `similar`, `status`, `modules`, `doctor`, `migrate`, `key`, `serve`.
|
|
43
|
+
|
|
44
|
+
### Where the database lives
|
|
45
|
+
|
|
46
|
+
By default there is **one database per user**, in your operating system's per-user data directory (`%LOCALAPPDATA%\CodePulse` on Windows, `~/Library/Application Support/CodePulse` on macOS, `$XDG_DATA_HOME/codepulse` or `~/.local/share/codepulse` on Linux), so it does not matter which directory you run a command from and nothing is written into your projects. Set `CODEPULSE_DATA_DIR` to move that directory.
|
|
47
|
+
|
|
48
|
+
Two things override the default:
|
|
49
|
+
|
|
50
|
+
- An explicit setting always wins: `--db-url`, `CODEPULSE_DB_URL`, or `db_url` in `codepulse.toml` (`codepulse init` writes a project-local one).
|
|
51
|
+
- If the directory you run from already contains a `codepulse.db`, that file is used (it was the default before), so existing setups keep working unchanged.
|
|
52
|
+
|
|
53
|
+
Every command prints which database it is using on stderr, and says so when it is about to create a new one. A `codepulse.toml` is picked up only from the directory you run from.
|
|
54
|
+
|
|
55
|
+
### Incremental indexing
|
|
56
|
+
|
|
57
|
+
`codepulse update <repo>` re-indexes using `git diff` when the repository has git history and a prior snapshot exists. Otherwise it falls back to a full index. The call graph is held in memory, so the incremental path only applies inside a long-lived process such as `codepulse serve`. A one-shot CLI run always does a full index and reports `incremental: false`.
|
|
58
|
+
|
|
59
|
+
## REST API
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
codepulse serve # http://127.0.0.1:8000
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Interactive docs are at `/docs`. Health checks are `/health/live` and `/health/ready`; `/metrics` exposes Prometheus metrics. All other endpoints need an `X-API-Key` header.
|
|
66
|
+
|
|
67
|
+
Keys are scoped to repositories and carry a role: `viewer` (search and read) < `indexer` (plus indexing) < `admin` (plus managing keys). Creating a key over REST needs an admin key, so make your first one on the command line:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
codepulse key create --repo path/to/project # role indexer (the default)
|
|
71
|
+
codepulse key create --repo path/to/project --role admin --name ci
|
|
72
|
+
codepulse key create --repo a --repo b --json # several folders; machine-readable
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
It prints the key once (only its hash is stored) and registers the folder if it is not in the database yet, so you can index it with that key right away. At least one `--repo` is required, since a key with no repository can do nothing. Further keys can come from `POST /v1/admin/keys`. A key can index a new repository only if it already holds the `indexer` role (or higher) on some existing repository; the key that creates a repository becomes its `admin`, so it can follow the indexing job and see the result.
|
|
76
|
+
|
|
77
|
+
Main endpoints: `POST /v1/search`, `POST /v1/repositories/index`, `GET /v1/repositories/{id}/index-status`, `GET /v1/symbols/{id}`, `POST /v1/symbols/{id}/impact-analysis`, `POST /v1/symbols/{id}/similar`, `GET /v1/symbols/{id}/references`, `POST /v1/agent/context`. Errors always use one shape: `{"error": {"code", "message", "details"}}`. Requests are rate-limited per key (5 req/s, burst 20, configurable).
|
|
78
|
+
|
|
79
|
+
A local repository is identified by its canonical path (absolute, symlinks and `..` resolved, true case and an uppercase drive letter on Windows, no trailing separator), so `C:\\proj`, `c:/proj/` and `C:\\proj\\sub\\..` are one repository, not three.
|
|
80
|
+
|
|
81
|
+
Local-path ingestion can be restricted to an allow-list with `ingestion_allowed_roots` (or `CODEPULSE_INGESTION_ALLOWED_ROOTS`). Cloning from git URLs is not implemented: the URL is validated (https/ssh, SSRF check) and the request is then rejected with 501.
|
|
82
|
+
|
|
83
|
+
## MCP server
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
export CODEPULSE_MCP_API_KEY=cpk_... # or pass --api-key
|
|
87
|
+
codepulse serve --mcp # stdio transport
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The connection is scoped to the repositories the key can access. The MCP tools call the same functions as the CLI and REST API; there is no separate implementation.
|
|
91
|
+
|
|
92
|
+
## VS Code extension
|
|
93
|
+
|
|
94
|
+
A separate extension (CodeLens, hovers, impact tree, MCP registration) lives in its own repository, [`codepulse-vscode`](https://github.com/Chh-Dhairya/codepulse-vscode). It talks to a running `codepulse serve` using a scoped API key.
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
Precedence: CLI flags > `CODEPULSE_*` environment variables > `codepulse.toml` > built-in defaults. Common settings are `db_url`, `embedding_model`, `embedding_device`, `ingestion_allowed_roots`, and the `rate_limit_*` options. See `codepulse/config.py` for the full list.
|
|
99
|
+
|
|
100
|
+
## Upgrading an existing database
|
|
101
|
+
|
|
102
|
+
After updating CodePulse, bring the database up to date with one command:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
codepulse migrate # apply (backs the SQLite file up first)
|
|
106
|
+
codepulse migrate --check # only report: exit 0 up to date, 1 needs migrating, 2 cannot be migrated safely
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
It works on whatever database CodePulse is configured for (`--db-url`, `CODEPULSE_DB_URL`, a `codepulse.toml` in the current directory, or the default `sqlite:///codepulse.db`) and does the safe thing for each case:
|
|
110
|
+
|
|
111
|
+
| The database is | `migrate` |
|
|
112
|
+
|---|---|
|
|
113
|
+
| new (no tables yet) | creates it at the current schema |
|
|
114
|
+
| behind | copies it to `<file>.pre-<revision>-<time>.bak`, then upgrades it |
|
|
115
|
+
| from an older CodePulse and was never tracked | checks its schema against the models; if it matches (tables it does not have yet are simply created, empty), records it as up to date, after a backup |
|
|
116
|
+
| not tracked and its schema differs in any other way (a missing or extra column, an extra table) | refuses, lists what differs, changes nothing |
|
|
117
|
+
| from a newer CodePulse | refuses, changes nothing |
|
|
118
|
+
|
|
119
|
+
Every CodePulse command prints a warning on stderr when the database is behind, and `codepulse doctor` reports the schema state. Until you migrate, CodePulse keeps working; features that need a newer table (for example module structure after a restart) are simply unavailable and a warning is logged. A database CodePulse creates from scratch is tracked from the start, so it can always be upgraded this way. The migration scripts ship inside the package, so this works from an installed copy as well as from a checkout.
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pytest tests/ -q
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Schema changes go through Alembic (`codepulse/storage/schema_migrations/`; `alembic.ini` in the repository root points at it for `alembic revision`/`alembic upgrade` during development). PostgreSQL, Redis, and distributed workers are intentionally out of scope for now.
|
|
128
|
+
|
|
129
|
+
## Project documents
|
|
130
|
+
|
|
131
|
+
- [`docs/CodePulse_Strategy_and_Roadmap.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/CodePulse_Strategy_and_Roadmap.md): the authoritative strategy, architecture, and milestone plan.
|
|
132
|
+
- [`docs/CODEPULSE_PRODUCT_AND_ARCHITECTURE.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/CODEPULSE_PRODUCT_AND_ARCHITECTURE.md): what CodePulse is and how it is built, as shipped.
|
|
133
|
+
- [`docs/CODEPULSE_CLIENT_STRATEGY.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/CODEPULSE_CLIENT_STRATEGY.md): the plan for the VS Code extension and other clients.
|
|
134
|
+
- [`docs/BACKUP_RESTORE.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/BACKUP_RESTORE.md): backing up and restoring a database.
|
|
135
|
+
- [`docs/ORIGINAL_DESIGN.md`](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/docs/ORIGINAL_DESIGN.md): the original design, kept for history (it describes infrastructure that was never built).
|
|
136
|
+
- [`docs/internal/`](https://github.com/Chh-Dhairya/CodePulse/tree/HEAD/docs/internal/): the working log (`CODEPULSE_PROGRESS.md`: what is built and verified, milestone by milestone) and `CODEPULSE_FUTURE_CHANGES.md` (known limitations and planned improvements).
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT. See [LICENSE](https://github.com/Chh-Dhairya/CodePulse/blob/HEAD/LICENSE).
|