ctxgraph 0.2.4__tar.gz → 0.3.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 (53) hide show
  1. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/PKG-INFO +323 -101
  2. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/README.md +322 -100
  3. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/pyproject.toml +1 -1
  4. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/capsule/renderer.py +9 -1
  5. ctxgraph-0.3.1/src/ctxgraph/capsule/savings.py +85 -0
  6. ctxgraph-0.3.1/src/ctxgraph/cli/main.py +537 -0
  7. ctxgraph-0.3.1/src/ctxgraph/config/init.py +26 -0
  8. ctxgraph-0.3.1/src/ctxgraph/history.py +69 -0
  9. ctxgraph-0.3.1/src/ctxgraph/skills/__init__.py +38 -0
  10. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/view/visualizer.py +10 -2
  11. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph.egg-info/PKG-INFO +323 -101
  12. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph.egg-info/SOURCES.txt +5 -0
  13. ctxgraph-0.3.1/tests/test_e2e.py +219 -0
  14. ctxgraph-0.2.4/src/ctxgraph/cli/main.py +0 -262
  15. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/setup.cfg +0 -0
  16. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/__init__.py +0 -0
  17. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/analyzers/__init__.py +0 -0
  18. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/analyzers/python/__init__.py +0 -0
  19. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/analyzers/python/importer.py +0 -0
  20. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/analyzers/python/semantic.py +0 -0
  21. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/analyzers/python/symbols.py +0 -0
  22. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/capsule/__init__.py +0 -0
  23. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/cli/__init__.py +0 -0
  24. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/clients/__init__.py +0 -0
  25. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/clients/models.py +0 -0
  26. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/config/__init__.py +0 -0
  27. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/config/providers.py +0 -0
  28. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/config/settings.py +0 -0
  29. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/exclude/__init__.py +0 -0
  30. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/exclude/patterns.py +0 -0
  31. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/graph/__init__.py +0 -0
  32. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/graph/builder.py +0 -0
  33. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/graph/models.py +0 -0
  34. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/graph/query.py +0 -0
  35. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/graph/storage.py +0 -0
  36. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/mcp/__init__.py +0 -0
  37. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/mcp/server.py +0 -0
  38. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/view/__init__.py +0 -0
  39. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/wrapper/__init__.py +0 -0
  40. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph/wrapper/claude.py +0 -0
  41. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph.egg-info/dependency_links.txt +0 -0
  42. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph.egg-info/entry_points.txt +0 -0
  43. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph.egg-info/requires.txt +0 -0
  44. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/src/ctxgraph.egg-info/top_level.txt +0 -0
  45. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_analyzers.py +0 -0
  46. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_benchmark.py +0 -0
  47. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_capsule.py +0 -0
  48. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_config.py +0 -0
  49. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_integration.py +0 -0
  50. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_model_mode.py +0 -0
  51. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_models.py +0 -0
  52. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_query.py +0 -0
  53. {ctxgraph-0.2.4 → ctxgraph-0.3.1}/tests/test_storage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctxgraph
3
- Version: 0.2.4
3
+ Version: 0.3.1
4
4
  Summary: AI context engine for Python — cuts LLM tokens 97% via code knowledge graphs. Build, query, and generate compact context capsules for Claude, OpenAI, Ollama.
5
5
  Author: ctxgraph contributors
6
6
  License: MIT
@@ -35,6 +35,7 @@ Requires-Dist: ruff>=0.1.0; extra == "dev"
35
35
  pip install ctxgraph
36
36
 
37
37
  ctx build # Build knowledge graph
38
+ ctx ask "how does JWT auth work" # Ask questions with automatic token savings
38
39
  ctx capsule "fix JWT expiry" # 92-99% fewer tokens vs raw code
39
40
  ccg "fix the login redirect bug" # Launch Claude with context pre-loaded
40
41
  ctx view # Interactive D3.js visualization (or --svg for static)
@@ -44,6 +45,24 @@ ctx view # Interactive D3.js visualization (or --svg f
44
45
 
45
46
  ---
