ctxgraph-code 0.4.1__tar.gz → 0.5.1__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.
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/PKG-INFO +34 -9
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/README.md +30 -8
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/pyproject.toml +5 -1
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/treesitter/analyzer.py +10 -2
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/cli.py +50 -27
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/config/settings.py +8 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/graph/builder.py +56 -11
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code.egg-info/PKG-INFO +34 -9
- ctxgraph_code-0.5.1/src/ctxgraph_code.egg-info/requires.txt +9 -0
- ctxgraph_code-0.4.1/src/ctxgraph_code.egg-info/requires.txt +0 -5
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/setup.cfg +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/__main__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/python/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/python/importer.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/python/semantic.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/python/symbols.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/treesitter/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/treesitter/languages.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/config/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/config/build_status.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/config/global_paths.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/config/hooks.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/config/init.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/exclude/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/exclude/patterns.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/graph/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/graph/models.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/graph/query.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/graph/storage.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/render.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/view/__init__.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/view/visualizer.py +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code.egg-info/SOURCES.txt +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code.egg-info/dependency_links.txt +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code.egg-info/entry_points.txt +0 -0
- {ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ctxgraph-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Code knowledge graph for Claude Code. Build a relationship graph of your Python codebase and query it during coding sessions.
|
|
5
5
|
Author: ctxgraph-code contributors
|
|
6
6
|
License: MIT
|
|
@@ -18,6 +18,9 @@ Requires-Python: >=3.10
|
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
Requires-Dist: typer>=0.9
|
|
20
20
|
Requires-Dist: rich>=13.0
|
|
21
|
+
Provides-Extra: full
|
|
22
|
+
Requires-Dist: tree-sitter>=0.22; extra == "full"
|
|
23
|
+
Requires-Dist: tree-sitter-language-pack>=0.13; extra == "full"
|
|
21
24
|
Provides-Extra: dev
|
|
22
25
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
23
26
|
|
|
@@ -27,6 +30,8 @@ Requires-Dist: pytest>=7.0; extra == "dev"
|
|
|
27
30
|
|
|
28
31
|
```bash
|
|
29
32
|
pip install ctxgraph-code
|
|
33
|
+
# For multi-language support (C, Go, Rust, JS, TS, Java, etc.):
|
|
34
|
+
pip install 'ctxgraph-code[full]'
|
|
30
35
|
cd my-project
|
|
31
36
|
ctxgraph-code setup
|
|
32
37
|
```
|
|
@@ -49,10 +54,10 @@ These questions require running multiple `grep` commands or reading dependency c
|
|
|
49
54
|
## Quick Start
|
|
50
55
|
|
|
51
56
|
```bash
|
|
52
|
-
# Install
|
|
53
|
-
pip install ctxgraph-code
|
|
57
|
+
# Install (add [full] for multi-language support)
|
|
58
|
+
pip install 'ctxgraph-code[full]'
|
|
54
59
|
|
|
55
|
-
# Navigate to your
|
|
60
|
+
# Navigate to your project
|
|
56
61
|
cd my-project
|
|
57
62
|
|
|
58
63
|
# One-command setup: init + build + configure Claude Code
|
|
@@ -77,7 +82,14 @@ Interactive walkthrough — prompts for:
|
|
|
77
82
|
Does everything in one step:
|
|
78
83
|
1. Creates `.ctxgraph/config.toml` with your chosen extensions and excludes
|
|
79
84
|
2. Installs the `/ctxgraph-code` slash command globally (works in every Claude Code session)
|
|
80
|
-
3. Builds the knowledge graph from all matching files
|
|
85
|
+
3. Builds the knowledge graph from all matching files — shows live per-graph progress:
|
|
86
|
+
```
|
|
87
|
+
Building 5 graphs with 8 workers...
|
|
88
|
+
✔ src/ (42 files, 156 nodes, 34 edges, 0.8s)
|
|
89
|
+
✔ api/ (18 files, 73 nodes, 12 edges, 0.4s)
|
|
90
|
+
✔ tests/ (31 files, 89 nodes, 0 edges, 0.6s)
|
|
91
|
+
Built all 5 graphs in 2.1s
|
|
92
|
+
```
|
|
81
93
|
|
|
82
94
|
Non-interactive mode:
|
|
83
95
|
```bash
|
|
@@ -119,6 +131,15 @@ Scans all matching files in the project, runs AST analysis. Extensions are read
|
|
|
119
131
|
- `--verbose` / `-v` — show per-file progress
|
|
120
132
|
- `--no-summary` — skip docstring extraction for faster builds
|
|
121
133
|
|
|
134
|
+
Shows live per-graph progress as each completes:
|
|
135
|
+
```
|
|
136
|
+
Building 5 graphs with 8 workers...
|
|
137
|
+
✔ src/ (42 files, 156 nodes, 34 edges, 0.8s)
|
|
138
|
+
✔ api/ (18 files, 73 nodes, 12 edges, 0.4s)
|
|
139
|
+
✔ tests/ (31 files, 89 nodes, 0 edges, 0.6s)
|
|
140
|
+
Built all 5 graphs in 2.1s
|
|
141
|
+
```
|
|
142
|
+
|
|
122
143
|
Stores graphs in `.ctxgraph/graphs/<dir>.db` (per-directory) or `.ctxgraph/graph.db` (combined).
|
|
123
144
|
|
|
124
145
|
> The graph is a **static snapshot**. If code changes, run `ctxgraph-code build` again to refresh. Use `--incremental` to only reprocess changed files.
|
|
@@ -222,10 +243,10 @@ ctxgraph-code probe "database connection pool"
|
|
|
222
243
|
ctxgraph-code probe "user authentication" --max 3
|
|
223
244
|
```
|
|
224
245
|
|
|
225
|
-
Searches the graph for relevant nodes **and reads the actual source code** inline. Claude gets paths + source in one command, saving 1–2 tool calls. Shows the first
|
|
246
|
+
Searches the graph for relevant nodes **and reads the actual source code** inline. Claude gets paths + source in one command, saving 1–2 tool calls. Shows the first N lines of matched files with automatic syntax highlighting per language.
|
|
226
247
|
|
|
227
248
|
- `--max` / `-m` — max files to probe (default: 5)
|
|
228
|
-
- `--context` / `-c` — lines
|
|
249
|
+
- `--context` / `-c` — lines to show per file (default: 40, use 0 for full file)
|
|
229
250
|
|
|
230
251
|
### `install-hooks`
|
|
231
252
|
|
|
@@ -314,7 +335,10 @@ This catches the common case where you edit a file after building the graph and
|
|
|
314
335
|
| **Multiprocessing** | Combined graphs split files across CPU cores via `multiprocessing.Pool` |
|
|
315
336
|
| **`--jobs`** | Control parallelism level (default: CPU count) |
|
|
316
337
|
| **Incremental builds** | `--incremental` caches file mtimes, only reprocesses changed files |
|
|
317
|
-
| **Trivial file skip** | `_quick_scan()` pre-checks
|
|
338
|
+
| **Trivial file skip** | `_quick_scan()` pre-checks all files (Python and non-Python) — skips full parse for files with no code |
|
|
339
|
+
| **`follow_symlinks` config** | Respects `follow_symlinks = false` setting to avoid duplicate/broken symlinks |
|
|
340
|
+
| **`max_file_size_mb` config** | Skips files exceeding the configured size limit before reading |
|
|
341
|
+
| **Live build progress** | Per-graph status + timing as each completes during parallel builds |
|
|
318
342
|
| **Cached excludes** | `lru_cache` on `should_exclude()` during `os.walk` |
|
|
319
343
|
| **Batch SQLite inserts** | `executemany` instead of per-row `INSERT` statements |
|
|
320
344
|
| **`--no-summary`** | Skips docstring extraction (fastest rebuilds) |
|
|
@@ -386,7 +410,7 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
|
|
|
386
410
|
|
|
387
411
|
| Feature | ctxgraph | ctxgraph-code |
|
|
388
412
|
|---------|----------|---------------|
|
|
389
|
-
| CLI commands | 9+ |
|
|
413
|
+
| CLI commands | 9+ | 17 (init, build, query, deps, usedby, overview, symbols, context, setup, view, info, install-slash, build-status, probe, install-hooks, uninstall-hooks, version) |
|
|
390
414
|
| LLM integration | Built-in (Ollama, Claude, OpenAI, Azure) | None (delegates to Claude Code) |
|
|
391
415
|
| Chat sessions | Yes | No |
|
|
392
416
|
| Visualizer | D3.js HTML + SVG | D3.js HTML (`view` opens in browser, `--tree` for text) |
|
|
@@ -401,6 +425,7 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
|
|
|
401
425
|
|
|
402
426
|
- Python 3.10+
|
|
403
427
|
- A Claude Code subscription (for the `/ctxgraph-code` slash command — the graph itself works standalone)
|
|
428
|
+
- For multi-language analysis (C, Go, Rust, JS, TS, Java, etc.): `pip install 'ctxgraph-code[full]'` to install tree-sitter support
|
|
404
429
|
|
|
405
430
|
---
|
|
406
431
|
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
pip install ctxgraph-code
|
|
7
|
+
# For multi-language support (C, Go, Rust, JS, TS, Java, etc.):
|
|
8
|
+
pip install 'ctxgraph-code[full]'
|
|
7
9
|
cd my-project
|
|
8
10
|
ctxgraph-code setup
|
|
9
11
|
```
|
|
@@ -26,10 +28,10 @@ These questions require running multiple `grep` commands or reading dependency c
|
|
|
26
28
|
## Quick Start
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
|
-
# Install
|
|
30
|
-
pip install ctxgraph-code
|
|
31
|
+
# Install (add [full] for multi-language support)
|
|
32
|
+
pip install 'ctxgraph-code[full]'
|
|
31
33
|
|
|
32
|
-
# Navigate to your
|
|
34
|
+
# Navigate to your project
|
|
33
35
|
cd my-project
|
|
34
36
|
|
|
35
37
|
# One-command setup: init + build + configure Claude Code
|
|
@@ -54,7 +56,14 @@ Interactive walkthrough — prompts for:
|
|
|
54
56
|
Does everything in one step:
|
|
55
57
|
1. Creates `.ctxgraph/config.toml` with your chosen extensions and excludes
|
|
56
58
|
2. Installs the `/ctxgraph-code` slash command globally (works in every Claude Code session)
|
|
57
|
-
3. Builds the knowledge graph from all matching files
|
|
59
|
+
3. Builds the knowledge graph from all matching files — shows live per-graph progress:
|
|
60
|
+
```
|
|
61
|
+
Building 5 graphs with 8 workers...
|
|
62
|
+
✔ src/ (42 files, 156 nodes, 34 edges, 0.8s)
|
|
63
|
+
✔ api/ (18 files, 73 nodes, 12 edges, 0.4s)
|
|
64
|
+
✔ tests/ (31 files, 89 nodes, 0 edges, 0.6s)
|
|
65
|
+
Built all 5 graphs in 2.1s
|
|
66
|
+
```
|
|
58
67
|
|
|
59
68
|
Non-interactive mode:
|
|
60
69
|
```bash
|
|
@@ -96,6 +105,15 @@ Scans all matching files in the project, runs AST analysis. Extensions are read
|
|
|
96
105
|
- `--verbose` / `-v` — show per-file progress
|
|
97
106
|
- `--no-summary` — skip docstring extraction for faster builds
|
|
98
107
|
|
|
108
|
+
Shows live per-graph progress as each completes:
|
|
109
|
+
```
|
|
110
|
+
Building 5 graphs with 8 workers...
|
|
111
|
+
✔ src/ (42 files, 156 nodes, 34 edges, 0.8s)
|
|
112
|
+
✔ api/ (18 files, 73 nodes, 12 edges, 0.4s)
|
|
113
|
+
✔ tests/ (31 files, 89 nodes, 0 edges, 0.6s)
|
|
114
|
+
Built all 5 graphs in 2.1s
|
|
115
|
+
```
|
|
116
|
+
|
|
99
117
|
Stores graphs in `.ctxgraph/graphs/<dir>.db` (per-directory) or `.ctxgraph/graph.db` (combined).
|
|
100
118
|
|
|
101
119
|
> The graph is a **static snapshot**. If code changes, run `ctxgraph-code build` again to refresh. Use `--incremental` to only reprocess changed files.
|
|
@@ -199,10 +217,10 @@ ctxgraph-code probe "database connection pool"
|
|
|
199
217
|
ctxgraph-code probe "user authentication" --max 3
|
|
200
218
|
```
|
|
201
219
|
|
|
202
|
-
Searches the graph for relevant nodes **and reads the actual source code** inline. Claude gets paths + source in one command, saving 1–2 tool calls. Shows the first
|
|
220
|
+
Searches the graph for relevant nodes **and reads the actual source code** inline. Claude gets paths + source in one command, saving 1–2 tool calls. Shows the first N lines of matched files with automatic syntax highlighting per language.
|
|
203
221
|
|
|
204
222
|
- `--max` / `-m` — max files to probe (default: 5)
|
|
205
|
-
- `--context` / `-c` — lines
|
|
223
|
+
- `--context` / `-c` — lines to show per file (default: 40, use 0 for full file)
|
|
206
224
|
|
|
207
225
|
### `install-hooks`
|
|
208
226
|
|
|
@@ -291,7 +309,10 @@ This catches the common case where you edit a file after building the graph and
|
|
|
291
309
|
| **Multiprocessing** | Combined graphs split files across CPU cores via `multiprocessing.Pool` |
|
|
292
310
|
| **`--jobs`** | Control parallelism level (default: CPU count) |
|
|
293
311
|
| **Incremental builds** | `--incremental` caches file mtimes, only reprocesses changed files |
|
|
294
|
-
| **Trivial file skip** | `_quick_scan()` pre-checks
|
|
312
|
+
| **Trivial file skip** | `_quick_scan()` pre-checks all files (Python and non-Python) — skips full parse for files with no code |
|
|
313
|
+
| **`follow_symlinks` config** | Respects `follow_symlinks = false` setting to avoid duplicate/broken symlinks |
|
|
314
|
+
| **`max_file_size_mb` config** | Skips files exceeding the configured size limit before reading |
|
|
315
|
+
| **Live build progress** | Per-graph status + timing as each completes during parallel builds |
|
|
295
316
|
| **Cached excludes** | `lru_cache` on `should_exclude()` during `os.walk` |
|
|
296
317
|
| **Batch SQLite inserts** | `executemany` instead of per-row `INSERT` statements |
|
|
297
318
|
| **`--no-summary`** | Skips docstring extraction (fastest rebuilds) |
|
|
@@ -363,7 +384,7 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
|
|
|
363
384
|
|
|
364
385
|
| Feature | ctxgraph | ctxgraph-code |
|
|
365
386
|
|---------|----------|---------------|
|
|
366
|
-
| CLI commands | 9+ |
|
|
387
|
+
| CLI commands | 9+ | 17 (init, build, query, deps, usedby, overview, symbols, context, setup, view, info, install-slash, build-status, probe, install-hooks, uninstall-hooks, version) |
|
|
367
388
|
| LLM integration | Built-in (Ollama, Claude, OpenAI, Azure) | None (delegates to Claude Code) |
|
|
368
389
|
| Chat sessions | Yes | No |
|
|
369
390
|
| Visualizer | D3.js HTML + SVG | D3.js HTML (`view` opens in browser, `--tree` for text) |
|
|
@@ -378,6 +399,7 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
|
|
|
378
399
|
|
|
379
400
|
- Python 3.10+
|
|
380
401
|
- A Claude Code subscription (for the `/ctxgraph-code` slash command — the graph itself works standalone)
|
|
402
|
+
- For multi-language analysis (C, Go, Rust, JS, TS, Java, etc.): `pip install 'ctxgraph-code[full]'` to install tree-sitter support
|
|
381
403
|
|
|
382
404
|
---
|
|
383
405
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ctxgraph-code"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.1"
|
|
8
8
|
description = "Code knowledge graph for Claude Code. Build a relationship graph of your Python codebase and query it during coding sessions."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -30,6 +30,10 @@ dependencies = [
|
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[project.optional-dependencies]
|
|
33
|
+
full = [
|
|
34
|
+
"tree-sitter>=0.22",
|
|
35
|
+
"tree-sitter-language-pack>=0.13",
|
|
36
|
+
]
|
|
33
37
|
dev = [
|
|
34
38
|
"pytest>=7.0",
|
|
35
39
|
]
|
{ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/treesitter/analyzer.py
RENAMED
|
@@ -38,8 +38,16 @@ class TSAnalyzer:
|
|
|
38
38
|
if not self.can_handle():
|
|
39
39
|
return TSAnalyzerResult()
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
try:
|
|
42
|
+
import tree_sitter as ts
|
|
43
|
+
from tree_sitter_language_pack import get_language
|
|
44
|
+
except ImportError:
|
|
45
|
+
import warnings
|
|
46
|
+
warnings.warn(
|
|
47
|
+
f"Missing tree-sitter dependency for {self.lang_name} files. "
|
|
48
|
+
"Install with: pip install 'ctxgraph-code[full]'"
|
|
49
|
+
)
|
|
50
|
+
raise
|
|
43
51
|
|
|
44
52
|
lang = self._get_lang(self.lang_name)
|
|
45
53
|
if not lang:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import time
|
|
@@ -245,12 +245,8 @@ def _write_slash_command(slash_path: Path, path: Path):
|
|
|
245
245
|
content = SLASH_COMMAND_TEMPLATE.format(build_time=build_label, available=avail_str)
|
|
246
246
|
|
|
247
247
|
slash_path.parent.mkdir(parents=True, exist_ok=True)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
console.print(f"[green][OK] Created [bold]{slash_path}[/bold][/green]")
|
|
251
|
-
else:
|
|
252
|
-
console.print(f"[yellow] Skipped (already exists): [bold]{slash_path}[/bold][/yellow]")
|
|
253
|
-
console.print("[yellow] To overwrite, delete it and run again.[/yellow]")
|
|
248
|
+
slash_path.write_text(content, encoding="utf-8")
|
|
249
|
+
console.print(f"[green][OK] {'Updated' if slash_path.exists() else 'Created'} [bold]{slash_path}[/bold][/green]")
|
|
254
250
|
|
|
255
251
|
|
|
256
252
|
# ── slash command template ───────────────────────────────────────────────────
|
|
@@ -311,8 +307,7 @@ def _print_build_hint(path: Path):
|
|
|
311
307
|
|
|
312
308
|
def _build_single_graph(path, exts, user_patterns, db_path, label,
|
|
313
309
|
incremental=False, verbose=False, no_summary=False):
|
|
314
|
-
|
|
315
|
-
mark_build_started(ctx_dir, os.getpid())
|
|
310
|
+
mark_build_started(path, os.getpid())
|
|
316
311
|
start = time.time()
|
|
317
312
|
with console.status(f"Scanning {', '.join(exts)} files for '{label}'..."):
|
|
318
313
|
stats = build_graph(
|
|
@@ -324,7 +319,7 @@ def _build_single_graph(path, exts, user_patterns, db_path, label,
|
|
|
324
319
|
verbose=verbose,
|
|
325
320
|
no_summary=no_summary,
|
|
326
321
|
)
|
|
327
|
-
mark_build_complete(
|
|
322
|
+
mark_build_complete(path, time.time() - start)
|
|
328
323
|
|
|
329
324
|
table = Table(title=f"Graph Build: {label}")
|
|
330
325
|
table.add_column("Metric", style="cyan")
|
|
@@ -341,8 +336,7 @@ def _build_single_graph(path, exts, user_patterns, db_path, label,
|
|
|
341
336
|
def _build_dir_worker(path, exts, user_patterns, db_path, label,
|
|
342
337
|
incremental=False, verbose=False, no_summary=False):
|
|
343
338
|
"""Silent build worker for parallel execution. No console output."""
|
|
344
|
-
|
|
345
|
-
mark_build_started(ctx_dir, os.getpid())
|
|
339
|
+
mark_build_started(path, os.getpid())
|
|
346
340
|
start = time.time()
|
|
347
341
|
stats = build_graph(
|
|
348
342
|
path,
|
|
@@ -353,7 +347,7 @@ def _build_dir_worker(path, exts, user_patterns, db_path, label,
|
|
|
353
347
|
verbose=verbose,
|
|
354
348
|
no_summary=no_summary,
|
|
355
349
|
)
|
|
356
|
-
mark_build_complete(
|
|
350
|
+
mark_build_complete(path, time.time() - start)
|
|
357
351
|
return label, stats
|
|
358
352
|
|
|
359
353
|
|
|
@@ -363,9 +357,11 @@ def _build_dirs_parallel(path, exts, user_patterns, top_dirs, graphs_dir, jobs,
|
|
|
363
357
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
364
358
|
|
|
365
359
|
n_workers = max(1, jobs) if jobs > 0 else os.cpu_count() or 1
|
|
366
|
-
|
|
360
|
+
total = len(top_dirs)
|
|
361
|
+
console.print(f"[bold]Building {total} graphs with {n_workers} workers...[/bold]")
|
|
367
362
|
|
|
368
|
-
futures =
|
|
363
|
+
futures = {}
|
|
364
|
+
_build_progress_start = time.time()
|
|
369
365
|
with ThreadPoolExecutor(max_workers=n_workers) as pool:
|
|
370
366
|
for d in top_dirs:
|
|
371
367
|
db_path = graphs_dir / f"{d.name}.db"
|
|
@@ -373,15 +369,37 @@ def _build_dirs_parallel(path, exts, user_patterns, top_dirs, graphs_dir, jobs,
|
|
|
373
369
|
_build_dir_worker, path, exts, user_patterns, db_path, d.name,
|
|
374
370
|
incremental, verbose, no_summary,
|
|
375
371
|
)
|
|
376
|
-
futures.
|
|
372
|
+
futures[fut] = d.name
|
|
377
373
|
|
|
378
374
|
results = []
|
|
375
|
+
completed = 0
|
|
376
|
+
err_count = 0
|
|
377
|
+
|
|
379
378
|
for f in as_completed(futures):
|
|
379
|
+
label = futures[f]
|
|
380
|
+
completed += 1
|
|
380
381
|
try:
|
|
381
|
-
|
|
382
|
-
results.append((
|
|
382
|
+
lbl, stats = f.result()
|
|
383
|
+
results.append((lbl, stats))
|
|
384
|
+
files = stats.get("files_analyzed", 0)
|
|
385
|
+
nodes = stats.get("total_nodes", 0)
|
|
386
|
+
edges = stats.get("total_edges", 0)
|
|
387
|
+
t = stats.get("elapsed_seconds", 0)
|
|
388
|
+
console.print(
|
|
389
|
+
f" [green]✔[/green] {label}/ "
|
|
390
|
+
f"({files} files, {nodes} nodes, {edges} edges, {t}s)"
|
|
391
|
+
)
|
|
383
392
|
except Exception as e:
|
|
384
|
-
results.append((
|
|
393
|
+
results.append((label, str(e)))
|
|
394
|
+
err_count += 1
|
|
395
|
+
console.print(f" [red]✘[/red] {label}/ ([red]{e}[/red])")
|
|
396
|
+
|
|
397
|
+
elapsed_total = time.time() - _build_progress_start
|
|
398
|
+
if err_count:
|
|
399
|
+
console.print(f"\n[yellow]Built {total - err_count}/{total} graphs"
|
|
400
|
+
f" ({err_count} failed) in {elapsed_total:.1f}s[/yellow]")
|
|
401
|
+
else:
|
|
402
|
+
console.print(f"\n[green]Built all {total} graphs in {elapsed_total:.1f}s[/green]")
|
|
385
403
|
|
|
386
404
|
results.sort(key=lambda x: x[0] if isinstance(x[0], str) else "")
|
|
387
405
|
|
|
@@ -413,9 +431,8 @@ def _build_dirs_parallel(path, exts, user_patterns, top_dirs, graphs_dir, jobs,
|
|
|
413
431
|
|
|
414
432
|
console.print(summary)
|
|
415
433
|
console.print(
|
|
416
|
-
f"
|
|
417
|
-
f"
|
|
418
|
-
f"in {total_time}s[/green]"
|
|
434
|
+
f"[green]Total: {total_files} files, {total_nodes} nodes, {total_edges} edges "
|
|
435
|
+
f"in {elapsed_total:.1f}s[/green]"
|
|
419
436
|
)
|
|
420
437
|
return results
|
|
421
438
|
|
|
@@ -921,7 +938,7 @@ def probe(
|
|
|
921
938
|
5, "--max", "-m", help="Maximum files to probe"
|
|
922
939
|
),
|
|
923
940
|
context_lines: int = typer.Option(
|
|
924
|
-
|
|
941
|
+
40, "--context", "-c", help="Number of lines to show per file"
|
|
925
942
|
),
|
|
926
943
|
dir_name: Optional[str] = typer.Option(
|
|
927
944
|
None, "--dir", "-d", help="Directory graph to query"
|
|
@@ -971,10 +988,16 @@ def probe(
|
|
|
971
988
|
|
|
972
989
|
if code:
|
|
973
990
|
lines = code.splitlines()
|
|
974
|
-
|
|
991
|
+
n = context_lines if context_lines > 0 else len(lines)
|
|
992
|
+
snippet_lines = lines[:n]
|
|
975
993
|
snippet = "\n".join(snippet_lines)
|
|
976
|
-
extra = f"\n... ({len(lines) -
|
|
977
|
-
|
|
994
|
+
extra = f"\n... ({len(lines) - n} more lines)" if len(lines) > n else ""
|
|
995
|
+
lang = "python"
|
|
996
|
+
if node.path:
|
|
997
|
+
ext = Path(node.path).suffix.lower()
|
|
998
|
+
lang_map = {".js": "javascript", ".ts": "typescript", ".tsx": "typescript", ".jsx": "javascript", ".go": "go", ".rs": "rust", ".c": "c", ".h": "c", ".cpp": "cpp", ".java": "java", ".rb": "ruby", ".kt": "kotlin", ".swift": "swift", ".cs": "csharp", ".scala": "scala", ".lua": "lua", ".zig": "zig", ".php": "php", ".sh": "bash", ".ps1": "powershell", ".json": "json", ".yaml": "yaml", ".yml": "yaml"}
|
|
999
|
+
lang = lang_map.get(ext, "python")
|
|
1000
|
+
syntax = Syntax(snippet + extra, lang, theme="monokai", line_numbers=True)
|
|
978
1001
|
panel = Panel(syntax, title=header, border_style="dim")
|
|
979
1002
|
console.print(panel)
|
|
980
1003
|
else:
|
|
@@ -1082,7 +1105,7 @@ def version():
|
|
|
1082
1105
|
try:
|
|
1083
1106
|
ver = _v("ctxgraph-code")
|
|
1084
1107
|
except Exception:
|
|
1085
|
-
ver = "0.
|
|
1108
|
+
ver = "0.5.0"
|
|
1086
1109
|
console.print(f"ctxgraph-code version [bold]{ver}[/bold]")
|
|
1087
1110
|
|
|
1088
1111
|
|
|
@@ -52,6 +52,14 @@ class Settings:
|
|
|
52
52
|
def exclude_patterns(self) -> list[str]:
|
|
53
53
|
return self._data["graph"].get("exclude", [])
|
|
54
54
|
|
|
55
|
+
@property
|
|
56
|
+
def follow_symlinks(self) -> bool:
|
|
57
|
+
return self._data["graph"].get("follow_symlinks", False)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def max_file_size_mb(self) -> int:
|
|
61
|
+
return self._data["graph"].get("max_file_size_mb", 5)
|
|
62
|
+
|
|
55
63
|
def to_dict(self) -> dict:
|
|
56
64
|
return dict(self._data)
|
|
57
65
|
|
|
@@ -59,6 +59,11 @@ def build_graph(
|
|
|
59
59
|
if jobs <= 0:
|
|
60
60
|
jobs = (os.cpu_count() or 1)
|
|
61
61
|
|
|
62
|
+
from ctxgraph_code.config.settings import Settings
|
|
63
|
+
_settings = Settings(repo_path)
|
|
64
|
+
follow_symlinks = _settings.follow_symlinks
|
|
65
|
+
max_bytes = _settings.max_file_size_mb * 1024 * 1024
|
|
66
|
+
|
|
62
67
|
@lru_cache(maxsize=None)
|
|
63
68
|
def _should_exclude(path: Path) -> bool:
|
|
64
69
|
return should_exclude(path, repo_path, exclude_patterns)
|
|
@@ -68,7 +73,7 @@ def build_graph(
|
|
|
68
73
|
scan_files: list[Path] = []
|
|
69
74
|
current_mtimes: dict[str, float] = {}
|
|
70
75
|
|
|
71
|
-
for dirpath, dirnames, filenames in os.walk(repo_path):
|
|
76
|
+
for dirpath, dirnames, filenames in os.walk(repo_path, followlinks=follow_symlinks):
|
|
72
77
|
dirnames[:] = [
|
|
73
78
|
d for d in dirnames
|
|
74
79
|
if not _should_exclude(repo_path / d)
|
|
@@ -140,7 +145,7 @@ def build_graph(
|
|
|
140
145
|
|
|
141
146
|
with mp.Pool(jobs) as pool:
|
|
142
147
|
results = [
|
|
143
|
-
pool.apply_async(_worker_batch, (chunk, repo_path, path_index, no_summary))
|
|
148
|
+
pool.apply_async(_worker_batch, (chunk, repo_path, path_index, no_summary, max_bytes))
|
|
144
149
|
for chunk in chunks
|
|
145
150
|
]
|
|
146
151
|
for i, r in enumerate(results):
|
|
@@ -159,7 +164,7 @@ def build_graph(
|
|
|
159
164
|
else:
|
|
160
165
|
for i, file_path in enumerate(changed_files):
|
|
161
166
|
try:
|
|
162
|
-
nds, eds, fh = _process_file(file_path, repo_path, path_index, no_summary)
|
|
167
|
+
nds, eds, fh = _process_file(file_path, repo_path, path_index, no_summary, max_bytes)
|
|
163
168
|
all_nodes.extend(nds)
|
|
164
169
|
all_edges.extend(eds)
|
|
165
170
|
file_hashes.update(fh)
|
|
@@ -213,14 +218,22 @@ def build_graph(
|
|
|
213
218
|
# ── worker helpers ───────────────────────────────────────────────────────────
|
|
214
219
|
|
|
215
220
|
|
|
216
|
-
def _quick_scan(source: str) -> bool:
|
|
217
|
-
"""Quick pre-check: does this file have
|
|
218
|
-
|
|
221
|
+
def _quick_scan(source: str, is_python: bool = True) -> bool:
|
|
222
|
+
"""Quick pre-check: does this file have meaningful code?
|
|
223
|
+
Returns True if full parsing is needed."""
|
|
219
224
|
for line in source.splitlines():
|
|
220
225
|
line = line.strip()
|
|
221
|
-
if not line or line.startswith("#"):
|
|
226
|
+
if not line or line.startswith(("#", "//", "/*", "*", "--", ";")) and is_python:
|
|
227
|
+
continue
|
|
228
|
+
if not line:
|
|
222
229
|
continue
|
|
223
|
-
if
|
|
230
|
+
if is_python:
|
|
231
|
+
if any(line.startswith(kw) for kw in ("import ", "from ", "class ", "def ", "@")):
|
|
232
|
+
return True
|
|
233
|
+
else:
|
|
234
|
+
if any(kw in line for kw in ("function", "class", "struct", "trait", "interface", "import ", "include ", "fn ", "def ", "pub ", "export ", "impl ")):
|
|
235
|
+
return True
|
|
236
|
+
if any(c in line for c in ("{", "(", "=", ";")):
|
|
224
237
|
return True
|
|
225
238
|
return False
|
|
226
239
|
|
|
@@ -234,9 +247,17 @@ def _process_file(
|
|
|
234
247
|
root_path: Path,
|
|
235
248
|
path_index: set[str],
|
|
236
249
|
no_summary: bool = False,
|
|
250
|
+
max_bytes: int = 0,
|
|
237
251
|
) -> tuple[list[dict], list[dict], dict[str, str]]:
|
|
238
252
|
rel = str(file_path.relative_to(root_path)).replace("\\", "/")
|
|
239
253
|
|
|
254
|
+
if max_bytes > 0:
|
|
255
|
+
try:
|
|
256
|
+
if file_path.stat().st_size > max_bytes:
|
|
257
|
+
return [], [], {}
|
|
258
|
+
except OSError:
|
|
259
|
+
pass
|
|
260
|
+
|
|
240
261
|
try:
|
|
241
262
|
source = file_path.read_text(encoding="utf-8", errors="replace")
|
|
242
263
|
except OSError:
|
|
@@ -261,7 +282,7 @@ def _process_python(
|
|
|
261
282
|
) -> tuple[list[dict], list[dict], dict[str, str]]:
|
|
262
283
|
fhash = fhash or {}
|
|
263
284
|
|
|
264
|
-
if not _quick_scan(source):
|
|
285
|
+
if not _quick_scan(source, is_python=True):
|
|
265
286
|
return [{
|
|
266
287
|
"id": f"{root_path}:{rel}",
|
|
267
288
|
"type": "file",
|
|
@@ -320,13 +341,36 @@ def _process_treesitter(
|
|
|
320
341
|
fhash: dict[str, str] | None = None,
|
|
321
342
|
) -> tuple[list[dict], list[dict], dict[str, str]]:
|
|
322
343
|
fhash = fhash or {}
|
|
344
|
+
|
|
345
|
+
if not _quick_scan(source, is_python=False):
|
|
346
|
+
return [{
|
|
347
|
+
"id": f"{root_path}:{rel}",
|
|
348
|
+
"type": "file",
|
|
349
|
+
"name": file_path.name,
|
|
350
|
+
"path": rel,
|
|
351
|
+
"parent_id": None,
|
|
352
|
+
"summary": None,
|
|
353
|
+
"importance": 0.5,
|
|
354
|
+
"size_bytes": len(source),
|
|
355
|
+
"lineno": 0,
|
|
356
|
+
}], [], fhash
|
|
357
|
+
|
|
323
358
|
from ctxgraph_code.analyzers.treesitter import TSAnalyzer
|
|
324
359
|
|
|
325
360
|
analyzer = TSAnalyzer(file_path, root_path)
|
|
326
361
|
if not analyzer.can_handle():
|
|
327
362
|
return [], [], fhash
|
|
328
363
|
|
|
329
|
-
|
|
364
|
+
import warnings
|
|
365
|
+
try:
|
|
366
|
+
result = analyzer.analyze(source)
|
|
367
|
+
except ImportError:
|
|
368
|
+
warnings.warn(
|
|
369
|
+
f"tree-sitter not installed — skipping {rel}. "
|
|
370
|
+
"Install with: pip install 'ctxgraph-code[full]'"
|
|
371
|
+
)
|
|
372
|
+
return [], [], fhash
|
|
373
|
+
|
|
330
374
|
return result.nodes, result.edges, fhash
|
|
331
375
|
|
|
332
376
|
|
|
@@ -335,6 +379,7 @@ def _worker_batch(
|
|
|
335
379
|
root_path: Path,
|
|
336
380
|
path_index: set[str],
|
|
337
381
|
no_summary: bool = False,
|
|
382
|
+
max_bytes: int = 0,
|
|
338
383
|
) -> tuple[list[dict], list[dict], int, int, dict[str, str]]:
|
|
339
384
|
nodes: list[dict] = []
|
|
340
385
|
edges: list[dict] = []
|
|
@@ -343,7 +388,7 @@ def _worker_batch(
|
|
|
343
388
|
err = 0
|
|
344
389
|
for fp in file_paths:
|
|
345
390
|
try:
|
|
346
|
-
nds, eds, fh = _process_file(fp, root_path, path_index, no_summary)
|
|
391
|
+
nds, eds, fh = _process_file(fp, root_path, path_index, no_summary, max_bytes)
|
|
347
392
|
nodes.extend(nds)
|
|
348
393
|
edges.extend(eds)
|
|
349
394
|
hashes.update(fh)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ctxgraph-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Code knowledge graph for Claude Code. Build a relationship graph of your Python codebase and query it during coding sessions.
|
|
5
5
|
Author: ctxgraph-code contributors
|
|
6
6
|
License: MIT
|
|
@@ -18,6 +18,9 @@ Requires-Python: >=3.10
|
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
Requires-Dist: typer>=0.9
|
|
20
20
|
Requires-Dist: rich>=13.0
|
|
21
|
+
Provides-Extra: full
|
|
22
|
+
Requires-Dist: tree-sitter>=0.22; extra == "full"
|
|
23
|
+
Requires-Dist: tree-sitter-language-pack>=0.13; extra == "full"
|
|
21
24
|
Provides-Extra: dev
|
|
22
25
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
23
26
|
|
|
@@ -27,6 +30,8 @@ Requires-Dist: pytest>=7.0; extra == "dev"
|
|
|
27
30
|
|
|
28
31
|
```bash
|
|
29
32
|
pip install ctxgraph-code
|
|
33
|
+
# For multi-language support (C, Go, Rust, JS, TS, Java, etc.):
|
|
34
|
+
pip install 'ctxgraph-code[full]'
|
|
30
35
|
cd my-project
|
|
31
36
|
ctxgraph-code setup
|
|
32
37
|
```
|
|
@@ -49,10 +54,10 @@ These questions require running multiple `grep` commands or reading dependency c
|
|
|
49
54
|
## Quick Start
|
|
50
55
|
|
|
51
56
|
```bash
|
|
52
|
-
# Install
|
|
53
|
-
pip install ctxgraph-code
|
|
57
|
+
# Install (add [full] for multi-language support)
|
|
58
|
+
pip install 'ctxgraph-code[full]'
|
|
54
59
|
|
|
55
|
-
# Navigate to your
|
|
60
|
+
# Navigate to your project
|
|
56
61
|
cd my-project
|
|
57
62
|
|
|
58
63
|
# One-command setup: init + build + configure Claude Code
|
|
@@ -77,7 +82,14 @@ Interactive walkthrough — prompts for:
|
|
|
77
82
|
Does everything in one step:
|
|
78
83
|
1. Creates `.ctxgraph/config.toml` with your chosen extensions and excludes
|
|
79
84
|
2. Installs the `/ctxgraph-code` slash command globally (works in every Claude Code session)
|
|
80
|
-
3. Builds the knowledge graph from all matching files
|
|
85
|
+
3. Builds the knowledge graph from all matching files — shows live per-graph progress:
|
|
86
|
+
```
|
|
87
|
+
Building 5 graphs with 8 workers...
|
|
88
|
+
✔ src/ (42 files, 156 nodes, 34 edges, 0.8s)
|
|
89
|
+
✔ api/ (18 files, 73 nodes, 12 edges, 0.4s)
|
|
90
|
+
✔ tests/ (31 files, 89 nodes, 0 edges, 0.6s)
|
|
91
|
+
Built all 5 graphs in 2.1s
|
|
92
|
+
```
|
|
81
93
|
|
|
82
94
|
Non-interactive mode:
|
|
83
95
|
```bash
|
|
@@ -119,6 +131,15 @@ Scans all matching files in the project, runs AST analysis. Extensions are read
|
|
|
119
131
|
- `--verbose` / `-v` — show per-file progress
|
|
120
132
|
- `--no-summary` — skip docstring extraction for faster builds
|
|
121
133
|
|
|
134
|
+
Shows live per-graph progress as each completes:
|
|
135
|
+
```
|
|
136
|
+
Building 5 graphs with 8 workers...
|
|
137
|
+
✔ src/ (42 files, 156 nodes, 34 edges, 0.8s)
|
|
138
|
+
✔ api/ (18 files, 73 nodes, 12 edges, 0.4s)
|
|
139
|
+
✔ tests/ (31 files, 89 nodes, 0 edges, 0.6s)
|
|
140
|
+
Built all 5 graphs in 2.1s
|
|
141
|
+
```
|
|
142
|
+
|
|
122
143
|
Stores graphs in `.ctxgraph/graphs/<dir>.db` (per-directory) or `.ctxgraph/graph.db` (combined).
|
|
123
144
|
|
|
124
145
|
> The graph is a **static snapshot**. If code changes, run `ctxgraph-code build` again to refresh. Use `--incremental` to only reprocess changed files.
|
|
@@ -222,10 +243,10 @@ ctxgraph-code probe "database connection pool"
|
|
|
222
243
|
ctxgraph-code probe "user authentication" --max 3
|
|
223
244
|
```
|
|
224
245
|
|
|
225
|
-
Searches the graph for relevant nodes **and reads the actual source code** inline. Claude gets paths + source in one command, saving 1–2 tool calls. Shows the first
|
|
246
|
+
Searches the graph for relevant nodes **and reads the actual source code** inline. Claude gets paths + source in one command, saving 1–2 tool calls. Shows the first N lines of matched files with automatic syntax highlighting per language.
|
|
226
247
|
|
|
227
248
|
- `--max` / `-m` — max files to probe (default: 5)
|
|
228
|
-
- `--context` / `-c` — lines
|
|
249
|
+
- `--context` / `-c` — lines to show per file (default: 40, use 0 for full file)
|
|
229
250
|
|
|
230
251
|
### `install-hooks`
|
|
231
252
|
|
|
@@ -314,7 +335,10 @@ This catches the common case where you edit a file after building the graph and
|
|
|
314
335
|
| **Multiprocessing** | Combined graphs split files across CPU cores via `multiprocessing.Pool` |
|
|
315
336
|
| **`--jobs`** | Control parallelism level (default: CPU count) |
|
|
316
337
|
| **Incremental builds** | `--incremental` caches file mtimes, only reprocesses changed files |
|
|
317
|
-
| **Trivial file skip** | `_quick_scan()` pre-checks
|
|
338
|
+
| **Trivial file skip** | `_quick_scan()` pre-checks all files (Python and non-Python) — skips full parse for files with no code |
|
|
339
|
+
| **`follow_symlinks` config** | Respects `follow_symlinks = false` setting to avoid duplicate/broken symlinks |
|
|
340
|
+
| **`max_file_size_mb` config** | Skips files exceeding the configured size limit before reading |
|
|
341
|
+
| **Live build progress** | Per-graph status + timing as each completes during parallel builds |
|
|
318
342
|
| **Cached excludes** | `lru_cache` on `should_exclude()` during `os.walk` |
|
|
319
343
|
| **Batch SQLite inserts** | `executemany` instead of per-row `INSERT` statements |
|
|
320
344
|
| **`--no-summary`** | Skips docstring extraction (fastest rebuilds) |
|
|
@@ -386,7 +410,7 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
|
|
|
386
410
|
|
|
387
411
|
| Feature | ctxgraph | ctxgraph-code |
|
|
388
412
|
|---------|----------|---------------|
|
|
389
|
-
| CLI commands | 9+ |
|
|
413
|
+
| CLI commands | 9+ | 17 (init, build, query, deps, usedby, overview, symbols, context, setup, view, info, install-slash, build-status, probe, install-hooks, uninstall-hooks, version) |
|
|
390
414
|
| LLM integration | Built-in (Ollama, Claude, OpenAI, Azure) | None (delegates to Claude Code) |
|
|
391
415
|
| Chat sessions | Yes | No |
|
|
392
416
|
| Visualizer | D3.js HTML + SVG | D3.js HTML (`view` opens in browser, `--tree` for text) |
|
|
@@ -401,6 +425,7 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
|
|
|
401
425
|
|
|
402
426
|
- Python 3.10+
|
|
403
427
|
- A Claude Code subscription (for the `/ctxgraph-code` slash command — the graph itself works standalone)
|
|
428
|
+
- For multi-language analysis (C, Go, Rust, JS, TS, Java, etc.): `pip install 'ctxgraph-code[full]'` to install tree-sitter support
|
|
404
429
|
|
|
405
430
|
---
|
|
406
431
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/treesitter/__init__.py
RENAMED
|
File without changes
|
{ctxgraph_code-0.4.1 → ctxgraph_code-0.5.1}/src/ctxgraph_code/analyzers/treesitter/languages.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|