ctxgraph-code 0.2.0__tar.gz → 0.2.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 (32) hide show
  1. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/PKG-INFO +1 -1
  2. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/pyproject.toml +1 -1
  3. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/cli.py +80 -30
  4. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code.egg-info/PKG-INFO +1 -1
  5. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/README.md +0 -0
  6. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/setup.cfg +0 -0
  7. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/__init__.py +0 -0
  8. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/__main__.py +0 -0
  9. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/analyzers/__init__.py +0 -0
  10. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/analyzers/python/__init__.py +0 -0
  11. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/analyzers/python/importer.py +0 -0
  12. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/analyzers/python/semantic.py +0 -0
  13. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/analyzers/python/symbols.py +0 -0
  14. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/config/__init__.py +0 -0
  15. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/config/global_paths.py +0 -0
  16. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/config/init.py +0 -0
  17. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/config/settings.py +0 -0
  18. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/exclude/__init__.py +0 -0
  19. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/exclude/patterns.py +0 -0
  20. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/graph/__init__.py +0 -0
  21. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/graph/builder.py +0 -0
  22. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/graph/models.py +0 -0
  23. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/graph/query.py +0 -0
  24. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/graph/storage.py +0 -0
  25. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/render.py +0 -0
  26. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/view/__init__.py +0 -0
  27. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code/view/visualizer.py +0 -0
  28. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code.egg-info/SOURCES.txt +0 -0
  29. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code.egg-info/dependency_links.txt +0 -0
  30. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code.egg-info/entry_points.txt +0 -0
  31. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.1}/src/ctxgraph_code.egg-info/requires.txt +0 -0
  32. {ctxgraph_code-0.2.0 → ctxgraph_code-0.2.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.2.0
3
+ Version: 0.2.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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ctxgraph-code"
7
- version = "0.2.0"
7
+ version = "0.2.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"}
@@ -261,6 +261,76 @@ def _build_single_graph(path, exts, user_patterns, db_path, label):
261
261
  return stats
262
262
 
263
263
 
264
+ def _build_dir_worker(path, exts, user_patterns, db_path, label):
265
+ """Silent build worker for parallel execution. No console output."""
266
+ stats = build_graph(
267
+ path,
268
+ db_path=db_path,
269
+ exclude_patterns=user_patterns,
270
+ extensions=exts,
271
+ )
272
+ return label, stats
273
+
274
+
275
+ def _build_dirs_parallel(path, exts, user_patterns, top_dirs, graphs_dir, jobs):
276
+ """Build per-directory graphs in parallel using a thread pool."""
277
+ from concurrent.futures import ThreadPoolExecutor, as_completed
278
+
279
+ n_workers = max(1, jobs) if jobs > 0 else os.cpu_count() or 1
280
+ console.print(f"[dim]Building {len(top_dirs)} graphs with {n_workers} workers...[/dim]")
281
+
282
+ futures = []
283
+ with ThreadPoolExecutor(max_workers=n_workers) as pool:
284
+ for d in top_dirs:
285
+ db_path = graphs_dir / f"{d.name}.db"
286
+ fut = pool.submit(_build_dir_worker, path, exts, user_patterns, db_path, d.name)
287
+ futures.append(fut)
288
+
289
+ results = []
290
+ for f in as_completed(futures):
291
+ try:
292
+ label, stats = f.result()
293
+ results.append((label, stats))
294
+ except Exception as e:
295
+ results.append(("error", str(e)))
296
+
297
+ results.sort(key=lambda x: x[0] if isinstance(x[0], str) else "")
298
+
299
+ summary = Table(title="Build Summary")
300
+ summary.add_column("Directory", style="cyan")
301
+ summary.add_column("Files", style="green")
302
+ summary.add_column("Nodes", style="blue")
303
+ summary.add_column("Edges", style="yellow")
304
+ summary.add_column("Time", style="magenta")
305
+
306
+ total_files = 0
307
+ total_nodes = 0
308
+ total_edges = 0
309
+ total_time = 0.0
310
+
311
+ for label, stats in results:
312
+ if isinstance(stats, str):
313
+ summary.add_row(f"{label}/", "[red]ERROR[/red]", stats, "", "")
314
+ else:
315
+ files = stats.get("files_analyzed", 0)
316
+ nodes = stats.get("total_nodes", 0)
317
+ edges = stats.get("total_edges", 0)
318
+ t = stats.get("elapsed_seconds", 0)
319
+ summary.add_row(f"{label}/", str(files), str(nodes), str(edges), f"{t}s")
320
+ total_files += files
321
+ total_nodes += nodes
322
+ total_edges += edges
323
+ total_time = max(total_time, t)
324
+
325
+ console.print(summary)
326
+ console.print(
327
+ f"\n[green]Built {len(top_dirs)} graphs: "
328
+ f"{total_files} files, {total_nodes} nodes, {total_edges} edges "
329
+ f"in {total_time}s[/green]"
330
+ )
331
+ return results
332
+
333
+
264
334
  @app.command()