46
47
 
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ # 1. Initialize project
52
+ ctx init # Creates .ctxgraph/config.toml + default skills
53
+
54
+ # 2. Build the knowledge graph
55
+ ctx build # AST analysis → SQLite graph
56
+
57
+ # 3. Ask questions (requires Ollama or other LLM provider)
58
+ ctx ask "how does authentication work"
59
+
60
+ # 4. Or generate a capsule for your AI tool
61
+ ctx capsule "fix login rate limiter" --savings
62
+ ```
63
+
64
+ ---
65
+
47
66
  ## Why ctxgraph?
48
67
 
49
68
  Sending entire files to an AI is wasteful. ctxgraph analyzes your code with AST-based static analysis, stores the result in a queryable SQLite graph, and retrieves *only the relevant nodes* — compressed into a token-efficient DSL format.
@@ -83,27 +102,6 @@ Repository (.py files)
83
102
  └─────────────────────────────────────────────────────────┘
84
103
  ```
85
104
 
86
- ### Architecture
87
-
88
- ```
89
- ┌─────────┐ ┌──────────────┐ ┌──────────────┐
90
- │ CLI │───▶│ Analyzers │───▶│ SQLite DB │
91
- │ typer │ │ AST-based │ │ .ctxgraph/ │
92
- └────┬────┘ └──────────────┘ └──────┬───────┘
93
- │ │
94
- ├── ctx build ──────────────────────▶│ Graph build
95
- │ │
96
- ├── ctx capsule ◀───────────────────│ Query + BFS
97
- │ │
98
- ├── ctx query ◀─────────────────────│ Keyword search
99
- │ │
100
- ├── ctx view ◀──────────────────────│ D3.js viz
101
- │ │
102
- ├── ctx serve ◀─────────────────────│ MCP server
103
- │ │
104
- └── ccg wrapper ───▶ Claude Code ───┘ AI tool
105
- ```
106
-
107
105
  ---
108
106
 
109
107
  ## Token Efficiency
@@ -142,40 +140,117 @@ JSON: 426 tokens DSL: 143 tokens
142
140
 
143
141
  > **97.0% average token reduction** across 4 projects, 42 benchmark runs. The larger the project, the greater the savings.
144
142
 
145
- ### With Graph vs Without (Ollama)
143
+ ### Token Savings Display
146
144
 
147
- | Query | No Context | With ctxgraph | Δ |
148
- |-------|:----------:|:-------------:|:-:|
149
- | Calculator expression parsing | 100% | 100% | — |
150
- | Plugin registration system | 33% | **100%** | **+67pp** |
151
- | JWT authentication (web_api) | 75% | **100%** | **+25pp** |
152
- | Middleware pipeline (web_api) | 100% | 100% | — |
153
- | Circuit breaker (microsvc) | 75% | 75% | — |
154
- | Services & communication | 50% | **100%** | **+50pp** |
155
- | PipelineBuilder pattern | 100% | 75% | -25pp* |
156
- | Processor registration | 33% | **67%** | **+34pp** |
157
- | Event bus & error handling | 100% | 100% | — |
158
- > \* Without context the model gave a generic answer matching all keywords; with context it focused on actual code — more honest, more useful.
145
+ ```bash
146
+ ctx capsule "user authentication" --savings
147
+ # ┌──────────────────────────┬──────────────┐
148
+ # Metric │ Value │
149
+ # ├──────────────────────────┼──────────────┤
150
+ # Raw Project .py Files │ 10,587 tokens│
151
+ # Capsule DSL │ 132 tokens │
152
+ # JSON Equivalent │ 490 tokens │
153
+ # Savings vs Raw │ 98.8%
154
+ # DSL vs JSON │ 73.1%
155
+ # └──────────────────────────┴──────────────┘
156
+ ```
159
157
 
160
- **+16.7pp average coverage improvement** better answers, concrete file names, real code structure.
158
+ `ctx ask` shows this automatically on every query. See how many tokens you save with each question.
161
159
 
162
160
  ---
163
161
 
164
162
  ## Commands
165
163
 
164
+ ### `ctx init` — Scaffold project
165
+
166
+ ```bash
167
+ ctx init # Default: current directory
168
+ ctx init /path/to/project # Specific path
169
+ ```
170
+
171
+ Creates a `.ctxgraph/` directory with everything you need:
172
+
173
+ ```
174
+ .ctxgraph/
175
+ ├── config.toml # API provider, model, context settings
176
+ ├── history.jsonl # Query history (auto-created, auto-pruned to 1000)
177
+ └── skills/
178
+ ├── project-style.toml # Default skill: project conventions
179
+ └── field-guide.toml # Default skill: field guide
180
+ ```
181
+
182
+ Idempotent — safe to run on existing projects. Existing files are never overwritten.
183
+
166
184
  ### `ctx build` — Build knowledge graph
