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.
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/PKG-INFO +14 -3
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/README.md +13 -2
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/pyproject.toml +1 -1
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/cli.py +29 -1
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/render.py +101 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/PKG-INFO +14 -3
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/setup.cfg +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/__init__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/__main__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/__init__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/__init__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/importer.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/semantic.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/analyzers/python/symbols.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/config/__init__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/config/init.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/config/settings.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/exclude/__init__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/exclude/patterns.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/__init__.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/builder.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/models.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/query.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code/graph/storage.py +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/SOURCES.txt +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/dependency_links.txt +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/entry_points.txt +0 -0
- {ctxgraph_code-0.1.1 → ctxgraph_code-0.1.2}/src/ctxgraph_code.egg-info/requires.txt +0 -0
- {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.
|
|
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) |
|
|
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 |
|
|
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) |
|
|
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 |
|
|
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.
|
|
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.
|
|
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.
|
|
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) |
|
|
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 |
|
|
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
|
|
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
|
|
File without changes
|