265
335
  def build(
266
336
  repo_path: Optional[str] = typer.Argument(
@@ -275,10 +345,13 @@ def build(
275
345
  all_graph: bool = typer.Option(
276
346
  False, "--all", "-a", help="Build a single combined graph instead of per-directory"
277
347
  ),
348
+ jobs: int = typer.Option(
349
+ 0, "--jobs", "-j", help="Number of parallel workers (0 = auto, default: CPU count)"
350
+ ),
278
351
  ):
279
352
  """Build the knowledge graph from source files.
280
353
 
281
- Default: builds a separate graph per top-level directory.
354
+ Default: builds a separate graph per top-level directory in parallel.
282
355
  Use --all to build one combined graph instead.
283
356
  """
284
357
  path = Path(repo_path).resolve() if repo_path else Path.cwd()
@@ -299,7 +372,6 @@ def build(
299
372
  db_path = ctx_dir / "graph.db"
300
373
  _build_single_graph(path, exts, user_patterns, db_path, "combined")
301
374
  else:
302
- # Per-directory: find top-level dirs (skip excluded ones)
303
375
  from ctxgraph_code.exclude.patterns import should_exclude
304
376
  top_dirs = sorted([
305
377
  d for d in path.iterdir()
@@ -314,28 +386,7 @@ def build(
314
386
  else:
315
387
  graphs_dir = ctx_dir / "graphs"
316
388
  graphs_dir.mkdir(parents=True, exist_ok=True)
317
-
318
- total_nodes = 0
319
- total_edges = 0
320
- for d in top_dirs:
321
- db_path = graphs_dir / f"{d.name}.db"
322
- s = _build_single_graph(path, exts, user_patterns, db_path, d.name)
323
- total_nodes += s.get("total_nodes", 0)
324
- total_edges += s.get("total_edges", 0)
325
-
326
- summary = Table(title="Build Summary")
327
- summary.add_column("Directory", style="cyan")
328
- for d in top_dirs:
329
- db = graphs_dir / f"{d.name}.db"
330
- if db.exists():
331
- from ctxgraph_code.graph.storage import Storage
332
- st = Storage(db)
333
- st.connect()
334
- nd = st.stats()["nodes"]
335
- ed = st.stats()["edges"]
336
- summary.add_row(f"{d.name}/: {nd} nodes, {ed} edges")
337
- console.print(summary)
338
- console.print(f"\n[green]Built {len(top_dirs)} graphs in {graphs_dir}[/green]")
389
+ _build_dirs_parallel(path, exts, user_patterns, top_dirs, graphs_dir, jobs)
339
390
 
340
391
 
341
392
  @app.command()
@@ -490,6 +541,9 @@ def setup(
490
541
  False, "--project-slash",
491
542
  help="Install slash command in project .claude/ instead of globally",
492
543
  ),
544
+ jobs: int = typer.Option(
545
+ 0, "--jobs", "-j", help="Number of parallel workers (0 = auto, default: CPU count)"
546
+ ),
493
547
  ):
494
548
  """Initialize config, build the graph, and install the Claude Code slash command.
495
549
 
@@ -529,7 +583,6 @@ def setup(
529
583
  init_project(path, extensions=exts, exclude_patterns=excl)
530
584
  console.print("[green][OK] Initialized .ctxgraph/[/green]")
531
585
 
532
- # Build per-directory graphs
533
586
  ctx_dir = path / ".ctxgraph"
534
587
  graphs_dir = ctx_dir / "graphs"
535
588
  graphs_dir.mkdir(parents=True, exist_ok=True)
@@ -539,10 +592,7 @@ def setup(
539
592
  ])
540
593
 
541
594
  if top_dirs:
542
- for d in top_dirs:
543
- db_path = graphs_dir / f"{d.name}.db"
544
- _build_single_graph(path, exts, excl, db_path, d.name)
545
- console.print(f"[green][OK] Built graphs for {len(top_dirs)} directories[/green]")
595
+ _build_dirs_parallel(path, exts, excl, top_dirs, graphs_dir, jobs)
546
596
  else:
547
597
  db_path = ctx_dir / "graph.db"
548
598
  _build_single_graph(path, exts, excl, db_path, "combined")
@@ -684,7 +734,7 @@ def version():
684
734
  try:
685
735
  ver = _v("ctxgraph-code")
686
736
  except Exception:
687
- ver = "0.2.0"
737
+ ver = "0.2.1"
688
738
  console.print(f"ctxgraph-code version [bold]{ver}[/bold]")
689
739
 
690
740
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctxgraph-code
3
- Version: 0.2.0
3
+ Version: 0.2.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
File without changes
File without changes