185
+
167
186
  ```bash
168
187
  ctx build # Current directory
169
188
  ctx build /path/to/project # Specific repo
170
189
  ctx build --exclude "vendor/*" # Custom exclude patterns
190
+ ctx build --provider claude # Set LLM provider for later use
191
+ ctx build --model gpt-4o # Set LLM model for later use
171
192
  ```
172
193
 
173
- ### `ctx capsule <query>` — Generate context
194
+ ### `ctx ask <query>` — Ask questions via LLM
195
+
196
+ The marquee command. Generates a context capsule, sends it to your LLM provider, and shows token savings.
197
+
198
+ ```bash
199
+ ctx ask "how does JWT auth work" # Uses configured provider (default: Ollama)
200
+ ctx ask "fix login bug" --provider claude --model claude-sonnet-4-20250514
201
+ ctx ask "refactor payment flow" --skill project-style # Activate a skill as system prompt
202
+ ctx ask "find auth code" --graph # Show graph search results table
203
+ ctx ask "deep dive" --mode deep # Use deep graph context (40 nodes)
204
+ ctx ask "explain" --skill field-guide --graph # Combine skill + graph results
205
+ ```
206
+
207
+ **Flags:**
208
+
209
+ | Flag | Description |
210
+ |------|-------------|
211
+ | `--provider` | LLM provider: `ollama`, `claude`, `openai`, `azure`, `custom` |
212
+ | `--model` | Model name (e.g. `gpt-4o`, `claude-sonnet-4-20250514`) |
213
+ | `--skill` | Skill name to activate (e.g. `project-style`, `field-guide`) |
214
+ | `--graph` | Show ranked graph search results alongside the answer |
215
+ | `--mode` | Graph context mode: `fast`, `balanced` (default), `deep` |
216
+
217
+ **Requirements:**
218
+ - A built graph (run `ctx build` first)
219
+ - A running LLM provider (Ollama by default at `http://localhost:11434`)
220
+
221
+ **Example output:**
222
+
223
+ ```bash
224
+ $ ctx ask "how does the greeting system work"
225
+
226
+ # (Token savings table shown automatically)
227
+ ┌──────────────────────────┬──────────────┐
228
+ │ Metric │ Value │
229
+ ├──────────────────────────┼──────────────┤
230
+ │ Raw Project .py Files │ 1,234 tokens │
231
+ │ Capsule DSL │ 45 tokens │
232
+ │ JSON Equivalent │ 180 tokens │
233
+ │ Savings vs Raw │ 96.4% │
234
+ │ DSL vs JSON │ 75.0% │
235
+ └──────────────────────────┴──────────────┘
236
+
237
+ Answer:
238
+ The greeting system is implemented in `src/greet.py`. The `greet()` function takes a name
239
+ and returns a formatted greeting string. The `Greeter` class extends this with a configurable
240
+ prefix. Both use type hints and follow the project conventions.
241
+ ```
242
+
243
+ ### `ctx capsule <query>` — Generate context capsule
244
+
245
+ Generate a token-efficient DSL capsule for use with any AI tool.
246
+
174
247
  ```bash
175
248
  ctx capsule "fix JWT token validation" # Balanced (default: 20 nodes, depth 2)
176
249
  ctx capsule "fix JWT token validation" --mode fast # Fast (10 nodes, depth 1)
177
250
  ctx capsule "fix JWT token validation" --mode deep # Deep (40 nodes, depth 3)
178
251
  ctx capsule --overview # Project architecture overview
252
+ ctx capsule "fix auth" --savings # Show token savings table
253
+ ctx capsule "fix auth" --skill project-style # Prepends skill context
179
254
  ```
180
255
 
181
256
  | Mode | Max Nodes | BFS Depth | When to Use |
@@ -185,26 +260,147 @@ ctx capsule --overview # Project architecture overv
185
260
  | `deep` | 40 | 3 | Complex refactoring, architecture |
186
261
 
187
262
  ### `ctx query <search>` — Search graph
263
+
188
264
  ```bash
189
265
  ctx query "user auth"
190
266
  ctx query "payment gateway" --mode deep
191
267
  ```
