ctxgraph-code 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/PKG-INFO +14 -3
  2. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/README.md +13 -2
  3. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/pyproject.toml +1 -1
  4. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/cli.py +29 -1
  5. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/render.py +101 -0
  6. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/PKG-INFO +14 -3
  7. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/setup.cfg +0 -0
  8. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/__init__.py +0 -0
  9. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/__main__.py +0 -0
  10. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/__init__.py +0 -0
  11. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/__init__.py +0 -0
  12. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/importer.py +0 -0
  13. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/semantic.py +0 -0
  14. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/symbols.py +0 -0
  15. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/config/__init__.py +0 -0
  16. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/config/init.py +0 -0
  17. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/config/settings.py +0 -0
  18. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/exclude/__init__.py +0 -0
  19. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/exclude/patterns.py +0 -0
  20. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/__init__.py +0 -0
  21. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/builder.py +0 -0
  22. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/models.py +0 -0
  23. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/query.py +0 -0
  24. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/storage.py +0 -0
  25. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/SOURCES.txt +0 -0
  26. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/dependency_links.txt +0 -0
  27. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/entry_points.txt +0 -0
  28. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/requires.txt +0 -0
  29. {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/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.1
3
+ Version: 0.1.2
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
@@ -162,6 +162,17 @@ ctxgraph-code context "add pagination to the users endpoint"
162
162
 
163
163
  Generates a focused context summary: relevant files, their symbols, and dependency/call edges between them. This is the closest equivalent to `ctxgraph`'s capsule format.
164
164
 
165
+ ### `view`
166
+
167
+ ```bash
168
+ ctxgraph-code view
169
+ ctxgraph-code view --output tree.txt
170
+ ```
171
+
172
+ Prints a hierarchical directory tree from the graph showing every file and its symbols (classes marked `[C]`, functions/methods marked `[M]`). Also lists import and call edges at the bottom.
173
+
174
+ Useful for a quick visual scan of the project structure without reading every file.
175
+
165
176
  ### `info`
166
177
 
167
178
  ```bash
@@ -272,10 +283,10 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
272
283
 
273
284
  | Feature | ctxgraph | ctxgraph-code |
274
285
  |---------|----------|---------------|
275
- | CLI commands | 9 (build, capsule, query, view, serve, info, init, ask, chat, history, skill) | 8 (init, build, query, deps, usedby, overview, symbols, context, setup, info) |
286
+ | CLI commands | 9 (build, capsule, query, view, serve, info, init, ask, chat, history, skill) | 9 (init, build, query, deps, usedby, overview, symbols, context, setup, view, info) |
276
287
  | LLM integration | Built-in (Ollama, Claude, OpenAI, Azure) | None (delegates to Claude Code) |
277
288
  | Chat sessions | Yes | No |
278
- | Visualizer | D3.js HTML + SVG | No |
289
+ | Visualizer | D3.js HTML + SVG | Text tree (`view` command) |
279
290
  | Skills system | Yes (customizable skill TOML files) | No |
280
291
  | MCP server | Yes | No |
281
292
  | Token savings | Yes (capsule DSL compression) | No |
@@ -139,6 +139,17 @@ ctxgraph-code context "add pagination to the users endpoint"
139
139
 
140
140
  Generates a focused context summary: relevant files, their symbols, and dependency/call edges between them. This is the closest equivalent to `ctxgraph`'s capsule format.
141
141
 
142
+ ### `view`
143
+
144
+ ```bash
145
+ ctxgraph-code view
146
+ ctxgraph-code view --output tree.txt
147
+ ```
148
+
149
+ Prints a hierarchical directory tree from the graph showing every file and its symbols (classes marked `[C]`, functions/methods marked `[M]`). Also lists import and call edges at the bottom.
150
+
151
+ Useful for a quick visual scan of the project structure without reading every file.
152
+
142
153
  ### `info`
143
154
 
144
155
  ```bash
@@ -249,10 +260,10 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
249
260
 
250
261
  | Feature | ctxgraph | ctxgraph-code |
251
262
  |---------|----------|---------------|
252
- | CLI commands | 9 (build, capsule, query, view, serve, info, init, ask, chat, history, skill) | 8 (init, build, query, deps, usedby, overview, symbols, context, setup, info) |
263
+ | CLI commands | 9 (build, capsule, query, view, serve, info, init, ask, chat, history, skill) | 9 (init, build, query, deps, usedby, overview, symbols, context, setup, view, info) |
253
264
  | LLM integration | Built-in (Ollama, Claude, OpenAI, Azure) | None (delegates to Claude Code) |
254
265
  | Chat sessions | Yes | No |
255
- | Visualizer | D3.js HTML + SVG | No |
266
+ | Visualizer | D3.js HTML + SVG | Text tree (`view` command) |
256
267
  | Skills system | Yes (customizable skill TOML files) | No |
257
268
  | MCP server | Yes | No |
258
269
  | Token savings | Yes (capsule DSL compression) | No |
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ctxgraph-code"
7
- version = "0.1.1"
7
+ version = "0.1.2"
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"}
@@ -17,6 +17,7 @@ from ctxgraph_code.render import (
17
17
  render_deps,
18
18
  render_overview,
19
19
  render_symbols,
20
+ render_treeview,
20
21
  render_usedby,
21
22
  )
22
23
 
@@ -350,6 +351,33 @@ def setup(
350
351
  console.print("Open Claude Code in this project and type [bold]/ctxgraph-code[/bold] to get started.")
351
352
 
352
353
 
354
+ @app.command()
355
+ def view(
356
+ repo_path: Optional[str] = typer.Option(
357
+ None, "--repo", "-r", help="Repository path"
358
+ ),
359
+ output: Optional[str] = typer.Option(
360
+ None, "--output", "-o", help="Save tree to file"
361
+ ),
362
+ ):
363
+ """Visualize the graph as a directory tree with symbols and edges."""
364
+ path = Path(repo_path).resolve() if repo_path else Path.cwd()
365
+
366
+ storage = get_storage(path)
367
+ if storage is None:
368
+ console.print("[red]No graph found. Run [bold]ctxgraph-code build[/bold] first.[/red]")
369
+ raise typer.Exit(1)
370
+
371
+ tree = render_treeview(storage)
372
+
373
+ if output:
374
+ out_path = Path(output)
375
+ out_path.write_text(tree, encoding="utf-8")
376
+ console.print(f"Saved tree to [bold]{out_path}[/bold]")
377
+ else:
378
+ console.print(tree)
379
+
380
+
353
381
  @app.command()
354
382
  def info(
355
383
  repo_path: Optional[str] = typer.Option(
@@ -395,7 +423,7 @@ def version():
395
423
  try:
396
424
  ver = _v("ctxgraph-code")
397
425
  except Exception:
398
- ver = "0.1.0"
426
+ ver = "0.1.2"
399
427
  console.print(f"ctxgraph-code version [bold]{ver}[/bold]")
400
428
 
401
429
 
@@ -235,6 +235,107 @@ def render_context(storage: Storage, query: str, max_nodes: int = 15) -> str:
235
235
  return "\n".join(lines)
236
236
 
237
237
 
238
+ def render_treeview(storage: Storage) -> str:
239
+ all_nodes = storage.get_all_nodes()
240
+ all_edges = storage.get_all_edges()
241
+
242
+ file_nodes = sorted([n for n in all_nodes if n.type == "file"], key=lambda n: n.path or "")
243
+ symbol_map: dict[str, list[Node]] = {}
244
+ for n in all_nodes:
245
+ if n.type != "file":
246
+ symbol_map.setdefault(n.parent_id or "", []).append(n)
247
+
248
+ dir_tree: dict[str, dict] = {}
249
+ for node in file_nodes:
250
+ parts = (node.path or node.name).split("/")
251
+ for i in range(len(parts)):
252
+ parent = "/".join(parts[:i]) if i > 0 else "."
253
+ child = parts[i]
254
+ if parent not in dir_tree:
255
+ dir_tree[parent] = {"dirs": set(), "files": []}
256
+ if i == len(parts) - 1:
257
+ dir_tree[parent]["files"].append(node)
258
+ else:
259
+ dir_tree[parent]["dirs"].add(child)
260
+
261
+ stats = storage.stats()
262
+ bt = storage.get_metadata("build_time")
263
+ build_label = ""
264
+ if bt:
265
+ try:
266
+ from datetime import datetime
267
+ build_label = f" (built {datetime.fromtimestamp(float(bt)).strftime('%Y-%m-%d %H:%M')})"
268
+ except Exception:
269
+ pass
270
+
271
+ lines = [
272
+ f".ctxgraph/graph.db ({stats['nodes']} nodes, {stats['edges']} edges){build_label}",
273
+ "",
274
+ ]
275
+
276
+ def _render_dir(parent: str, prefix: str = ""):
277
+ entry = dir_tree.get(parent, {"dirs": set(), "files": []})
278
+ items: list[tuple[str, object]] = []
279
+ for d in sorted(entry["dirs"]):
280
+ items.append(("dir", d))
281
+ for f in sorted(entry["files"], key=lambda x: x.path or x.name):
282
+ items.append(("file", f))
283
+
284
+ for idx, (kind, obj) in enumerate(items):
285
+ last = idx == len(items) - 1
286
+ connector = "\\-- " if last else "+-- "
287
+ ext = " " if last else "| "
288
+
289
+ if kind == "dir":
290
+ name = str(obj)
291
+ lines.append(f"{prefix}{connector}{name}/")
292
+ child = name if parent == "." else parent + "/" + name
293
+ _render_dir(child, prefix + ext)
294
+ else:
295
+ node = obj
296
+ basename = (node.path or node.name).split("/")[-1]
297
+ lines.append(f"{prefix}{connector}{basename}")
298
+ symbols = sorted(symbol_map.get(node.id, []), key=lambda s: s.lineno)
299
+ if symbols:
300
+ sym_lines = []
301
+ for s in symbols:
302
+ tag = "C" if s.type == "class" else "M"
303
+ summary = f" -- {s.summary}" if s.summary else ""
304
+ sym_lines.append(f" [{tag}] {s.name}{summary}")
305
+ for sidx, sl in enumerate(sym_lines):
306
+ slast = sidx == len(sym_lines) - 1
307
+ sconn = "\\-- " if slast else "+-- "
308
+ lines.append(f"{prefix}{ext}{sconn}{sl}")
309
+
310
+ _render_dir(".")
311
+ lines.append("")
312
+
313
+ import_edges = [(s, t) for e in all_edges for s, t, r in [(e.source_id, e.target_id, e.relation)] if r == "imports"]
314
+ call_edges = [(s, t) for e in all_edges for s, t, r in [(e.source_id, e.target_id, e.relation)] if r == "calls"]
315
+
316
+ if import_edges:
317
+ lines.append(f"Imports ({len(import_edges)}):")
318
+ node_map = {n.id: n for n in all_nodes}
319
+ for src, tgt in sorted(import_edges, key=lambda x: (x[0], x[1]))[:20]:
320
+ sn = _short_name(src, node_map) or src
321
+ tn = _short_name(tgt, node_map) or tgt
322
+ lines.append(f" {sn} -> {tn}")
323
+ if len(import_edges) > 20:
324
+ lines.append(f" ... and {len(import_edges) - 20} more")
325
+
326
+ if call_edges:
327
+ lines.append(f"\nCalls ({len(call_edges)}):")
328
+ node_map = {n.id: n for n in all_nodes}
329
+ for src, tgt in sorted(call_edges, key=lambda x: (x[0], x[1]))[:15]:
330
+ sn = _short_name(src, node_map) or src
331
+ tn = _short_name(tgt, node_map) or tgt
332
+ lines.append(f" {sn} -> {tn}")
333
+ if len(call_edges) > 15:
334
+ lines.append(f" ... and {len(call_edges) - 15} more")
335
+
336
+ return "\n".join(lines)
337
+
338
+
238
339
  def _short_name(node_id: str, node_map: dict[str, Node]) -> Optional[str]:
239
340
  if node_id in node_map:
240
341
  n = node_map[node_id]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctxgraph-code
3
- Version: 0.1.1
3
+ Version: 0.1.2
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
@@ -162,6 +162,17 @@ ctxgraph-code context "add pagination to the users endpoint"
162
162
 
163
163
  Generates a focused context summary: relevant files, their symbols, and dependency/call edges between them. This is the closest equivalent to `ctxgraph`'s capsule format.
164
164
 
165
+ ### `view`
166
+
167
+ ```bash
168
+ ctxgraph-code view
169
+ ctxgraph-code view --output tree.txt
170
+ ```
171
+
172
+ Prints a hierarchical directory tree from the graph showing every file and its symbols (classes marked `[C]`, functions/methods marked `[M]`). Also lists import and call edges at the bottom.
173
+
174
+ Useful for a quick visual scan of the project structure without reading every file.
175
+
165
176
  ### `info`
166
177
 
167
178
  ```bash
@@ -272,10 +283,10 @@ Built-in default exclusion patterns (always applied): `__pycache__`, `*.pyc`, `.
272
283
 
273
284
  | Feature | ctxgraph | ctxgraph-code |
274
285
  |---------|----------|---------------|
275
- | CLI commands | 9 (build, capsule, query, view, serve, info, init, ask, chat, history, skill) | 8 (init, build, query, deps, usedby, overview, symbols, context, setup, info) |
286
+ | CLI commands | 9 (build, capsule, query, view, serve, info, init, ask, chat, history, skill) | 9 (init, build, query, deps, usedby, overview, symbols, context, setup, view, info) |
276
287
  | LLM integration | Built-in (Ollama, Claude, OpenAI, Azure) | None (delegates to Claude Code) |
277
288
  | Chat sessions | Yes | No |
278
- | Visualizer | D3.js HTML + SVG | No |
289
+ | Visualizer | D3.js HTML + SVG | Text tree (`view` command) |
279
290
  | Skills system | Yes (customizable skill TOML files) | No |
280
291
  | MCP server | Yes | No |
281
292
  | Token savings | Yes (capsule DSL compression) | No |
File without changes