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.
Files changed (30) hide show
  1. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/PKG-INFO +24 -8
  2. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/README.md +23 -7
  3. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/pyproject.toml +1 -1
  4. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/cli.py +75 -9
  5. ctxgraph_code-0.1.1/src/ctxgraph_code/config/init.py +19 -0
  6. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/config/settings.py +41 -6
  7. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/builder.py +4 -2
  8. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/PKG-INFO +24 -8
  9. ctxgraph_code-0.1.0/src/ctxgraph_code/config/init.py +0 -14
  10. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/setup.cfg +0 -0
  11. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/__init__.py +0 -0
  12. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/__main__.py +0 -0
  13. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/__init__.py +0 -0
  14. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/__init__.py +0 -0
  15. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/importer.py +0 -0
  16. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/semantic.py +0 -0
  17. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/analyzers/python/symbols.py +0 -0
  18. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/config/__init__.py +0 -0
  19. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/exclude/__init__.py +0 -0
  20. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/exclude/patterns.py +0 -0
  21. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/__init__.py +0 -0
  22. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/models.py +0 -0
  23. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/query.py +0 -0
  24. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/graph/storage.py +0 -0
  25. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code/render.py +0 -0
  26. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/SOURCES.txt +0 -0
  27. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/dependency_links.txt +0 -0
  28. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/entry_points.txt +0 -0
  29. {ctxgraph_code-0.1.0 → ctxgraph_code-0.1.1}/src/ctxgraph_code.egg-info/requires.txt +0 -0
  30. {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.0
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 defaults
75
- 2. Builds the knowledge graph from all Python files
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 --exclude "tests/" --exclude "*.generated.py"
100
+ ctxgraph-code build --extensions .py,.js,.ts
101
+ ctxgraph-code build --exclude tests/ --exclude *.generated.py
91
102
  ```
92
103
 
93
- Scans all `*.py` files in the project, runs AST analysis:
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 `init` or `setup`):
251
+ Configure via `.ctxgraph/config.toml` (created interactively by `setup` or manually):
238
252
 
239
253
  ```toml
240
254
  [graph]
241
- # Additional exclude patterns beyond defaults
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
- Default exclusion patterns: `__pycache__`, `*.pyc`, `.git`, `node_modules`, `venv`, `.venv`, `dist`, `build`, `*.egg-info`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.tox`, `migrations`, `*.min.js`, `*.min.css`.
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 defaults
52
- 2. Builds the knowledge graph from all Python files
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 --exclude "tests/" --exclude "*.generated.py"
77
+ ctxgraph-code build --extensions .py,.js,.ts
78
+ ctxgraph-code build --exclude tests/ --exclude *.generated.py
68
79
  ```
69
80
 
70
- Scans all `*.py` files in the project, runs AST analysis:
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 `init` or `setup`):
228
+ Configure via `.ctxgraph/config.toml` (created interactively by `setup` or manually):
215
229
 
216
230
  ```toml
217
231
  [graph]
218
- # Additional exclude patterns beyond defaults
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
- Default exclusion patterns: `__pycache__`, `*.pyc`, `.git`, `node_modules`, `venv`, `.venv`, `dist`, `build`, `*.egg-info`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.tox`, `migrations`, `*.min.js`, `*.min.css`.
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.0"
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 Python source files."""
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
- with console.status(f"Analyzing {path}..."):
89
- stats = build_graph(path, exclude_patterns=user_patterns)
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 integration."""
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
- init_project(path)
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
- settings = Settings(path)
258
- with console.status(f"Building graph for {path}..."):
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(SLASH_COMMAND_TEMPLATE, encoding="utf-8")
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 (value.startswith('"') and value.endswith('"')) or \
71
- (value.startswith("'") and value.endswith("'")):
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(repo_path: Path):
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
- # Additional exclude patterns (gitignore is used automatically)
113
- exclude = []
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
- python_files = list(repo_path.rglob("*.py"))
33
- for file_path in python_files:
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.0
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 defaults
75
- 2. Builds the knowledge graph from all Python files
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 --exclude "tests/" --exclude "*.generated.py"
100
+ ctxgraph-code build --extensions .py,.js,.ts
101
+ ctxgraph-code build --exclude tests/ --exclude *.generated.py
91
102
  ```
92
103
 
93
- Scans all `*.py` files in the project, runs AST analysis:
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 `init` or `setup`):
251
+ Configure via `.ctxgraph/config.toml` (created interactively by `setup` or manually):
238
252
 
239
253
  ```toml
240
254
  [graph]
241
- # Additional exclude patterns beyond defaults
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
- Default exclusion patterns: `__pycache__`, `*.pyc`, `.git`, `node_modules`, `venv`, `.venv`, `dist`, `build`, `*.egg-info`, `.pytest_cache`, `.mypy_cache`, `.ruff_cache`, `.tox`, `migrations`, `*.min.js`, `*.min.css`.
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