192
- Returns ranked nodes with relevance scores.
268
+
269
+ Returns ranked nodes with relevance scores, displaying type, name, path, and score.
193
270
 
194
271
  ### `ctx view` — Visualize graph
272
+
273
+ ```bash
274
+ ctx view # Opens interactive D3.js HTML in browser
275
+ ctx view --output graph.html # Save to custom path
276
+ ctx view --svg # Generate static SVG
277
+ ctx view --no-open # Generate without opening browser
278
+ ```
279
+
280
+ ### `ctx history` — Query history
281
+
282
+ Review past questions, token savings, and provider usage.
283
+
284
+ ```bash
285
+ ctx history # Last 10 queries
286
+ ctx history -n 20 # Last 20
287
+ ctx history --filter "auth" # Filter by keyword in query text
288
+ ctx history --stats # Aggregate statistics
289
+ ```
290
+
291
+ **Example output:**
292
+
293
+ ```bash
294
+ $ ctx history
295
+ ┌────────────┬──────────────────────────────────────────────────┬─────────┬──────────┬──────────┐
296
+ │ Time │ Query │ Savings │ Provider │ Skill │
297
+ ├────────────┼──────────────────────────────────────────────────┼─────────┼──────────┼──────────┤
298
+ │ 2026-06-06 │ how does the greeting system work │ 96.4% │ ollama │ - │
299
+ │ 2026-06-06 │ fix login rate limiter │ 97.1% │ ollama │ - │
300
+ │ 2026-06-06 │ refactor payment module with proper error handl… │ 95.8% │ claude │ project-style │
301
+ └────────────┴──────────────────────────────────────────────────┴─────────┴──────────┴──────────┘
302
+
303
+ $ ctx history --stats
304
+ ┌──────────────────────┬───────────┐
305
+ │ Metric │ Value │
306
+ ├──────────────────────┼───────────┤
307
+ │ Total Queries │ 24 │
308
+ │ Total Raw Tokens │ 254,088 │
309
+ │ Total Tokens Saved │ 246,465 │
310
+ │ Avg Savings │ 96.5% │
311
+ │ Provider: ollama │ 18 │
312
+ │ Provider: claude │ 6 │
313
+ └──────────────────────┴───────────┘
314
+ ```
315
+
316
+ History is stored as JSONL in `.ctxgraph/history.jsonl`. Auto-prunes to 1000 entries (oldest dropped).
317
+
318
+ ### `ctx skill` — Manage skills
319
+
320
+ Skills are reusable system prompts that prepend project knowledge to your capsule context.
321
+
322
+ ```bash
323
+ ctx skill list # Show all available skills
324
+ ctx skill show project-style # Display a skill's contents
325
+ ```
326
+
327
+ **Example:**
328
+
329
+ ```bash
330
+ $ ctx skill list
331
+ ┌─────────┬─────────────────┬────────────────────────────────────────────────────┐
332
+ │ Source │ Name │ Preview │
333
+ ├─────────┼─────────────────┼────────────────────────────────────────────────────┤
334
+ │ builtin │ project-style │ # Project Style Guide — default ctxgraph skill │
335
+ │ builtin │ field-guide │ # Project Field Guide — default ctxgraph skill │
336
+ └─────────┴─────────────────┴────────────────────────────────────────────────────┘
337
+
338
+ $ ctx skill show project-style
339
+ Skill: project-style
340
+
341
+ # Project Style Guide — default ctxgraph skill
342
+ # Activate with: ctx ask --skill project-style "..."
343
+
344
+ [about]
345
+ name = "Project Style Guide"
346
+ description = "Enforces project conventions, code style, and naming patterns"
347
+
348
+ [rules]
349
+ import_style = "absolute imports, grouped: stdlib, third-party, local"
350
+ naming = "snake_case for functions/variables, PascalCase for classes, UPPER_CASE for constants"
351
+ ...
352
+ ```
353
+
354
+ **Activating a skill:**
355
+
356
+ ```bash
357
+ ctx ask "refactor payment flow" --skill project-style
358
+ ctx capsule "fix auth" --skill field-guide
359
+ ```
360
+
361
+ When activated, the skill contents are prepended as a `## Project Knowledge` section before the capsule DSL.
362
+
363
+ **Creating your own skills:**
364
+
365
+ Skills are TOML files in `.ctxgraph/skills/`. Create a new file:
366
+
367
+ ```toml
368
+ # .ctxgraph/skills/my-team-rules.toml
369
+
370
+ [about]
371
+ name = "Team Conventions"
372
+ description = "Custom team coding conventions"
373
+
374
+ [rules]
375
+ testing = "must write pytest tests for all new functions"
376
+ documentation = "every public API needs a docstring with Args and Returns"
377
+ branching = "prefer early returns over nested if-else"
378
+ ```
379
+
380
+ Now it appears in `ctx skill list` and can be activated with `--skill my-team-rules`.
381
+
382
+ ### `ctx info` — Graph statistics
383
+
195
384
  ```bash
196
- ctx view
197
- ctx view --output graph.html
198
- ctx view --port 8080 --no-open
385
+ ctx info
386
+ # ┌────────────────────┬───────┐
387
+ # Total Nodes │ 1090 │
388
+ # │ Total Edges │ 1565 │
389
+ # │ files │ 147 │
390
+ # │ classes │ 45 │
391
+ # │ functions │ 312 │
392
+ # └────────────────────┴───────┘
199
393
  ```
