pycodesage 0.3.1__tar.gz → 0.3.2__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.
- pycodesage-0.3.2/PKG-INFO +350 -0
- pycodesage-0.3.2/README.md +295 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/__init__.py +1 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/context.py +0 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/engine.py +313 -108
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/commands/__init__.py +2 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/commands/chat.py +25 -7
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/commands/init.py +1 -1
- pycodesage-0.3.2/codesage/cli/commands/review.py +138 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/groups/__init__.py +2 -1
- pycodesage-0.3.2/codesage/cli/groups/hook.py +173 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/groups/mcp.py +39 -98
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/main.py +4 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/utils/console.py +0 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/confidence.py +1 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/context_provider.py +31 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/indexer.py +75 -3
- pycodesage-0.3.2/codesage/core/relationship_extractor.py +1211 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/suggester.py +3 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/hooks/installer.py +63 -10
- pycodesage-0.3.2/codesage/hooks/templates/pre-commit.sh +34 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/mcp/__init__.py +10 -6
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/mcp/server.py +350 -48
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/__init__.py +3 -27
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/hooks.py +8 -2
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/learning_engine.py +13 -4
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/memory_graph.py +10 -12
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/memory_manager.py +12 -12
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/pattern_miner.py +1 -2
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/preference_store.py +2 -12
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/style_analyzer.py +162 -63
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/parsers/treesitter_parser.py +1 -3
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/review/__init__.py +4 -4
- pycodesage-0.3.2/codesage/review/checks/__init__.py +26 -0
- pycodesage-0.3.2/codesage/review/checks/complexity.py +116 -0
- pycodesage-0.3.2/codesage/review/checks/generic_checks.py +255 -0
- pycodesage-0.3.2/codesage/review/checks/naming.py +243 -0
- pycodesage-0.3.2/codesage/review/checks/python_checks.py +287 -0
- pycodesage-0.3.2/codesage/review/checks/structure.py +210 -0
- pycodesage-0.3.2/codesage/review/checks/treesitter_checks.py +478 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/review/diff.py +20 -21
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/review/hybrid_analyzer.py +1 -4
- pycodesage-0.3.2/codesage/review/models.py +347 -0
- pycodesage-0.3.2/codesage/review/output.py +224 -0
- pycodesage-0.3.2/codesage/review/pipeline.py +690 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/review/smells.py +12 -15
- pycodesage-0.3.2/codesage/review/suppression.py +251 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/__init__.py +0 -2
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/scanner.py +1 -1
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/kuzu_store.py +30 -10
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/lance_store.py +0 -2
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/manager.py +6 -2
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/utils/config.py +11 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/utils/language_detector.py +8 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/utils/logging.py +1 -1
- pycodesage-0.3.2/codesage/utils/treesitter_utils.py +88 -0
- pycodesage-0.3.2/pycodesage.egg-info/PKG-INFO +350 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/pycodesage.egg-info/SOURCES.txt +14 -11
- {pycodesage-0.3.1 → pycodesage-0.3.2}/pyproject.toml +4 -1
- pycodesage-0.3.1/PKG-INFO +0 -277
- pycodesage-0.3.1/README.md +0 -222
- pycodesage-0.3.1/codesage/cli/utils/formatters.py +0 -141
- pycodesage-0.3.1/codesage/core/relationship_extractor.py +0 -409
- pycodesage-0.3.1/codesage/docs/__init__.py +0 -6
- pycodesage-0.3.1/codesage/docs/generator.py +0 -469
- pycodesage-0.3.1/codesage/docs/onboarding.py +0 -69
- pycodesage-0.3.1/codesage/memory/profile.py +0 -355
- pycodesage-0.3.1/codesage/review/analyzer.py +0 -218
- pycodesage-0.3.1/codesage/review/formatters.py +0 -132
- pycodesage-0.3.1/codesage/review/models.py +0 -107
- pycodesage-0.3.1/codesage/security/formatters.py +0 -179
- pycodesage-0.3.1/codesage/utils/features.py +0 -40
- pycodesage-0.3.1/codesage/utils/health.py +0 -244
- pycodesage-0.3.1/codesage/utils/mixins.py +0 -77
- pycodesage-0.3.1/pycodesage.egg-info/PKG-INFO +0 -277
- {pycodesage-0.3.1 → pycodesage-0.3.2}/LICENSE +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/__main__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/commands.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/models.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/prompts.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/chat/query_expansion.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/commands/index.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/utils/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/utils/decorators.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/utils/options.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/cli/utils/signals.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/deep_analyzer.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/core/resource_manager.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/hooks/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/llm/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/llm/embeddings.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/llm/prompts.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/llm/provider.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/mcp/global_server.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/models.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/pattern_store.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/memory/schemas.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/models/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/models/code_element.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/models/context.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/models/smell.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/models/suggestion.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/parsers/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/parsers/base.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/parsers/python_parser.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/parsers/registry.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/review/prompts.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/models.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/config.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/crypto.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/deserialization.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/injection.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/secrets.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/security/rules/xss.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/base.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/database.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/storage/vector_base.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/utils/__init__.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/utils/rate_limiter.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/codesage/utils/retry.py +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/pycodesage.egg-info/dependency_links.txt +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/pycodesage.egg-info/entry_points.txt +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/pycodesage.egg-info/requires.txt +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/pycodesage.egg-info/top_level.txt +0 -0
- {pycodesage-0.3.1 → pycodesage-0.3.2}/setup.cfg +0 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pycodesage
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: Local-first CLI code intelligence tool with LangChain-powered RAG
|
|
5
|
+
Author: Keshav Ashiya
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/keshavashiya/codesage
|
|
8
|
+
Project-URL: Repository, https://github.com/keshavashiya/codesage
|
|
9
|
+
Project-URL: Issues, https://github.com/keshavashiya/codesage/issues
|
|
10
|
+
Keywords: code,ai,cli,devtools,rag,langchain
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: typer[all]>=0.9.0
|
|
20
|
+
Requires-Dist: rich>=13.7.0
|
|
21
|
+
Requires-Dist: langchain>=0.3.0
|
|
22
|
+
Requires-Dist: langchain-community>=0.3.0
|
|
23
|
+
Requires-Dist: langchain-ollama>=0.2.0
|
|
24
|
+
Requires-Dist: lancedb>=0.4.0
|
|
25
|
+
Requires-Dist: kuzu>=0.3.0
|
|
26
|
+
Requires-Dist: pyarrow>=14.0.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
28
|
+
Requires-Dist: gitpython>=3.1.0
|
|
29
|
+
Requires-Dist: numpy<2.0.0,>=1.26.0
|
|
30
|
+
Requires-Dist: pandas>=2.0.0
|
|
31
|
+
Provides-Extra: openai
|
|
32
|
+
Requires-Dist: langchain-openai>=0.1.0; extra == "openai"
|
|
33
|
+
Provides-Extra: anthropic
|
|
34
|
+
Requires-Dist: langchain-anthropic>=0.1.0; extra == "anthropic"
|
|
35
|
+
Provides-Extra: multi-language
|
|
36
|
+
Requires-Dist: tree-sitter>=0.23.0; extra == "multi-language"
|
|
37
|
+
Requires-Dist: tree-sitter-javascript>=0.23.0; extra == "multi-language"
|
|
38
|
+
Requires-Dist: tree-sitter-typescript>=0.23.0; extra == "multi-language"
|
|
39
|
+
Requires-Dist: tree-sitter-go>=0.23.0; extra == "multi-language"
|
|
40
|
+
Requires-Dist: tree-sitter-rust>=0.23.0; extra == "multi-language"
|
|
41
|
+
Provides-Extra: mcp
|
|
42
|
+
Requires-Dist: mcp>=1.0.0; extra == "mcp"
|
|
43
|
+
Requires-Dist: starlette>=0.27.0; extra == "mcp"
|
|
44
|
+
Requires-Dist: uvicorn>=0.23.0; extra == "mcp"
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
48
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
49
|
+
Requires-Dist: black>=23.12.0; extra == "dev"
|
|
50
|
+
Requires-Dist: ruff>=0.1.8; extra == "dev"
|
|
51
|
+
Requires-Dist: mypy>=1.7.0; extra == "dev"
|
|
52
|
+
Provides-Extra: all
|
|
53
|
+
Requires-Dist: pycodesage[anthropic,dev,mcp,multi-language,openai]; extra == "all"
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
|
|
56
|
+
# CodeSage
|
|
57
|
+
|
|
58
|
+
Local-first code intelligence CLI. Search, analyze, and chat with your codebase using natural language — all running on your machine via Ollama.
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# macOS
|
|
64
|
+
brew install pipx && pipx ensurepath
|
|
65
|
+
|
|
66
|
+
# Linux
|
|
67
|
+
python3 -m pip install --user pipx && python3 -m pipx ensurepath
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pipx install pycodesage
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Optional features
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Tree-sitter AST analysis for JS, TS, Go, Rust (recommended)
|
|
78
|
+
pipx inject pycodesage "pycodesage[multi-language]"
|
|
79
|
+
|
|
80
|
+
# MCP server for Claude Desktop / Cursor / Windsurf
|
|
81
|
+
pipx inject pycodesage "pycodesage[mcp]"
|
|
82
|
+
|
|
83
|
+
# Both at once
|
|
84
|
+
pipx inject pycodesage "pycodesage[multi-language,mcp]"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Without `multi-language`, review checks for non-Python files still run but use text/regex heuristics instead of real AST parsing.
|
|
88
|
+
|
|
89
|
+
## Requirements
|
|
90
|
+
|
|
91
|
+
Ollama must be running:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
ollama pull qwen2.5-coder:7b # LLM
|
|
95
|
+
ollama pull nomic-embed-text # embeddings (fast, lightweight)
|
|
96
|
+
ollama serve
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Alternatively**, use any Ollama-compatible model. `qwen3-embedding` gives significantly better semantic search if you have the RAM.
|
|
100
|
+
|
|
101
|
+
## Quick start
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd your-project
|
|
105
|
+
codesage init # detect languages, write .codesage/config.yaml
|
|
106
|
+
codesage index # parse files, build vector + graph index
|
|
107
|
+
codesage chat # ask questions about your code
|
|
108
|
+
codesage review # review uncommitted changes
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Commands
|
|
112
|
+
|
|
113
|
+
### `codesage init`
|
|
114
|
+
|
|
115
|
+
Detects languages in the project and creates `.codesage/config.yaml`. Safe to re-run — it won't overwrite an existing config.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
codesage init
|
|
119
|
+
codesage init --model llama3.1 # use a different LLM
|
|
120
|
+
codesage init --embedding-model qwen3-embedding
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `codesage index`
|
|
124
|
+
|
|
125
|
+
Parses source files, generates embeddings, and builds the call graph. Only processes changed files by default.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
codesage index # incremental (changed files only)
|
|
129
|
+
codesage index --full # reindex everything from scratch
|
|
130
|
+
codesage index --clear # wipe the index first, then reindex
|
|
131
|
+
codesage index --no-learn # skip pattern learning
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Index data lives in `.codesage/` — SQLite for metadata, LanceDB for vectors, KuzuDB for the call graph.
|
|
135
|
+
|
|
136
|
+
### `codesage chat`
|
|
137
|
+
|
|
138
|
+
Interactive session. Ask anything in plain English, or use slash commands:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
/search <query> semantic code search with RRF fusion
|
|
142
|
+
/deep <query> multi-strategy deep analysis
|
|
143
|
+
/plan <task> generate an implementation plan
|
|
144
|
+
/similar <name> find similar functions/classes
|
|
145
|
+
/patterns [query] show learned patterns from this codebase
|
|
146
|
+
/review [file] review code changes with LLM
|
|
147
|
+
/security [path] security vulnerability scan
|
|
148
|
+
/impact <name> blast radius: who calls this, what breaks
|
|
149
|
+
/mode <mode> switch to brainstorm / implement / review
|
|
150
|
+
/context show or adjust context window settings
|
|
151
|
+
/stats index statistics
|
|
152
|
+
/export [file] save conversation to file
|
|
153
|
+
/clear clear chat history
|
|
154
|
+
/help show all commands
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Natural language questions work too — you don't have to use slash commands.
|
|
158
|
+
|
|
159
|
+
### `codesage review`
|
|
160
|
+
|
|
161
|
+
Reviews uncommitted changes. Combines static analysis, pattern deviation detection, and (in full mode) semantic similarity search.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
codesage review # all uncommitted changes, fast mode
|
|
165
|
+
codesage review --staged # staged changes only (good for pre-commit)
|
|
166
|
+
codesage review --mode full # add semantic similarity + LLM synthesis
|
|
167
|
+
codesage review --severity warning # block on warnings, not just high+critical
|
|
168
|
+
codesage review --format json # JSON output for CI pipelines
|
|
169
|
+
codesage review --format sarif # SARIF for GitHub Advanced Security
|
|
170
|
+
codesage review --verbose # show timing and suppression details
|
|
171
|
+
codesage review path/to/subdir # limit to a subdirectory
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**What it checks:**
|
|
175
|
+
|
|
176
|
+
| Category | Rules |
|
|
177
|
+
|----------|-------|
|
|
178
|
+
| Python static | Long functions, high complexity, deep nesting, too many params, god classes, missing return types, magic numbers |
|
|
179
|
+
| Rust/Go/JS/TS static | Cyclomatic complexity, long functions, deep nesting, param count, naming conventions (requires `multi-language`) |
|
|
180
|
+
| Security | Hardcoded secrets, SQL injection, eval/exec, unsafe deserialization, weak crypto, XSS sinks |
|
|
181
|
+
| Patterns | Deviations from your codebase's own learned patterns |
|
|
182
|
+
|
|
183
|
+
Suppress a finding inline: `# codesage:ignore GEN-LONG-LINE` or `# codesage:ignore-next-line`.
|
|
184
|
+
Suppress a file: add it to `.codesageignore`.
|
|
185
|
+
|
|
186
|
+
### `codesage hook`
|
|
187
|
+
|
|
188
|
+
Installs a git pre-commit hook that runs `codesage review --staged` before each commit.
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
codesage hook install # install the hook
|
|
192
|
+
codesage hook uninstall # remove it
|
|
193
|
+
codesage hook status # check if installed
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The hook blocks commits with findings at `high` severity or above. Bypass when needed: `git commit --no-verify`.
|
|
197
|
+
|
|
198
|
+
If you use the [pre-commit](https://pre-commit.com) framework instead, this repo includes a `.pre-commit-hooks.yaml`:
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
repos:
|
|
202
|
+
- repo: https://github.com/keshavashiya/codesage
|
|
203
|
+
rev: v0.3.1
|
|
204
|
+
hooks:
|
|
205
|
+
- id: codesage-review
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### `codesage mcp`
|
|
209
|
+
|
|
210
|
+
MCP server for AI IDE integration. Always runs in global mode — all projects you've indexed with `codesage index` are available through a single server.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
codesage mcp serve # stdio (default, for IDE use)
|
|
214
|
+
codesage mcp serve -t sse -p 8080 # HTTP/SSE for multi-client setups
|
|
215
|
+
codesage mcp setup # print IDE config
|
|
216
|
+
codesage mcp test # smoke-test all tools
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## MCP Setup
|
|
220
|
+
|
|
221
|
+
Run `codesage mcp setup` to get the config, or add this to your IDE:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"mcpServers": {
|
|
226
|
+
"codesage": {
|
|
227
|
+
"command": "codesage",
|
|
228
|
+
"args": ["mcp", "serve"]
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
<details>
|
|
235
|
+
<summary>Available MCP tools (12)</summary>
|
|
236
|
+
|
|
237
|
+
| Tool | What it does |
|
|
238
|
+
|------|-------------|
|
|
239
|
+
| `list_projects` | List all indexed projects (global mode only) |
|
|
240
|
+
| `get_developer_profile` | Your coding style and learned patterns |
|
|
241
|
+
| `search_code` | Semantic search with confidence scoring |
|
|
242
|
+
| `get_file_context` | File content with definitions and security notes |
|
|
243
|
+
| `get_stats` | Index stats: files, elements, languages |
|
|
244
|
+
| `review_code` | Run a code review on a file or diff |
|
|
245
|
+
| `analyze_security` | Security vulnerability scan |
|
|
246
|
+
| `explain_concept` | How is X implemented in this codebase? |
|
|
247
|
+
| `suggest_approach` | Implementation guidance for a task |
|
|
248
|
+
| `trace_flow` | Callers and callees through the call graph |
|
|
249
|
+
| `find_examples` | Usage examples for a function or pattern |
|
|
250
|
+
| `recommend_pattern` | Patterns from your codebase's memory |
|
|
251
|
+
|
|
252
|
+
</details>
|
|
253
|
+
|
|
254
|
+
## Configuration
|
|
255
|
+
|
|
256
|
+
Created by `codesage init` at `.codesage/config.yaml`. The most useful fields:
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
project_name: my-project
|
|
260
|
+
languages:
|
|
261
|
+
- python # auto-detected
|
|
262
|
+
|
|
263
|
+
llm:
|
|
264
|
+
provider: ollama
|
|
265
|
+
model: qwen2.5-coder:7b
|
|
266
|
+
embedding_model: nomic-embed-text
|
|
267
|
+
base_url: http://localhost:11434
|
|
268
|
+
|
|
269
|
+
exclude_dirs:
|
|
270
|
+
- node_modules
|
|
271
|
+
- venv
|
|
272
|
+
- .git
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
<details>
|
|
276
|
+
<summary>Full configuration reference</summary>
|
|
277
|
+
|
|
278
|
+
```yaml
|
|
279
|
+
llm:
|
|
280
|
+
provider: ollama # ollama | openai | anthropic
|
|
281
|
+
model: qwen2.5-coder:7b
|
|
282
|
+
embedding_model: nomic-embed-text
|
|
283
|
+
base_url: http://localhost:11434
|
|
284
|
+
temperature: 0.3
|
|
285
|
+
max_tokens: 500
|
|
286
|
+
request_timeout: 30.0
|
|
287
|
+
|
|
288
|
+
storage:
|
|
289
|
+
vector_backend: lancedb
|
|
290
|
+
use_graph: true # enable call graph (KuzuDB)
|
|
291
|
+
|
|
292
|
+
security:
|
|
293
|
+
enabled: true
|
|
294
|
+
severity_threshold: medium
|
|
295
|
+
block_on_critical: true
|
|
296
|
+
|
|
297
|
+
memory:
|
|
298
|
+
enabled: true
|
|
299
|
+
learn_on_index: true # learn patterns during indexing
|
|
300
|
+
min_pattern_confidence: 0.5
|
|
301
|
+
|
|
302
|
+
performance:
|
|
303
|
+
embedding_batch_size: 200
|
|
304
|
+
embedding_cache_size: 1000
|
|
305
|
+
cache_enabled: true
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
</details>
|
|
309
|
+
|
|
310
|
+
## Language support
|
|
311
|
+
|
|
312
|
+
| Language | Indexing | Static review | Call graph |
|
|
313
|
+
|----------|----------|---------------|------------|
|
|
314
|
+
| Python | built-in | ✓ | ✓ |
|
|
315
|
+
| Rust | `multi-language` | ✓ AST-based | ✓ |
|
|
316
|
+
| Go | `multi-language` | ✓ AST-based | ✓ |
|
|
317
|
+
| TypeScript | `multi-language` | ✓ AST-based | ✓ |
|
|
318
|
+
| JavaScript | `multi-language` | ✓ AST-based | ✓ |
|
|
319
|
+
|
|
320
|
+
Install `pycodesage[multi-language]` for Rust/Go/JS/TS. Without it, those files are still indexed and reviewed using text/regex heuristics.
|
|
321
|
+
|
|
322
|
+
## Using OpenAI or Anthropic instead of Ollama
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
pipx inject pycodesage "pycodesage[openai]"
|
|
326
|
+
# or
|
|
327
|
+
pipx inject pycodesage "pycodesage[anthropic]"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Then set in `.codesage/config.yaml`:
|
|
331
|
+
|
|
332
|
+
```yaml
|
|
333
|
+
llm:
|
|
334
|
+
provider: openai
|
|
335
|
+
model: gpt-4o
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Development
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
git clone https://github.com/keshavashiya/codesage.git
|
|
342
|
+
cd codesage
|
|
343
|
+
python3 -m venv venv && source venv/bin/activate
|
|
344
|
+
pip install -e ".[dev,multi-language,mcp]"
|
|
345
|
+
pytest tests/ -v
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## License
|
|
349
|
+
|
|
350
|
+
MIT
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# CodeSage
|
|
2
|
+
|
|
3
|
+
Local-first code intelligence CLI. Search, analyze, and chat with your codebase using natural language — all running on your machine via Ollama.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# macOS
|
|
9
|
+
brew install pipx && pipx ensurepath
|
|
10
|
+
|
|
11
|
+
# Linux
|
|
12
|
+
python3 -m pip install --user pipx && python3 -m pipx ensurepath
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pipx install pycodesage
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Optional features
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Tree-sitter AST analysis for JS, TS, Go, Rust (recommended)
|
|
23
|
+
pipx inject pycodesage "pycodesage[multi-language]"
|
|
24
|
+
|
|
25
|
+
# MCP server for Claude Desktop / Cursor / Windsurf
|
|
26
|
+
pipx inject pycodesage "pycodesage[mcp]"
|
|
27
|
+
|
|
28
|
+
# Both at once
|
|
29
|
+
pipx inject pycodesage "pycodesage[multi-language,mcp]"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Without `multi-language`, review checks for non-Python files still run but use text/regex heuristics instead of real AST parsing.
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
Ollama must be running:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ollama pull qwen2.5-coder:7b # LLM
|
|
40
|
+
ollama pull nomic-embed-text # embeddings (fast, lightweight)
|
|
41
|
+
ollama serve
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Alternatively**, use any Ollama-compatible model. `qwen3-embedding` gives significantly better semantic search if you have the RAM.
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cd your-project
|
|
50
|
+
codesage init # detect languages, write .codesage/config.yaml
|
|
51
|
+
codesage index # parse files, build vector + graph index
|
|
52
|
+
codesage chat # ask questions about your code
|
|
53
|
+
codesage review # review uncommitted changes
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
### `codesage init`
|
|
59
|
+
|
|
60
|
+
Detects languages in the project and creates `.codesage/config.yaml`. Safe to re-run — it won't overwrite an existing config.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
codesage init
|
|
64
|
+
codesage init --model llama3.1 # use a different LLM
|
|
65
|
+
codesage init --embedding-model qwen3-embedding
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `codesage index`
|
|
69
|
+
|
|
70
|
+
Parses source files, generates embeddings, and builds the call graph. Only processes changed files by default.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
codesage index # incremental (changed files only)
|
|
74
|
+
codesage index --full # reindex everything from scratch
|
|
75
|
+
codesage index --clear # wipe the index first, then reindex
|
|
76
|
+
codesage index --no-learn # skip pattern learning
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Index data lives in `.codesage/` — SQLite for metadata, LanceDB for vectors, KuzuDB for the call graph.
|
|
80
|
+
|
|
81
|
+
### `codesage chat`
|
|
82
|
+
|
|
83
|
+
Interactive session. Ask anything in plain English, or use slash commands:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
/search <query> semantic code search with RRF fusion
|
|
87
|
+
/deep <query> multi-strategy deep analysis
|
|
88
|
+
/plan <task> generate an implementation plan
|
|
89
|
+
/similar <name> find similar functions/classes
|
|
90
|
+
/patterns [query] show learned patterns from this codebase
|
|
91
|
+
/review [file] review code changes with LLM
|
|
92
|
+
/security [path] security vulnerability scan
|
|
93
|
+
/impact <name> blast radius: who calls this, what breaks
|
|
94
|
+
/mode <mode> switch to brainstorm / implement / review
|
|
95
|
+
/context show or adjust context window settings
|
|
96
|
+
/stats index statistics
|
|
97
|
+
/export [file] save conversation to file
|
|
98
|
+
/clear clear chat history
|
|
99
|
+
/help show all commands
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Natural language questions work too — you don't have to use slash commands.
|
|
103
|
+
|
|
104
|
+
### `codesage review`
|
|
105
|
+
|
|
106
|
+
Reviews uncommitted changes. Combines static analysis, pattern deviation detection, and (in full mode) semantic similarity search.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
codesage review # all uncommitted changes, fast mode
|
|
110
|
+
codesage review --staged # staged changes only (good for pre-commit)
|
|
111
|
+
codesage review --mode full # add semantic similarity + LLM synthesis
|
|
112
|
+
codesage review --severity warning # block on warnings, not just high+critical
|
|
113
|
+
codesage review --format json # JSON output for CI pipelines
|
|
114
|
+
codesage review --format sarif # SARIF for GitHub Advanced Security
|
|
115
|
+
codesage review --verbose # show timing and suppression details
|
|
116
|
+
codesage review path/to/subdir # limit to a subdirectory
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**What it checks:**
|
|
120
|
+
|
|
121
|
+
| Category | Rules |
|
|
122
|
+
|----------|-------|
|
|
123
|
+
| Python static | Long functions, high complexity, deep nesting, too many params, god classes, missing return types, magic numbers |
|
|
124
|
+
| Rust/Go/JS/TS static | Cyclomatic complexity, long functions, deep nesting, param count, naming conventions (requires `multi-language`) |
|
|
125
|
+
| Security | Hardcoded secrets, SQL injection, eval/exec, unsafe deserialization, weak crypto, XSS sinks |
|
|
126
|
+
| Patterns | Deviations from your codebase's own learned patterns |
|
|
127
|
+
|
|
128
|
+
Suppress a finding inline: `# codesage:ignore GEN-LONG-LINE` or `# codesage:ignore-next-line`.
|
|
129
|
+
Suppress a file: add it to `.codesageignore`.
|
|
130
|
+
|
|
131
|
+
### `codesage hook`
|
|
132
|
+
|
|
133
|
+
Installs a git pre-commit hook that runs `codesage review --staged` before each commit.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
codesage hook install # install the hook
|
|
137
|
+
codesage hook uninstall # remove it
|
|
138
|
+
codesage hook status # check if installed
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The hook blocks commits with findings at `high` severity or above. Bypass when needed: `git commit --no-verify`.
|
|
142
|
+
|
|
143
|
+
If you use the [pre-commit](https://pre-commit.com) framework instead, this repo includes a `.pre-commit-hooks.yaml`:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
repos:
|
|
147
|
+
- repo: https://github.com/keshavashiya/codesage
|
|
148
|
+
rev: v0.3.1
|
|
149
|
+
hooks:
|
|
150
|
+
- id: codesage-review
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `codesage mcp`
|
|
154
|
+
|
|
155
|
+
MCP server for AI IDE integration. Always runs in global mode — all projects you've indexed with `codesage index` are available through a single server.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
codesage mcp serve # stdio (default, for IDE use)
|
|
159
|
+
codesage mcp serve -t sse -p 8080 # HTTP/SSE for multi-client setups
|
|
160
|
+
codesage mcp setup # print IDE config
|
|
161
|
+
codesage mcp test # smoke-test all tools
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## MCP Setup
|
|
165
|
+
|
|
166
|
+
Run `codesage mcp setup` to get the config, or add this to your IDE:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"mcpServers": {
|
|
171
|
+
"codesage": {
|
|
172
|
+
"command": "codesage",
|
|
173
|
+
"args": ["mcp", "serve"]
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
<details>
|
|
180
|
+
<summary>Available MCP tools (12)</summary>
|
|
181
|
+
|
|
182
|
+
| Tool | What it does |
|
|
183
|
+
|------|-------------|
|
|
184
|
+
| `list_projects` | List all indexed projects (global mode only) |
|
|
185
|
+
| `get_developer_profile` | Your coding style and learned patterns |
|
|
186
|
+
| `search_code` | Semantic search with confidence scoring |
|
|
187
|
+
| `get_file_context` | File content with definitions and security notes |
|
|
188
|
+
| `get_stats` | Index stats: files, elements, languages |
|
|
189
|
+
| `review_code` | Run a code review on a file or diff |
|
|
190
|
+
| `analyze_security` | Security vulnerability scan |
|
|
191
|
+
| `explain_concept` | How is X implemented in this codebase? |
|
|
192
|
+
| `suggest_approach` | Implementation guidance for a task |
|
|
193
|
+
| `trace_flow` | Callers and callees through the call graph |
|
|
194
|
+
| `find_examples` | Usage examples for a function or pattern |
|
|
195
|
+
| `recommend_pattern` | Patterns from your codebase's memory |
|
|
196
|
+
|
|
197
|
+
</details>
|
|
198
|
+
|
|
199
|
+
## Configuration
|
|
200
|
+
|
|
201
|
+
Created by `codesage init` at `.codesage/config.yaml`. The most useful fields:
|
|
202
|
+
|
|
203
|
+
```yaml
|
|
204
|
+
project_name: my-project
|
|
205
|
+
languages:
|
|
206
|
+
- python # auto-detected
|
|
207
|
+
|
|
208
|
+
llm:
|
|
209
|
+
provider: ollama
|
|
210
|
+
model: qwen2.5-coder:7b
|
|
211
|
+
embedding_model: nomic-embed-text
|
|
212
|
+
base_url: http://localhost:11434
|
|
213
|
+
|
|
214
|
+
exclude_dirs:
|
|
215
|
+
- node_modules
|
|
216
|
+
- venv
|
|
217
|
+
- .git
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary>Full configuration reference</summary>
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
llm:
|
|
225
|
+
provider: ollama # ollama | openai | anthropic
|
|
226
|
+
model: qwen2.5-coder:7b
|
|
227
|
+
embedding_model: nomic-embed-text
|
|
228
|
+
base_url: http://localhost:11434
|
|
229
|
+
temperature: 0.3
|
|
230
|
+
max_tokens: 500
|
|
231
|
+
request_timeout: 30.0
|
|
232
|
+
|
|
233
|
+
storage:
|
|
234
|
+
vector_backend: lancedb
|
|
235
|
+
use_graph: true # enable call graph (KuzuDB)
|
|
236
|
+
|
|
237
|
+
security:
|
|
238
|
+
enabled: true
|
|
239
|
+
severity_threshold: medium
|
|
240
|
+
block_on_critical: true
|
|
241
|
+
|
|
242
|
+
memory:
|
|
243
|
+
enabled: true
|
|
244
|
+
learn_on_index: true # learn patterns during indexing
|
|
245
|
+
min_pattern_confidence: 0.5
|
|
246
|
+
|
|
247
|
+
performance:
|
|
248
|
+
embedding_batch_size: 200
|
|
249
|
+
embedding_cache_size: 1000
|
|
250
|
+
cache_enabled: true
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
</details>
|
|
254
|
+
|
|
255
|
+
## Language support
|
|
256
|
+
|
|
257
|
+
| Language | Indexing | Static review | Call graph |
|
|
258
|
+
|----------|----------|---------------|------------|
|
|
259
|
+
| Python | built-in | ✓ | ✓ |
|
|
260
|
+
| Rust | `multi-language` | ✓ AST-based | ✓ |
|
|
261
|
+
| Go | `multi-language` | ✓ AST-based | ✓ |
|
|
262
|
+
| TypeScript | `multi-language` | ✓ AST-based | ✓ |
|
|
263
|
+
| JavaScript | `multi-language` | ✓ AST-based | ✓ |
|
|
264
|
+
|
|
265
|
+
Install `pycodesage[multi-language]` for Rust/Go/JS/TS. Without it, those files are still indexed and reviewed using text/regex heuristics.
|
|
266
|
+
|
|
267
|
+
## Using OpenAI or Anthropic instead of Ollama
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
pipx inject pycodesage "pycodesage[openai]"
|
|
271
|
+
# or
|
|
272
|
+
pipx inject pycodesage "pycodesage[anthropic]"
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Then set in `.codesage/config.yaml`:
|
|
276
|
+
|
|
277
|
+
```yaml
|
|
278
|
+
llm:
|
|
279
|
+
provider: openai
|
|
280
|
+
model: gpt-4o
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Development
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
git clone https://github.com/keshavashiya/codesage.git
|
|
287
|
+
cd codesage
|
|
288
|
+
python3 -m venv venv && source venv/bin/activate
|
|
289
|
+
pip install -e ".[dev,multi-language,mcp]"
|
|
290
|
+
pytest tests/ -v
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
MIT
|