ctxgraph-code 0.1.0__tar.gz → 0.1.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.1.0 → ctxgraph_code-0.1.1}/PKG-INFO +24 -8
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/README.md +23 -7
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/pyproject.toml +1 -1
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/cli.py +75 -9
- ctxgraph_code-0.1.1/src/ctxgraph_code/config/init.py +19 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/config/settings.py +41 -6
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/builder.py +4 -2
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/PKG-INFO +24 -8
- ctxgraph_code-0.1.0/src/ctxgraph_code/config/init.py +0 -14
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/setup.cfg +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/__init__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/__main__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/__init__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/__init__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/importer.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/semantic.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/symbols.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/config/__init__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/exclude/__init__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/exclude/patterns.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/__init__.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/models.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/query.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/storage.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/render.py +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/SOURCES.txt +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/dependency_links.txt +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/entry_points.txt +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/requires.txt +0 -0
- {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.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.1.
|
|
3
|
+
Version: 0.1.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
|
|
@@ -70,11 +70,21 @@ ctxgraph-code setup
|
|
|
70
70
|
ctxgraph-code setup
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
Interactive walkthrough — prompts for:
|
|
74
|
+
- **File extensions** to scan (`.py`, `.js`, `.ts`, etc.)
|
|
75
|
+
- **Exclude patterns** (folders like `tests/`, globs like `*.generated.py`)
|
|
76
|
+
|
|
73
77
|
Does everything in one step:
|
|
74
|
-
1. Creates `.ctxgraph/config.toml` with
|
|
75
|
-
2. Builds the knowledge graph from all
|
|
78
|
+
1. Creates `.ctxgraph/config.toml` with your chosen extensions and excludes
|
|
79
|
+
2. Builds the knowledge graph from all matching files
|
|
76
80
|
3. Creates `.claude/commands/ctxgraph-code.md` with instructions for Claude Code
|
|
77
81
|
|
|
82
|
+
Non-interactive mode (skip prompts):
|
|
83
|
+
```bash
|
|
84
|
+
ctxgraph-code setup --extensions .py,.js,.ts --exclude tests/,examples/
|
|
85
|
+
ctxgraph-code setup -y # all defaults
|
|
86
|
+
```
|
|
87
|
+
|
|
78
88
|
### `init`
|
|
79
89
|
|
|
80
90
|
```bash
|
|
@@ -87,10 +97,12 @@ Creates the `.ctxgraph/` directory with a default `config.toml`.
|
|
|
87
97
|
|
|
88
98
|
```bash
|
|
89
99
|
ctxgraph-code build
|
|
90
|
-
ctxgraph-code build --
|
|
100
|
+
ctxgraph-code build --extensions .py,.js,.ts
|
|
101
|
+
ctxgraph-code build --exclude tests/ --exclude *.generated.py
|
|
91
102
|
```
|
|
92
103
|
|
|
93
|
-
Scans all
|
|
104
|
+
Scans all matching files in the project, runs AST analysis. Extensions are read from config (`.py` by default, or whatever was set in `setup`).
|
|
105
|
+
|
|
94
106
|
- **Imports**: which files import other files
|
|
95
107
|
- **Class definitions**: class names, base classes, methods
|
|
96
108
|
- **Function definitions**: function names, arguments
|
|
@@ -99,6 +111,8 @@ Scans all `*.py` files in the project, runs AST analysis:
|
|
|
99
111
|
|
|
100
112
|
Stores the result in `.ctxgraph/graph.db`.
|
|
101
113
|
|
|
114
|
+
> The graph is a **static snapshot**. If code changes, run `ctxgraph-code build` again to refresh. Claude Code will also rebuild when it detects the graph is stale.
|
|
115
|
+
|
|
102
116
|
### `query`
|
|
103
117
|
|
|
104
118
|
```bash
|
|
@@ -234,11 +248,13 @@ Claude then uses these commands as needed during the conversation.
|
|
|
234
248
|
|
|
235
249
|
## Configuration
|
|
236
250
|
|
|
237
|
-
Configure via `.ctxgraph/config.toml` (created by `
|
|
251
|
+
Configure via `.ctxgraph/config.toml` (created interactively by `setup` or manually):
|
|
238
252
|
|
|
239
253
|
```toml
|
|
240
254
|
[graph]
|
|
241
|
-
#
|
|
255
|
+
# File extensions to scan
|
|
256
|
+
extensions = [".py", ".js", ".ts"]
|
|
257
|
+
# Exclude patterns beyond built-in defaults
|
|
242
258
|
exclude = ["tests/", "examples/"]
|
|
243
259
|
# Follow symlinks when scanning
|
|
244
260
|
follow_symlinks = false
|
|
@@ -246,7 +262,7 @@ follow_symlinks = false
|
|
|
246
262
|
max_file_size_mb = 5
|
|
247
263
|
```
|
|
248
264
|
|
|
249
|
-
|
|
265
|
+
Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.git`, `node_modules`, `venv`, `.venv`, `dist`, `build`, `*.egg-info`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.tox`, `migrations`, `*.min.js`, `*.min.css`.
|
|
250
266
|
|
|
251
267
|
---
|
|
252
268
|
|
|
@@ -47,11 +47,21 @@ ctxgraph-code setup
|
|
|
47
47
|
ctxgraph-code setup
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
Interactive walkthrough — prompts for:
|
|
51
|
+
- **File extensions** to scan (`.py`, `.js`, `.ts`, etc.)
|
|
52
|
+
- **Exclude patterns** (folders like `tests/`, globs like `*.generated.py`)
|
|
53
|
+
|
|
50
54
|
Does everything in one step:
|
|
51
|
-
1. Creates `.ctxgraph/config.toml` with
|
|
52
|
-
2. Builds the knowledge graph from all
|
|
55
|
+
1. Creates `.ctxgraph/config.toml` with your chosen extensions and excludes
|
|
56
|
+
2. Builds the knowledge graph from all matching files
|
|
53
57
|
3. Creates `.claude/commands/ctxgraph-code.md` with instructions for Claude Code
|
|
54
58
|
|
|
59
|
+
Non-interactive mode (skip prompts):
|
|
60
|
+
```bash
|
|
61
|
+
ctxgraph-code setup --extensions .py,.js,.ts --exclude tests/,examples/
|
|
62
|
+
ctxgraph-code setup -y # all defaults
|
|
63
|
+
```
|
|
64
|
+
|
|
55
65
|
### `init`
|
|
56
66
|
|
|
57
67
|
```bash
|
|
@@ -64,10 +74,12 @@ Creates the `.ctxgraph/` directory with a default `config.toml`.
|
|
|
64
74
|
|
|
65
75
|
```bash
|
|
66
76
|
ctxgraph-code build
|
|
67
|
-
ctxgraph-code build --
|
|
77
|
+
ctxgraph-code build --extensions .py,.js,.ts
|
|
78
|
+
ctxgraph-code build --exclude tests/ --exclude *.generated.py
|
|
68
79
|
```
|
|
69
80
|
|
|
70
|
-
Scans all
|
|
81
|
+
Scans all matching files in the project, runs AST analysis. Extensions are read from config (`.py` by default, or whatever was set in `setup`).
|
|
82
|
+
|
|
71
83
|
- **Imports**: which files import other files
|
|
72
84
|
- **Class definitions**: class names, base classes, methods
|
|
73
85
|
- **Function definitions**: function names, arguments
|
|
@@ -76,6 +88,8 @@ Scans all `*.py` files in the project, runs AST analysis:
|
|
|
76
88
|
|
|
77
89
|
Stores the result in `.ctxgraph/graph.db`.
|
|
78
90
|
|
|
91
|
+
> The graph is a **static snapshot**. If code changes, run `ctxgraph-code build` again to refresh. Claude Code will also rebuild when it detects the graph is stale.
|
|
92
|
+
|
|
79
93
|
### `query`
|
|
80
94
|
|
|
81
95
|
```bash
|
|
@@ -211,11 +225,13 @@ Claude then uses these commands as needed during the conversation.
|
|
|
211
225
|
|
|
212
226
|
## Configuration
|
|
213
227
|
|
|
214
|
-
Configure via `.ctxgraph/config.toml` (created by `
|
|
228
|
+
Configure via `.ctxgraph/config.toml` (created interactively by `setup` or manually):
|
|
215
229
|
|
|
216
230
|
```toml
|
|
217
231
|
[graph]
|
|
218
|
-
#
|
|
232
|
+
# File extensions to scan
|
|
233
|
+
extensions = [".py", ".js", ".ts"]
|
|
234
|
+
# Exclude patterns beyond built-in defaults
|
|
219
235
|
exclude = ["tests/", "examples/"]
|
|
220
236
|
# Follow symlinks when scanning
|
|
221
237
|
follow_symlinks = false
|
|
@@ -223,7 +239,7 @@ follow_symlinks = false
|
|
|
223
239
|
max_file_size_mb = 5
|
|
224
240
|
```
|
|
225
241
|
|
|
226
|
-
|
|
242
|
+
Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.git`, `node_modules`, `venv`, `.venv`, `dist`, `build`, `*.egg-info`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.tox`, `migrations`, `*.min.js`, `*.min.css`.
|
|
227
243
|
|
|
228
244
|
---
|
|
229
245
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ctxgraph-code"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.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"}
|
|
@@ -24,11 +24,25 @@ app = typer.Typer(name="ctxgraph-code", help="Code knowledge graph for Claude Co
|
|
|
24
24
|
console = Console()
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def _build_time_label(storage) -> str:
|
|
28
|
+
ts = storage.get_metadata("build_time")
|
|
29
|
+
if ts:
|
|
30
|
+
try:
|
|
31
|
+
from datetime import datetime
|
|
32
|
+
dt = datetime.fromtimestamp(float(ts))
|
|
33
|
+
return dt.strftime("%Y-%m-%d %H:%M")
|
|
34
|
+
except Exception:
|
|
35
|
+
return ts
|
|
36
|
+
return "unknown"
|
|
37
|
+
|
|
38
|
+
|
|
27
39
|
SLASH_COMMAND_TEMPLATE = """# ctxgraph-code: Code Relationship Graph
|
|
28
40
|
|
|
29
41
|
This project has a knowledge graph at `.ctxgraph/graph.db`.
|
|
30
42
|
The graph knows about imports, class hierarchies, and function calls.
|
|
31
43
|
|
|
44
|
+
**Last build:** {build_time}
|
|
45
|
+
|
|
32
46
|
**Available commands** (run these as shell commands in the terminal):
|
|
33
47
|
|
|
34
48
|
- `ctxgraph-code query "search terms"` -- Find relevant files, classes, and functions
|
|
@@ -43,6 +57,9 @@ The graph knows about imports, class hierarchies, and function calls.
|
|
|
43
57
|
- When exploring an unfamiliar area, run `query` to find relevant files, then read them.
|
|
44
58
|
- When asked about architecture, run `overview` for the big picture.
|
|
45
59
|
- For complex tasks, run `context "what I need to do"` for a focused summary.
|
|
60
|
+
|
|
61
|
+
**Note:** The graph is a static snapshot. If files have changed since the last build,
|
|
62
|
+
run `ctxgraph-code build` to refresh it.
|
|
46
63
|
"""
|
|
47
64
|
|
|
48
65
|
|
|
@@ -70,11 +87,14 @@ def build(
|
|
|
70
87
|
repo_path: Optional[str] = typer.Argument(
|
|
71
88
|
None, help="Path to repository (default: current directory)"
|
|
72
89
|
),
|
|
90
|
+
extensions: Optional[str] = typer.Option(
|
|
91
|
+
None, "--extensions", help="File extensions to scan, e.g. .py,.js,.ts"
|
|
92
|
+
),
|
|
73
93
|
exclude: Optional[list[str]] = typer.Option(
|
|
74
94
|
None, "--exclude", "-e", help="Additional exclude patterns"
|
|
75
95
|
),
|
|
76
96
|
):
|
|
77
|
-
"""Build the knowledge graph from
|
|
97
|
+
"""Build the knowledge graph from source files."""
|
|
78
98
|
path = Path(repo_path).resolve() if repo_path else Path.cwd()
|
|
79
99
|
|
|
80
100
|
settings = Settings(path)
|
|
@@ -82,11 +102,16 @@ def build(
|
|
|
82
102
|
if exclude:
|
|
83
103
|
user_patterns = list((user_patterns or []) + exclude)
|
|
84
104
|
|
|
105
|
+
exts = settings.extensions
|
|
106
|
+
if extensions:
|
|
107
|
+
exts = [e.strip() for e in extensions.split(",") if e.strip()]
|
|
108
|
+
|
|
85
109
|
if not (path / ".ctxgraph").exists():
|
|
86
110
|
(path / ".ctxgraph").mkdir(parents=True, exist_ok=True)
|
|
87
111
|
|
|
88
|
-
|
|
89
|
-
|
|
112
|
+
ext_label = ", ".join(exts)
|
|
113
|
+
with console.status(f"Scanning {ext_label} files in {path}..."):
|
|
114
|
+
stats = build_graph(path, exclude_patterns=user_patterns, extensions=exts)
|
|
90
115
|
|
|
91
116
|
table = Table(title="Graph Build Complete")
|
|
92
117
|
table.add_column("Metric", style="cyan")
|
|
@@ -247,16 +272,52 @@ def setup(
|
|
|
247
272
|
repo_path: Optional[str] = typer.Argument(
|
|
248
273
|
None, help="Path to repository (default: current directory)"
|
|
249
274
|
),
|
|
275
|
+
extensions: Optional[str] = typer.Option(
|
|
276
|
+
None, "--extensions", help="File extensions to scan, e.g. .py,.js,.ts"
|
|
277
|
+
),
|
|
278
|
+
exclude: Optional[str] = typer.Option(
|
|
279
|
+
None, "--exclude", help="Exclude patterns, e.g. tests/,examples/"
|
|
280
|
+
),
|
|
281
|
+
non_interactive: bool = typer.Option(
|
|
282
|
+
False, "--yes", "-y", help="Skip prompts, use defaults"
|
|
283
|
+
),
|
|
250
284
|
):
|
|
251
|
-
"""Initialize config, build the graph, and configure Claude Code
|
|
285
|
+
"""Initialize config, build the graph, and configure Claude Code."""
|
|
252
286
|
path = Path(repo_path).resolve() if repo_path else Path.cwd()
|
|
253
287
|
|
|
254
|
-
|
|
288
|
+
if non_interactive:
|
|
289
|
+
exts = [".py"]
|
|
290
|
+
excl = []
|
|
291
|
+
elif extensions:
|
|
292
|
+
exts = [e.strip() for e in extensions.split(",") if e.strip()]
|
|
293
|
+
excl = [e.strip() for e in exclude.split(",") if e.strip()] if exclude else []
|
|
294
|
+
else:
|
|
295
|
+
console.print("[bold cyan]ctxgraph-code setup[/bold cyan]")
|
|
296
|
+
console.print("Let's configure your project graph.\n")
|
|
297
|
+
|
|
298
|
+
ext_input = typer.prompt(
|
|
299
|
+
"File extensions to scan (comma-separated)",
|
|
300
|
+
default=".py",
|
|
301
|
+
prompt_suffix=": ",
|
|
302
|
+
)
|
|
303
|
+
exts = [e.strip() for e in ext_input.split(",") if e.strip()]
|
|
304
|
+
if not exts:
|
|
305
|
+
exts = [".py"]
|
|
306
|
+
|
|
307
|
+
excl_input = typer.prompt(
|
|
308
|
+
"Exclude patterns (comma-separated, e.g. tests/,examples/)",
|
|
309
|
+
default="",
|
|
310
|
+
prompt_suffix=": ",
|
|
311
|
+
)
|
|
312
|
+
excl = [e.strip() for e in excl_input.split(",") if e.strip()] if excl_input.strip() else []
|
|
313
|
+
|
|
314
|
+
console.print()
|
|
315
|
+
|
|
316
|
+
init_project(path, extensions=exts, exclude_patterns=excl)
|
|
255
317
|
console.print(f"[green][OK] Initialized .ctxgraph/[/green]")
|
|
256
318
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
stats = build_graph(path, exclude_patterns=settings.exclude_patterns)
|
|
319
|
+
with console.status(f"Scanning {', '.join(exts)} files in {path}..."):
|
|
320
|
+
stats = build_graph(path, exclude_patterns=excl, extensions=exts)
|
|
260
321
|
|
|
261
322
|
table = Table(title="Graph Build Complete")
|
|
262
323
|
table.add_column("Metric", style="cyan")
|
|
@@ -273,8 +334,13 @@ def setup(
|
|
|
273
334
|
claude_dir = path / ".claude" / "commands"
|
|
274
335
|
claude_dir.mkdir(parents=True, exist_ok=True)
|
|
275
336
|
slash_path = claude_dir / "ctxgraph-code.md"
|
|
337
|
+
|
|
338
|
+
storage = get_storage(path)
|
|
339
|
+
build_label = _build_time_label(storage) if storage else "unknown"
|
|
340
|
+
content = SLASH_COMMAND_TEMPLATE.format(build_time=build_label)
|
|
341
|
+
|
|
276
342
|
if not slash_path.exists():
|
|
277
|
-
slash_path.write_text(
|
|
343
|
+
slash_path.write_text(content, encoding="utf-8")
|
|
278
344
|
console.print(f"[green][OK] Created {slash_path}[/green]")
|
|
279
345
|
else:
|
|
280
346
|
console.print(f"[yellow] Skipped (already exists): {slash_path}[/yellow]")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from ctxgraph_code.config.settings import create_default_config
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def init_project(
|
|
10
|
+
repo_path: Path,
|
|
11
|
+
extensions: Optional[list[str]] = None,
|
|
12
|
+
exclude_patterns: Optional[list[str]] = None,
|
|
13
|
+
) -> Path:
|
|
14
|
+
cfg_dir = repo_path / ".ctxgraph"
|
|
15
|
+
cfg_dir.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
|
|
17
|
+
create_default_config(repo_path, extensions=extensions, exclude_patterns=exclude_patterns)
|
|
18
|
+
|
|
19
|
+
return cfg_dir
|
|
@@ -8,6 +8,7 @@ from typing import Optional
|
|
|
8
8
|
|
|
9
9
|
DEFAULT_CONFIG = {
|
|
10
10
|
"graph": {
|
|
11
|
+
"extensions": [".py"],
|
|
11
12
|
"exclude": [],
|
|
12
13
|
"follow_symlinks": False,
|
|
13
14
|
"max_file_size_mb": 5,
|
|
@@ -43,6 +44,11 @@ class Settings:
|
|
|
43
44
|
parsed = self._parse_toml(text)
|
|
44
45
|
self._deep_merge(self._data, parsed)
|
|
45
46
|
|
|
47
|
+
@property
|
|
48
|
+
def extensions(self) -> list[str]:
|
|
49
|
+
exts = self._data["graph"].get("extensions", [".py"])
|
|
50
|
+
return [e if e.startswith(".") else f".{e}" for e in exts]
|
|
51
|
+
|
|
46
52
|
@property
|
|
47
53
|
def exclude_patterns(self) -> list[str]:
|
|
48
54
|
return self._data["graph"].get("exclude", [])
|
|
@@ -67,8 +73,10 @@ class Settings:
|
|
|
67
73
|
key = key.strip()
|
|
68
74
|
value = value.strip()
|
|
69
75
|
|
|
70
|
-
if
|
|
71
|
-
|
|
76
|
+
if value.startswith("[") and value.endswith("]"):
|
|
77
|
+
value = Settings._parse_toml_array(value)
|
|
78
|
+
elif (value.startswith('"') and value.endswith('"')) or \
|
|
79
|
+
(value.startswith("'") and value.endswith("'")):
|
|
72
80
|
value = value[1:-1]
|
|
73
81
|
else:
|
|
74
82
|
value = Settings._parse_toml_value(value)
|
|
@@ -77,6 +85,21 @@ class Settings:
|
|
|
77
85
|
|
|
78
86
|
return result
|
|
79
87
|
|
|
88
|
+
@staticmethod
|
|
89
|
+
def _parse_toml_array(text: str) -> list:
|
|
90
|
+
inner = text[1:-1].strip()
|
|
91
|
+
if not inner:
|
|
92
|
+
return []
|
|
93
|
+
items = []
|
|
94
|
+
for item in inner.split(","):
|
|
95
|
+
item = item.strip()
|
|
96
|
+
if (item.startswith('"') and item.endswith('"')) or \
|
|
97
|
+
(item.startswith("'") and item.endswith("'")):
|
|
98
|
+
items.append(item[1:-1])
|
|
99
|
+
else:
|
|
100
|
+
items.append(Settings._parse_toml_value(item))
|
|
101
|
+
return items
|
|
102
|
+
|
|
80
103
|
@staticmethod
|
|
81
104
|
def _parse_toml_value(value: str):
|
|
82
105
|
if value.lower() in ("true", "false"):
|
|
@@ -97,7 +120,11 @@ class Settings:
|
|
|
97
120
|
base[key] = value
|
|
98
121
|
|
|
99
122
|
|
|
100
|
-
def create_default_config(
|
|
123
|
+
def create_default_config(
|
|
124
|
+
repo_path: Path,
|
|
125
|
+
extensions: Optional[list[str]] = None,
|
|
126
|
+
exclude_patterns: Optional[list[str]] = None,
|
|
127
|
+
):
|
|
101
128
|
config_dir = repo_path / ".ctxgraph"
|
|
102
129
|
config_dir.mkdir(parents=True, exist_ok=True)
|
|
103
130
|
|
|
@@ -105,12 +132,20 @@ def create_default_config(repo_path: Path):
|
|
|
105
132
|
if config_path.exists():
|
|
106
133
|
return
|
|
107
134
|
|
|
135
|
+
ext_list = extensions or [".py"]
|
|
136
|
+
ext_line = ", ".join(f'"{e}"' for e in ext_list)
|
|
137
|
+
|
|
138
|
+
excl_list = exclude_patterns or []
|
|
139
|
+
excl_line = ", ".join(f'"{e}"' for e in excl_list) if excl_list else ""
|
|
140
|
+
|
|
108
141
|
config_path.write_text(
|
|
109
|
-
"""# ctxgraph-code configuration
|
|
142
|
+
f"""# ctxgraph-code configuration
|
|
110
143
|
|
|
111
144
|
[graph]
|
|
112
|
-
#
|
|
113
|
-
|
|
145
|
+
# File extensions to scan
|
|
146
|
+
extensions = [{ext_line}]
|
|
147
|
+
# Exclude patterns (gitignore patterns are excluded automatically)
|
|
148
|
+
exclude = [{excl_line}]
|
|
114
149
|
# Follow symlinks when scanning files
|
|
115
150
|
follow_symlinks = false
|
|
116
151
|
# Skip files larger than this many MB
|
|
@@ -16,6 +16,7 @@ def build_graph(
|
|
|
16
16
|
repo_path: str | Path,
|
|
17
17
|
db_path: Optional[str | Path] = None,
|
|
18
18
|
exclude_patterns: Optional[list[str]] = None,
|
|
19
|
+
extensions: Optional[list[str]] = None,
|
|
19
20
|
) -> dict:
|
|
20
21
|
repo_path = Path(repo_path).resolve()
|
|
21
22
|
if db_path is None:
|
|
@@ -29,8 +30,9 @@ def build_graph(
|
|
|
29
30
|
combined = Graph()
|
|
30
31
|
stats = {"files_analyzed": 0, "files_skipped": 0, "errors": 0}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
for
|
|
33
|
+
exts = set(extensions or [".py"])
|
|
34
|
+
scan_files = [f for f in repo_path.rglob("*") if f.suffix in exts and f.is_file()]
|
|
35
|
+
for file_path in scan_files:
|
|
34
36
|
if should_exclude(file_path, repo_path, exclude_patterns):
|
|
35
37
|
stats["files_skipped"] += 1
|
|
36
38
|
continue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ctxgraph-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.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
|
|
@@ -70,11 +70,21 @@ ctxgraph-code setup
|
|
|
70
70
|
ctxgraph-code setup
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
Interactive walkthrough — prompts for:
|
|
74
|
+
- **File extensions** to scan (`.py`, `.js`, `.ts`, etc.)
|
|
75
|
+
- **Exclude patterns** (folders like `tests/`, globs like `*.generated.py`)
|
|
76
|
+
|
|
73
77
|
Does everything in one step:
|
|
74
|
-
1. Creates `.ctxgraph/config.toml` with
|
|
75
|
-
2. Builds the knowledge graph from all
|
|
78
|
+
1. Creates `.ctxgraph/config.toml` with your chosen extensions and excludes
|
|
79
|
+
2. Builds the knowledge graph from all matching files
|
|
76
80
|
3. Creates `.claude/commands/ctxgraph-code.md` with instructions for Claude Code
|
|
77
81
|
|
|
82
|
+
Non-interactive mode (skip prompts):
|
|
83
|
+
```bash
|
|
84
|
+
ctxgraph-code setup --extensions .py,.js,.ts --exclude tests/,examples/
|
|
85
|
+
ctxgraph-code setup -y # all defaults
|
|
86
|
+
```
|
|
87
|
+
|
|
78
88
|
### `init`
|
|
79
89
|
|
|
80
90
|
```bash
|
|
@@ -87,10 +97,12 @@ Creates the `.ctxgraph/` directory with a default `config.toml`.
|
|
|
87
97
|
|
|
88
98
|
```bash
|
|
89
99
|
ctxgraph-code build
|
|
90
|
-
ctxgraph-code build --
|
|
100
|
+
ctxgraph-code build --extensions .py,.js,.ts
|
|
101
|
+
ctxgraph-code build --exclude tests/ --exclude *.generated.py
|
|
91
102
|
```
|
|
92
103
|
|
|
93
|
-
Scans all
|
|
104
|
+
Scans all matching files in the project, runs AST analysis. Extensions are read from config (`.py` by default, or whatever was set in `setup`).
|
|
105
|
+
|
|
94
106
|
- **Imports**: which files import other files
|
|
95
107
|
- **Class definitions**: class names, base classes, methods
|
|
96
108
|
- **Function definitions**: function names, arguments
|
|
@@ -99,6 +111,8 @@ Scans all `*.py` files in the project, runs AST analysis:
|
|
|
99
111
|
|
|
100
112
|
Stores the result in `.ctxgraph/graph.db`.
|
|
101
113
|
|
|
114
|
+
> The graph is a **static snapshot**. If code changes, run `ctxgraph-code build` again to refresh. Claude Code will also rebuild when it detects the graph is stale.
|
|
115
|
+
|
|
102
116
|
### `query`
|
|
103
117
|
|
|
104
118
|
```bash
|
|
@@ -234,11 +248,13 @@ Claude then uses these commands as needed during the conversation.
|
|
|
234
248
|
|
|
235
249
|
## Configuration
|
|
236
250
|
|
|
237
|
-
Configure via `.ctxgraph/config.toml` (created by `
|
|
251
|
+
Configure via `.ctxgraph/config.toml` (created interactively by `setup` or manually):
|
|
238
252
|
|
|
239
253
|
```toml
|
|
240
254
|
[graph]
|
|
241
|
-
#
|
|
255
|
+
# File extensions to scan
|
|
256
|
+
extensions = [".py", ".js", ".ts"]
|
|
257
|
+
# Exclude patterns beyond built-in defaults
|
|
242
258
|
exclude = ["tests/", "examples/"]
|
|
243
259
|
# Follow symlinks when scanning
|
|
244
260
|
follow_symlinks = false
|
|
@@ -246,7 +262,7 @@ follow_symlinks = false
|
|
|
246
262
|
max_file_size_mb = 5
|
|
247
263
|
```
|
|
248
264
|
|
|
249
|
-
|
|
265
|
+
Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.git`, `node_modules`, `venv`, `.venv`, `dist`, `build`, `*.egg-info`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.tox`, `migrations`, `*.min.js`, `*.min.css`.
|
|
250
266
|
|
|
251
267
|
---
|
|
252
268
|
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from ctxgraph_code.config.settings import create_default_config
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def init_project(repo_path: Path) -> Path:
|
|
9
|
-
cfg_dir = repo_path / ".ctxgraph"
|
|
10
|
-
cfg_dir.mkdir(parents=True, exist_ok=True)
|
|
11
|
-
|
|
12
|
-
create_default_config(repo_path)
|
|
13
|
-
|
|
14
|
-
return cfg_dir
|
|
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
|
|
File without changes
|
|
File without changes
|