200
- Interactive D3.js force-directed HTML — no JS build tools needed.
201
394
 
202
395
  ### `ctx serve` — MCP server
396
+
203
397
  ```bash
204
398
  pip install ctxgraph[mcp]
205
399
  ctx serve
206
400
  ```
401
+
207
402
  Claude Desktop config:
403
+
208
404
  ```json
209
405
  {
210
406
  "mcpServers": {
@@ -215,24 +411,15 @@ Claude Desktop config:
215
411
  }
216
412
  }
217
413
  ```
218
- Tools: `search_graph`, `get_context_capsule`, `get_file_dependencies`, `get_project_overview`.
219
414
 
220
- ### `ctx info` Graph statistics
221
- ```bash
222
- ctx info
223
- # ┌────────────────────┬───────┐
224
- # │ Total Nodes │ 1090 │
225
- # │ Total Edges │ 1565 │
226
- # │ files │ 147 │
227
- # │ classes │ 45 │
228
- # │ functions │ 312 │
229
- # └────────────────────┴───────┘
230
- ```
415
+ Tools: `search_graph`, `get_context_capsule`, `get_file_dependencies`, `get_project_overview`.
231
416
 
232
417
  ---
233
418
 
234
419
  ## Claude Wrapper (`ccg`)
235
420
 
421
+ The `ccg` command launches Claude Code with ctxgraph context pre-loaded:
422
+
236
423
  ```bash
237
424
  ccg "fix the JWT expiry bug in auth module" # Single-shot
238
425
  ccg --chat "refactor the payment flow" # Interactive session
@@ -244,7 +431,8 @@ ccg --mode deep "redesign the database schema" # Deep mode
244
431
 
245
432
  ## Configuration
246
433
 
247
- `.ctxgraph/config.toml`:
434
+ `.ctxgraph/config.toml` is auto-created by `ctx init`:
435
+
248
436
  ```toml
249
437
  [graph]
250
438
  exclude = ["legacy/*", "vendor/*"]
@@ -253,6 +441,7 @@ exclude = ["legacy/*", "vendor/*"]
253
441
  provider = "ollama" # ollama, claude, openai, azure, custom
254
442
  model = "qwen2.5-coder:7b"
255
443
  endpoint = "http://localhost:11434"
444
+ api_key = ""
256
445
 
257
446
  [context]
258
447
  mode = "balanced"
@@ -260,45 +449,46 @@ max_nodes = 20
260
449
  max_depth = 2
261
450
  ```
262
451
 
263
- | Environment Variable | Overrides |
264
- |----------------------|-----------|
265
- | `CTXGRAPH_PROVIDER` | `ai.provider` |
266
- | `CTXGRAPH_MODEL` | `ai.model` |
267
- | `CTXGRAPH_ENDPOINT` | `ai.endpoint` |
268
- | `ANTHROPIC_API_KEY` | Claude API |
269
- | `OPENAI_API_KEY` | OpenAI API |
270
- | `AZURE_OPENAI_API_KEY` | Azure OpenAI API |
452
+ ### Environment variables
453
+
454
+ | Variable | Overrides | Required For |
455
+ |----------|-----------|-------------|
456
+ | `CTXGRAPH_PROVIDER` | `ai.provider` | — |
457
+ | `CTXGRAPH_MODEL` | `ai.model` | |
458
+ | `CTXGRAPH_ENDPOINT` | `ai.endpoint` | |
459
+ | `ANTHROPIC_API_KEY` | `ai.api_key` | Claude provider |
460
+ | `OPENAI_API_KEY` | `ai.api_key` | OpenAI provider |
461
+ | `AZURE_OPENAI_API_KEY` | `ai.api_key` | Azure provider |
462
+
463
+ ### Provider examples
271
464
 
272
465
  ```bash
273
466
  # Ollama (default — no env vars needed)
274
- ctx capsule "query"
467
+ ctx ask "how does auth work"
275
468
 
276
469
  # Claude
277
- CTXGRAPH_PROVIDER=claude CTXGRAPH_MODEL=claude-sonnet-4-20250514 ctx capsule "query"
470
+ CTXGRAPH_PROVIDER=claude CTXGRAPH_MODEL=claude-sonnet-4-20250514 ctx ask "explain the architecture"
278
471
 
279
472
  # OpenAI
280
- CTXGRAPH_PROVIDER=openai CTXGRAPH_MODEL=gpt-4o ctx capsule "query"
473
+ CTXGRAPH_PROVIDER=openai CTXGRAPH_MODEL=gpt-4o ctx ask "find the bug"
281
474
 
282
475
  # Azure OpenAI
283
476
  CTXGRAPH_PROVIDER=azure \
284
477
  CTXGRAPH_MODEL=gpt-4o \
285
478
  CTXGRAPH_ENDPOINT=https://my-resource.openai.azure.com \
286
479
  AZURE_OPENAI_API_KEY=sk-... \
287
- ctx capsule "query"
480
+ ctx ask "refactor this"
288
481
 
289
482
  # Custom (OpenAI-compatible)
290
- CTXGRAPH_PROVIDER=custom CTXGRAPH_ENDPOINT=http://my-api/v1 ctx capsule "query"
483
+ CTXGRAPH_PROVIDER=custom CTXGRAPH_ENDPOINT=http://my-api/v1 ctx ask "explain"
484
+
485
+ # Per-command override (overrides both config and env vars)
486
+ ctx ask "how does this work" --provider claude --model claude-sonnet-4-20250514
291
487
  ```
292
488
 
293
489
  > **Windows (PowerShell):** Use `$env:` prefix instead:
294
490
  > ```powershell
295
- > $env:CTXGRAPH_PROVIDER = "azure"; $env:CTXGRAPH_MODEL = "gpt-4o"; ctx capsule "query"
296
- > ```
297
- > Or set them once per session:
298
- > ```powershell
299
- > $env:CTXGRAPH_PROVIDER = "azure"
300
- > $env:AZURE_OPENAI_API_KEY = "sk-..."
301
- > ctx capsule "query"
491
+ > $env:CTXGRAPH_PROVIDER = "azure"; $env:CTXGRAPH_MODEL = "gpt-4o"; ctx ask "query"
302
492
  > ```
303
493
 
304
494
  ---
@@ -306,6 +496,7 @@ CTXGRAPH_PROVIDER=custom CTXGRAPH_ENDPOINT=http://my-api/v1 ctx capsule "query"
306
496
  ## Use Cases
307
497
 
308
498
  ### Debug a failing test
499
+
309
500
  ```bash
310
501
  ctx build
311
502
  ctx capsule "test_user_login is failing with auth error" --mode deep
@@ -313,17 +504,35 @@ ctx capsule "test_user_login is failing with auth error" --mode deep
313
504
  # [F]src/auth/login.py
314
505
  # [C]AuthService
315
506
  # [DEP] auth/login.py → core/database.py, auth/session.py
507
+
508
+ # Or ask directly:
509
+ ctx ask "test_user_login is failing" --mode deep
510
+ # → Explains the issue with file references and suggests fixes
316
511
  ```
317
512
 
318
513
  ### Understand a new codebase
514
+
319
515
  ```bash
516
+ ctx build
320
517
  ctx capsule "project architecture" --overview
321
518
  ccg --chat "explain the overall architecture and data flow"
519
+
520
+ # Or explore with skills active:
521
+ ctx ask "explain the architecture" --skill field-guide
322
522
  ```
323
523
 
324
524
  ### Refactor across modules
525
+
325
526
  ```bash
326
527
  ctx capsule "extract payment processing into separate module" --mode deep
528
+ ctx ask "plan the payment module extraction" --skill project-style --mode deep
529
+ ```
530
+
531
+ ### Track your LLM usage
532
+
533
+ ```bash
534
+ ctx history --stats
535
+ # Shows total queries, tokens saved, avg savings, provider breakdown
327
536
  ```
328
537
 
329
538
  ---
@@ -371,6 +580,27 @@ for node, score in results:
371
580
 
372
581
  > **Tip:** `build_graph` is a one-time setup. In production, run `ctx build` during CI/deployment and let your app code only call `get_storage` + `render_capsule`.
373
582
 
583
+ ### Compose with skill context
584
+
585
+ ```python
586
+ from ctxgraph.skills import load_skill
587
+
588
+ storage = get_storage(Path("./my_project"))
589
+ skill_text = load_skill(Path("./my_project"), "project-style")
590
+ capsule = render_capsule(storage, "fix auth", max_nodes=20, skill_context=skill_text)
591
+ # Capsule now has "## Project Knowledge" section prepended
592
+ ```
593
+
594
+ ### Compute token savings
595
+
596
+ ```python
597
+ from ctxgraph.capsule.savings import compute_savings
598
+
599
+ savings = compute_savings(Path("./my_project"), capsule_text)
600
+ print(f"Saved {savings['savings_pct']}% tokens")
601
+ print(f"DSL is {savings['dsl_vs_json']}% more efficient than JSON")
602
+ ```
603
+
374
604
  ### LangChain
375
605
 
376
606
  Pass the capsule as context in your prompt template. The LLM gets exactly the files, classes, and dependencies it needs — no token waste.
@@ -379,13 +609,10 @@ Pass the capsule as context in your prompt template. The LLM gets exactly the fi
379
609
  from pathlib import Path
380
610
  from langchain_openai import ChatOpenAI
381
611
  from langchain_core.prompts import ChatPromptTemplate
382
- from ctxgraph.graph.builder import get_storage # graph already built
612
+ from ctxgraph.graph.builder import get_storage
383
613
  from ctxgraph.capsule.renderer import render_capsule
384
614
 
385
- # Load existing graph (zero build time)
386
615
  storage = get_storage(Path("./my_project"))
387
-
388
- # Generate capsule for the question
389
616
  context = render_capsule(storage, "login rate limiter", max_nodes=15)
390
617
 
391
618
  prompt = ChatPromptTemplate.from_messages([
@@ -400,13 +627,11 @@ print(response.invoke({
400
627
  "context": context,
401
628
  "question": "Where is the rate limiter applied in the login flow?",
402
629
  }))
403
- # → "The rate limiter is in src/auth/middleware.py at line 42.
404
- # It wraps the login endpoint with a 5req/min limit per IP."
405
630
  ```
406
631
 
407
632
  ### LangGraph
408
633
 
409
- Expose ctxgraph as a tool the agent calls on-demand. The agent fetches context only when it hits a code-related question.
634
+ Expose ctxgraph as a tool the agent calls on-demand.
410
635
 
411
636
  ```python
412
637
  from pathlib import Path
@@ -417,17 +642,13 @@ from langchain_core.tools import tool
417
642
  from ctxgraph.graph.builder import get_storage
418
643
  from ctxgraph.capsule.renderer import render_capsule
419
644
 
420
- # Pre-built graph — loaded instantly
421
645
  _storage = get_storage(Path("./my_project"))
422
646
 
423
647
  @tool
424
648
  def code_context(task: str) -> str:
425
- """Fetch relevant source code for a development task.
426
- Use this whenever the user asks about implementation details,
427
- bug fixes, or architecture in the codebase."""
649
+ """Fetch relevant source code for a development task."""
428
650
  return render_capsule(_storage, task, max_nodes=20)
429
651
 
430
- # --- Build LangGraph ---
431
652
  tools = [code_context]
432
653
  model = ChatOpenAI(model="gpt-4o", temperature=0).bind_tools(tools)
433
654
 
@@ -446,7 +667,6 @@ graph.add_edge("tools", "agent")
446
667
 
447
668
  app = graph.compile()
448
669
 
449
- # --- Run ---
450
670
  for chunk in app.stream({"messages": [("user", "How does payment retry work?")]}):
451
671
  for node, vals in chunk.items():
452
672
  msg = vals["messages"][0]
@@ -454,12 +674,8 @@ for chunk in app.stream({"messages": [("user", "How does payment retry work?")]}
454
674
  print(f"[{node}]: {msg.content[:300]}")
455
675
  ```
456
676
 
457
- When the user asks about code, the agent calls `code_context("payment retry")`, gets back a capsule with `[F]src/payment/retry.py`, `[F]src/payment/processor.py`, and their dependency edges, then answers with those files in context.
458
-
459
677
  ### OpenAI Agents SDK
460
678
 
461
- Same pattern — ctxgraph is a function tool the agent invokes.
462
-
463
679
  ```python
464
680
  from pathlib import Path
465
681
  from agents import Agent, Runner, function_tool
@@ -470,8 +686,7 @@ _storage = get_storage(Path("./my_project"))
470
686
 
471
687
  @function_tool
472
688
  def fetch_code_context(task_description: str) -> str:
473
- """Retrieve code context from the project's knowledge graph.
474
- Provide a task description like 'JWT auth middleware' or 'payment processor'."""
689
+ """Retrieve code context from the project's knowledge graph."""
475
690
  return render_capsule(_storage, task_description, max_nodes=20)
476
691
 
477
692
  agent = Agent(
@@ -487,8 +702,6 @@ print(result.final_output)
487
702
 
488
703
  ### Azure OpenAI (direct client)
489
704
 
490
- For Azure OpenAI or any OpenAI-compatible endpoint, inject the capsule directly into the system message.
491
-
492
705
  ```python
493
706
  import os
494
707
  from openai import AzureOpenAI
@@ -506,7 +719,7 @@ client = AzureOpenAI(
506
719
  )
507
720
 
508
721
  response = client.chat.completions.create(
509
- model="gpt-4o", # deployment name
722
+ model="gpt-4o",
510
723
  messages=[
511
724
  {"role": "system", "content": f"You are a senior developer. Code context:\n\n{context}"},
512
725
  {"role": "user", "content": "How do I add a new event handler?"},
@@ -523,33 +736,42 @@ print(response.choices[0].message.content)
523
736
  git clone https://github.com/shashi3070/ctxgraph.git
524
737
  cd ctxgraph
525
738
  pip install -e ".[dev]"
526
- pytest
739
+ pytest # 88+ tests
527
740
  python benchmarks/run_benchmarks.py
528
741
  python benchmarks/run_ollama_comparison.py # Requires local Ollama
529
742
  ```
530
743
 
531
744
  ### Project Structure
745
+
532
746
  ```
533
747
  src/ctxgraph/
534
- ├── cli/main.py — Typer CLI (6 commands)
748
+ ├── cli/main.py — Typer CLI (9 commands)
535
749
  ├── graph/
536
750
  │ ├── models.py — Node, Edge, Graph dataclasses
537
751
  │ ├── storage.py — SQLite persistence
538
752
  │ ├── builder.py — Graph build orchestrator
539
753
  │ └── query.py — Tokenizer + BFS + relevance scoring
540
- ├── capsule/renderer.py — DSL context generation
754
+ ├── capsule/
755
+ │ ├── renderer.py — DSL context generation
756
+ │ └── savings.py — Token savings computation
541
757
  ├── analyzers/python/
542
758
  │ ├── importer.py — AST import extraction
543
759
  │ ├── symbols.py — AST class/function/method analysis
544
760
  │ └── semantic.py — Docstring summarization
545
761
  ├── config/
762
+ │ ├── init.py — Project scaffold (.ctxgraph dir)
546
763
  │ ├── settings.py — TOML/JSON/env config loading
547
764
  │ └── providers.py — Ollama, Claude, OpenAI clients
548
765
  ├── clients/models.py — Mode enum (fast/balanced/deep)
549
766
  ├── exclude/patterns.py — Exclusion pattern matching
550
767
  ├── view/visualizer.py — D3.js HTML graph generator
551
768
  ├── wrapper/claude.py — ccg Claude wrapper
552
- └── mcp/server.py — MCP protocol server
769
+ ├── mcp/server.py — MCP protocol server
770
+ ├── skills/
771
+ │ ├── __init__.py — Skill discovery + loading
772
+ │ ├── project-style.toml — Default skill: project conventions
773
+ │ └── field-guide.toml — Default skill: field guide
774
+ └── history.py — JSONL history append/query/stats
553
775
  ```
554
776
 
555
777
  ---