cgh 0.3.0__py3-none-any.whl

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 (69) hide show
  1. cgh-0.3.0.dist-info/METADATA +1084 -0
  2. cgh-0.3.0.dist-info/RECORD +69 -0
  3. cgh-0.3.0.dist-info/WHEEL +5 -0
  4. cgh-0.3.0.dist-info/entry_points.txt +2 -0
  5. cgh-0.3.0.dist-info/licenses/LICENSE +56 -0
  6. cgh-0.3.0.dist-info/top_level.txt +1 -0
  7. codegraph/__init__.py +3 -0
  8. codegraph/__main__.py +414 -0
  9. codegraph/activity.py +75 -0
  10. codegraph/auth.py +120 -0
  11. codegraph/call_log.py +605 -0
  12. codegraph/cli/__init__.py +52 -0
  13. codegraph/cli/commands_federate.py +246 -0
  14. codegraph/cli/commands_graph.py +316 -0
  15. codegraph/cli/commands_index.py +336 -0
  16. codegraph/cli/commands_init.py +1042 -0
  17. codegraph/cli/commands_monitor.py +1433 -0
  18. codegraph/cli/commands_query.py +336 -0
  19. codegraph/config.py +378 -0
  20. codegraph/context_builder.py +494 -0
  21. codegraph/core/__init__.py +23 -0
  22. codegraph/core/db.py +131 -0
  23. codegraph/core/schema.py +162 -0
  24. codegraph/core/utils.py +63 -0
  25. codegraph/db.py +7 -0
  26. codegraph/dead_code.py +106 -0
  27. codegraph/endpoints.py +208 -0
  28. codegraph/federation.py +501 -0
  29. codegraph/fts.py +467 -0
  30. codegraph/indexer.py +1165 -0
  31. codegraph/ipc.py +355 -0
  32. codegraph/memory_index.py +140 -0
  33. codegraph/module_doc.py +202 -0
  34. codegraph/parsers/__init__.py +152 -0
  35. codegraph/parsers/base.py +167 -0
  36. codegraph/parsers/markdown.py +167 -0
  37. codegraph/parsers/plaintext.py +215 -0
  38. codegraph/parsers/python.py +196 -0
  39. codegraph/parsers/terraform.py +148 -0
  40. codegraph/parsers/typescript.py +190 -0
  41. codegraph/parsers/vue.py +543 -0
  42. codegraph/pattern.py +258 -0
  43. codegraph/pidfile.py +102 -0
  44. codegraph/plan_index.py +111 -0
  45. codegraph/post_commit.py +150 -0
  46. codegraph/roles.py +235 -0
  47. codegraph/scan_meta.py +180 -0
  48. codegraph/schema.py +6 -0
  49. codegraph/server/__init__.py +459 -0
  50. codegraph/server/tools_arch.py +226 -0
  51. codegraph/server/tools_docs.py +218 -0
  52. codegraph/server/tools_index.py +385 -0
  53. codegraph/server/tools_knowledge.py +198 -0
  54. codegraph/server/tools_memory.py +102 -0
  55. codegraph/server/tools_meta.py +274 -0
  56. codegraph/server/tools_plans.py +101 -0
  57. codegraph/server/tools_query.py +429 -0
  58. codegraph/server/tools_viz.py +484 -0
  59. codegraph/skill_installer.py +437 -0
  60. codegraph/skills/cgh-add-dir/SKILL.md +56 -0
  61. codegraph/skills/cgh-feature-plan/SKILL.md +82 -0
  62. codegraph/skills/cgh-record-knowledge/SKILL.md +108 -0
  63. codegraph/skills/cgh-scan-after-pull/SKILL.md +57 -0
  64. codegraph/skills/cgh-use-codegraph/SKILL.md +54 -0
  65. codegraph/skills/cgh-use-memory/SKILL.md +79 -0
  66. codegraph/viz/__init__.py +26 -0
  67. codegraph/viz/html.py +189 -0
  68. codegraph/viz/mermaid.py +224 -0
  69. codegraph/watcher.py +271 -0
@@ -0,0 +1,1084 @@
1
+ Metadata-Version: 2.4
2
+ Name: cgh
3
+ Version: 0.3.0
4
+ Summary: Local code graph for AI coding agents. Indexes your repo into Kuzu + SQLite FTS, exposes 30+ MCP tools to Claude Code, Cursor, Codex, and Gemini. Federates across sibling repos.
5
+ Author-email: Joy Ndjama <joy.ndjama@altikva.com>
6
+ Maintainer-email: ALTIKVA <dev@altikva.com>
7
+ License: ALTIKVA Dual License v1.0
8
+ =========================
9
+
10
+ Copyright (c) 2026 ALTIKVA
11
+
12
+ This software is dual-licensed under your choice of either:
13
+
14
+ - The MIT License (full text below), or
15
+ - The Creative Commons Attribution-NonCommercial-ShareAlike 4.0
16
+ International License (CC BY-NC-SA 4.0), full text at:
17
+ https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
18
+
19
+ The canonical version of this dual license notice is published at
20
+ https://www.altikva.com/licenses/LICENSE-1.0
21
+
22
+
23
+ ----------------------------------------------------------------------
24
+ MIT License
25
+ ----------------------------------------------------------------------
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ of this software and associated documentation files (the "Software"), to deal
29
+ in the Software without restriction, including without limitation the rights
30
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ copies of the Software, and to permit persons to whom the Software is
32
+ furnished to do so, subject to the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be included in all
35
+ copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43
+ SOFTWARE.
44
+
45
+
46
+ ----------------------------------------------------------------------
47
+ CC BY-NC-SA 4.0 (summary, not a substitute for the canonical text)
48
+ ----------------------------------------------------------------------
49
+
50
+ You are free to:
51
+ - Share: copy and redistribute the material in any medium or format
52
+ - Adapt: remix, transform, and build upon the material
53
+
54
+ Under the following terms:
55
+ - Attribution: you must give appropriate credit, provide a link to
56
+ the license, and indicate if changes were made.
57
+ - NonCommercial: you may not use the material for commercial purposes.
58
+ - ShareAlike: if you remix, transform, or build upon the material,
59
+ you must distribute your contributions under the same license.
60
+
61
+ Full legal text:
62
+ https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
63
+
64
+ Project-URL: Homepage, https://github.com/altikva/cgh
65
+ Project-URL: Repository, https://github.com/altikva/cgh
66
+ Project-URL: Issues, https://github.com/altikva/cgh/issues
67
+ Keywords: code-graph,mcp,mcp-server,claude,claude-code,cursor,code-index,symbol-lookup,call-graph,ai-agents
68
+ Classifier: Development Status :: 4 - Beta
69
+ Classifier: Environment :: Console
70
+ Classifier: Intended Audience :: Developers
71
+ Classifier: License :: OSI Approved :: MIT License
72
+ Classifier: License :: Free for non-commercial use
73
+ Classifier: Operating System :: OS Independent
74
+ Classifier: Programming Language :: Python :: 3
75
+ Classifier: Programming Language :: Python :: 3.11
76
+ Classifier: Programming Language :: Python :: 3.12
77
+ Classifier: Programming Language :: Python :: 3.13
78
+ Classifier: Topic :: Software Development :: Code Generators
79
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
80
+ Classifier: Typing :: Typed
81
+ Requires-Python: >=3.11
82
+ Description-Content-Type: text/markdown
83
+ License-File: LICENSE
84
+ Requires-Dist: kuzu>=0.7
85
+ Requires-Dist: tree-sitter>=0.23
86
+ Requires-Dist: tree-sitter-python>=0.23
87
+ Requires-Dist: tree-sitter-typescript>=0.23
88
+ Requires-Dist: watchdog>=4.0
89
+ Requires-Dist: fastmcp>=2.0
90
+ Requires-Dist: rank-bm25>=0.2
91
+ Requires-Dist: rich>=13.0
92
+ Requires-Dist: questionary>=2.0
93
+ Provides-Extra: rust
94
+ Requires-Dist: tree-sitter-rust>=0.23; extra == "rust"
95
+ Provides-Extra: go
96
+ Requires-Dist: tree-sitter-go>=0.23; extra == "go"
97
+ Provides-Extra: java
98
+ Requires-Dist: tree-sitter-java>=0.23; extra == "java"
99
+ Provides-Extra: all
100
+ Requires-Dist: cgh[go,java,rust]; extra == "all"
101
+ Dynamic: license-file
102
+
103
+ ```
104
+ ___ _ _
105
+ / __\___ __| | ___ __ _ _ __ __ _ _ __ | |__
106
+ / / / _ \ / _` |/ _ \/ _` | '__/ _` | '_ \| '_ \
107
+ / /__| (_) | (_| | __/ (_| | | | (_| | |_) | | | |
108
+ \____/\___/ \__,_|\___|\__, |_| \__,_| .__/|_| |_|
109
+ |___/ |_|
110
+ ```
111
+
112
+ **Local code graph index for AI coding assistants.**
113
+
114
+ Parses your repo into a graph of files, functions, classes, Terraform resources, and Markdown documentation -- then exposes it as an MCP server so Claude Code, Cursor, Codex, and Gemini can do symbol-level lookups instead of reading entire files.
115
+
116
+ **Result:** 60-90% fewer tokens on typical navigation tasks.
117
+
118
+ ---
119
+
120
+ ## Install
121
+
122
+ ```bash
123
+ git clone https://github.com/altikva/cgh.git
124
+ cd cgh
125
+
126
+ # pip
127
+ pip install -e .
128
+
129
+ # pipx (isolated install)
130
+ pipx install .
131
+
132
+ # uv
133
+ uv pip install -e .
134
+ uv tool install .
135
+ ```
136
+
137
+ Once installed, the `cgh` CLI is on your PATH:
138
+
139
+ ```bash
140
+ cgh --help
141
+ cgh init # initialize in any project
142
+ cgh serve # start the MCP server for Claude / Cursor / Codex / Gemini
143
+ ```
144
+
145
+ After install, both `codegraph` and `cgh` (short alias) are available:
146
+
147
+ ```bash
148
+ cgh --version
149
+ # codegraph 0.3.0
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Quick Start
155
+
156
+ ```bash
157
+ # 1. Initialize (interactive wizard)
158
+ cgh init
159
+
160
+ # 2. Build the graph
161
+ cgh index
162
+
163
+ # 3. Check what was indexed
164
+ cgh stats
165
+
166
+ # 4. Start the MCP server for your AI tool
167
+ cgh serve --watch --reindex
168
+ ```
169
+
170
+ ---
171
+
172
+ ## How It Works
173
+
174
+ ```
175
+ AI Assistant (Claude / Cursor / Codex / Gemini)
176
+ | symbol_lookup("process_data")
177
+ | search_docs("reconciliation")
178
+ | context_for_task("fix auth bug")
179
+ v
180
+ MCP server (codegraph) <-- stdio, no network
181
+ | Cypher query + BM25 FTS
182
+ v
183
+ Kuzu graph DB (.codegraph/graph.db) <-- embedded, file-based
184
+ SQLite FTS5 (.codegraph/fts.db) <-- BM25 full-text search
185
+ | indexed from
186
+ v
187
+ Your source files (.py / .ts / .tf / .md / .vue)
188
+ ^
189
+ File watcher (watchdog) <-- live incremental updates on save
190
+ ```
191
+
192
+ Instead of reading `services.py` (800 tokens) to find where `verify_token` is defined, your AI calls `symbol_lookup("verify_token")` and gets back:
193
+
194
+ ```json
195
+ {
196
+ "file": "src/auth/services.py",
197
+ "lines": "42-55",
198
+ "kind": "function",
199
+ "doc": "Verify a JWT token, raise on expiry."
200
+ }
201
+ ```
202
+
203
+ Then reads only lines 42-55.
204
+
205
+ ---
206
+
207
+ ## Architecture (v0.3)
208
+
209
+ ```
210
+ codegraph/
211
+ __init__.py # version only
212
+ __main__.py # thin argparse + dispatch (~260 lines)
213
+ config.py # layered TOML config
214
+ auth.py # MCP auth key management
215
+
216
+ core/ # shared utilities (single source of truth)
217
+ db.py # Kuzu connection manager
218
+ schema.py # graph DDL
219
+ utils.py # rows(), short_path(), safe_id(), lang_color()
220
+
221
+ parsers/ # plugin registry (auto-discovery)
222
+ base.py # BaseParser ABC + FileIndex dataclass
223
+ python.py, typescript.py, terraform.py, markdown.py, vue.py
224
+
225
+ server/ # MCP server (split from monolith)
226
+ __init__.py # FastMCP setup + main()
227
+ tools_query.py # symbol_lookup, callers, callees, imports, subgraph
228
+ tools_docs.py # search_docs, doc_outline, doc_refs
229
+ tools_index.py # scan_repo, index_changed, force_index
230
+ tools_viz.py # visualize_graph, graph_stats
231
+ tools_meta.py # fts_search, dead_code, context_for_task, call_stats
232
+
233
+ cli/ # Rich CLI (split from monolith)
234
+ commands_init.py # init, setup, parsers
235
+ commands_query.py # search, lookup, callers, callees, outline
236
+ commands_index.py # index, watch, serve, force-index
237
+ commands_monitor.py # stats, logs, history, diff, doctor, compact
238
+ commands_graph.py # graph, add-dir
239
+
240
+ viz/ # visualization
241
+ mermaid.py # Mermaid diagram generators
242
+ html.py # HTML template + browser open
243
+
244
+ indexer.py # parse + Kuzu ingestion engine
245
+ fts.py # BM25 full-text search (SQLite FTS5)
246
+ context_builder.py # AI context builder (graph + FTS)
247
+ dead_code.py # unused symbol detection
248
+
249
+ tests/ # 77 tests (pytest)
250
+ test_parsers/ # Python, TS, TF, Markdown
251
+ test_core/ # db, utils
252
+ test_indexer/ # engine, .cghignore
253
+ test_search/ # FTS
254
+ ```
255
+
256
+ ---
257
+
258
+ ## CLI Reference
259
+
260
+ `cgh` is a short alias for `codegraph`. All commands accept `--root <DIR>` to target a different project.
261
+
262
+ ### Getting Started
263
+
264
+ #### `init`
265
+
266
+ Interactive wizard that detects AI tools, installs MCP configs, and indexes the project.
267
+
268
+ ```bash
269
+ cgh init
270
+ cgh init --yes # accept all defaults (non-interactive)
271
+ ```
272
+
273
+ ```text
274
+ ___ _ _
275
+ / __\___ __| | ___ __ _ _ __ __ _ _ __ | |__
276
+ / / / _ \ / _` |/ _ \/ _` | '__/ _` | '_ \| '_ \
277
+ / /__| (_) | (_| | __/ (_| | | | (_| | |_) | | | |
278
+ \____/\___/ \__,_|\___|\__, |_| \__,_| .__/|_| |_|
279
+ |___/ |_|
280
+
281
+ Project: /home/user/my-project
282
+
283
+ Detecting AI tools...
284
+
285
+ > Claude Code detected
286
+ > Cursor detected
287
+ - Codex CLI not found
288
+ - Gemini CLI not found
289
+
290
+ ? Install MCP server for: (space to toggle, enter to confirm)
291
+ [x] Claude Code (MCP server + hooks)
292
+ [x] Cursor (MCP server + hooks)
293
+
294
+ + .mcp.json (MCP server)
295
+ + .claude/settings.json (post-commit hook)
296
+ + .cursor/mcp.json (MCP server)
297
+
298
+ Files to index:
299
+
300
+ python 142 files >>>>>>>>>>>>>>>>>>>>>>>>>>>>
301
+ typescript 8 files >>
302
+ terraform 12 files >>
303
+ markdown 23 files >>>>>
304
+
305
+ ? Index 185 files now? Yes
306
+
307
+ ...indexing...
308
+
309
+ +-----------------------+
310
+ | codegraph is ready! |
311
+ | |
312
+ | cgh stats |
313
+ | cgh search X |
314
+ | cgh serve |
315
+ | cgh parsers |
316
+ | cgh --help |
317
+ +-----------------------+
318
+ ```
319
+
320
+ #### `index`
321
+
322
+ Build or rebuild the full code graph. Uses `git ls-files` for file discovery.
323
+
324
+ ```bash
325
+ cgh index
326
+ cgh index --verbose
327
+ ```
328
+
329
+ ```text
330
+ Indexing (git ls-files) [################........] 142/185 api/handlers/donation_handler.py 3.2s
331
+
332
+ +--------------------+--------+
333
+ | Index Summary | |
334
+ +--------------------+--------+
335
+ | Files indexed | 185 |
336
+ | Files skipped | 3 |
337
+ | Errors | 0 |
338
+ | Elapsed | 4.1s |
339
+ | Method | git_ls |
340
+ +--------------------+--------+
341
+ ```
342
+
343
+ #### `serve`
344
+
345
+ Start the MCP server over stdio. This is the command AI tools invoke.
346
+
347
+ ```bash
348
+ cgh serve --root . --watch --reindex
349
+ ```
350
+
351
+ Flags:
352
+ - `--watch` -- enable live file watcher (watchdog, debounced)
353
+ - `--reindex` -- rebuild the graph before accepting connections
354
+
355
+ #### `setup`
356
+
357
+ Generate integration files for a specific AI tool without the interactive wizard.
358
+
359
+ ```bash
360
+ cgh setup claude
361
+ cgh setup cursor
362
+ cgh setup codex
363
+ cgh setup gemini
364
+ cgh setup all
365
+ ```
366
+
367
+ ### Query
368
+
369
+ #### `search`
370
+
371
+ Fuzzy search symbols (functions, classes, doc sections) by name.
372
+
373
+ ```bash
374
+ cgh search "Handler"
375
+ cgh search "Handler" --limit 5
376
+ cgh search "Handler" --json
377
+ ```
378
+
379
+ ```text
380
+ Search: Handler
381
+ +------+----------------------------+-------------------------------+
382
+ | Type | Symbol | Location |
383
+ +------+----------------------------+-------------------------------+
384
+ | fn | DonationHandler | api/handlers/donation.py:12 |
385
+ | fn | ReceiptHandler | api/handlers/receipt.py:8 |
386
+ | cls | BaseHandler | api/handlers/base.py:15 |
387
+ | fn | PaymentHandler | api/handlers/payment.py:22 |
388
+ +------+----------------------------+-------------------------------+
389
+ ```
390
+
391
+ #### `lookup`
392
+
393
+ Find the exact definition of a symbol.
394
+
395
+ ```bash
396
+ cgh lookup verify_token
397
+ ```
398
+
399
+ ```text
400
+ fn verify_token api/middleware/auth.py:42-55
401
+ ```
402
+
403
+ #### `callers`
404
+
405
+ Show all functions that call a given function (tree view).
406
+
407
+ ```bash
408
+ cgh callers verify_token
409
+ ```
410
+
411
+ ```text
412
+ verify_token is called by:
413
+ +-- get_current_user api/dependencies.py:18
414
+ +-- require_role api/middleware/auth.py:72
415
+ +-- portal_auth api/routers/portal.py:34
416
+ ```
417
+
418
+ #### `callees`
419
+
420
+ Show all functions that a given function calls (tree view).
421
+
422
+ ```bash
423
+ cgh callees get_current_user
424
+ ```
425
+
426
+ ```text
427
+ get_current_user calls:
428
+ +-- verify_token api/middleware/auth.py:42
429
+ +-- load_user_by_id api/managers/user_manager.py:15
430
+ +-- build_current_user api/dependencies.py:30
431
+ ```
432
+
433
+ #### `outline`
434
+
435
+ Display the heading structure of a Markdown file as a tree.
436
+
437
+ ```bash
438
+ cgh outline CLAUDE.md
439
+ cgh outline docs/ARCHITECTURE.md
440
+ ```
441
+
442
+ ```text
443
+ CLAUDE.md
444
+ +-- ondonne-api -- FastAPI Backend L1
445
+ | +-- Project overview L5
446
+ | +-- Tech stack L30
447
+ | +-- Architecture -- 4-layer request flow L45
448
+ | | +-- Entity registration (factory pattern) L52
449
+ | +-- Provider architecture (plugin system) L60
450
+ | | +-- Mobile Money provider architecture L85
451
+ | | +-- Payment routing strategy L110
452
+ | +-- Multi-tenancy model L200
453
+ | +-- User roles & access control (RBAC) L215
454
+ ```
455
+
456
+ #### `graph`
457
+
458
+ Visualize the code graph in the browser as interactive Mermaid diagrams.
459
+
460
+ ```bash
461
+ cgh graph # overview (default)
462
+ cgh graph imports # file import graph
463
+ cgh graph calls --symbol verify # call graph filtered to a symbol
464
+ cgh graph classes # class inheritance tree
465
+ cgh graph docs # documentation structure
466
+ cgh graph imports --file auth.py # imports for a specific file
467
+ cgh graph calls --mermaid # output raw Mermaid to stdout
468
+ cgh graph imports --html out.html # save to file instead of opening browser
469
+ cgh graph overview --max-nodes 20 # limit nodes
470
+ ```
471
+
472
+ Scopes: `overview`, `imports`, `calls`, `classes`, `docs`
473
+
474
+ ```text
475
+ +--------------------------------------------+
476
+ | codegraph |
477
+ | |
478
+ | Opened in browser |
479
+ | File: /tmp/codegraph/codegraph-calls.html|
480
+ | Scope: calls |
481
+ | Nodes: 40 max |
482
+ +--------------------------------------------+
483
+ ```
484
+
485
+ ### Monitor
486
+
487
+ #### `stats`
488
+
489
+ Display graph nodes, edges, MCP call stats, FTS index size, and storage.
490
+
491
+ ```bash
492
+ cgh stats
493
+ cgh stats --json
494
+ ```
495
+
496
+ ```text
497
+ Graph Nodes
498
+ Type Count
499
+ File 185 ##########..........
500
+ Function 1,204 ####################
501
+ Class 85 ####................
502
+ TFResource 14 #...................
503
+ TFVar 9 ...................
504
+ MdSection 230 ########............
505
+ Total 1,727
506
+
507
+ Graph Edges
508
+ Relationship Count
509
+ CALLS 3,412
510
+ IMPORTS 892
511
+ DEFINES_FN 1,204
512
+ DEFINES_CLASS 85
513
+ INHERITS 47
514
+ HAS_METHOD 312
515
+ DEFINES_SECTION 230
516
+ MD_REFS_SYMBOL 89
517
+ Total 6,271
518
+
519
+ Index Info
520
+ FTS symbols 1,533
521
+ graph.db 12.4 MB
522
+ fts.db 2.1 MB
523
+ call_log.db 48 KB
524
+ Total storage 14.5 MB
525
+
526
+ MCP Tool Calls
527
+ Tool Calls Avg ms Max ms Errors
528
+ context_for_task 42 18.3 45.2 0
529
+ symbol_lookup 38 2.1 8.4 0
530
+ search_symbols 15 3.5 12.1 0
531
+ fts_search 12 4.2 15.3 0
532
+ find_callers 8 1.8 4.2 0
533
+ Total 115 0
534
+ ```
535
+
536
+ #### `logs`
537
+
538
+ View MCP tool call history with latency and status.
539
+
540
+ ```bash
541
+ cgh logs
542
+ cgh logs --tool symbol_lookup
543
+ cgh logs --errors
544
+ cgh logs --limit 10
545
+ cgh logs --json
546
+ cgh logs --clear
547
+ ```
548
+
549
+ ```text
550
+ Call Logs (last 10)
551
+ Time Tool Latency Size Args
552
+ 2026-04-11 14:32:01 OK symbol_lookup 2.1ms 142B name=verify_token
553
+ 2026-04-11 14:31:58 OK context_for_task 18ms 1,204B task=fix auth bug
554
+ 2026-04-11 14:31:45 OK fts_search 4.2ms 892B query=donation handler
555
+ 2026-04-11 14:30:12 ERR find_callers 1.2ms 0B fn_name=nonexistent
556
+ ```
557
+
558
+ #### `history`
559
+
560
+ Show recent MCP activity grouped by day.
561
+
562
+ ```bash
563
+ cgh history
564
+ cgh history --days 14
565
+ ```
566
+
567
+ ```text
568
+ Activity -- Last 7 Day(s)
569
+ Date Calls Errors Top Tools
570
+ 2026-04-11 42 0 context_for_task(18), symbol_lookup(12), fts_search(8)
571
+ 2026-04-10 31 1 symbol_lookup(15), find_callers(8), search_docs(5)
572
+ 2026-04-09 28 0 context_for_task(12), search_symbols(9), graph_stats(4)
573
+
574
+ Total: 101 calls, 1 errors across 3 day(s)
575
+ ```
576
+
577
+ #### `diff`
578
+
579
+ Show files changed since the last index, categorized by parseability.
580
+
581
+ ```bash
582
+ cgh diff
583
+ cgh diff --since HEAD~3
584
+ cgh diff --since main
585
+ ```
586
+
587
+ ```text
588
+ Changed Files (parseable) since HEAD
589
+ File Language
590
+ api/routers/donations.py .py
591
+ api/handlers/receipt_handler.py .py
592
+ CLAUDE.md .md
593
+
594
+ + 2 non-parseable changed file(s)
595
+
596
+ +----------------------------------------------+
597
+ | 3 parseable changed | 0 new unindexed | 2 other |
598
+ +----------------------------------------------+
599
+ ```
600
+
601
+ #### `parsers`
602
+
603
+ List all registered language parsers.
604
+
605
+ ```bash
606
+ cgh parsers
607
+ ```
608
+
609
+ ```text
610
+ Registered Parsers
611
+ Language Extensions Extracts Description
612
+ python .py functions, classes, imports Python source files (tree-sitter)
613
+ typescript .ts .tsx .js .mjs functions, classes, imports TypeScript/JavaScript (tree-sitter)
614
+ terraform .tf resources, variables, outputs Terraform HCL files
615
+ markdown .md .mdx sections, links, code_refs Markdown documentation
616
+ vue .vue functions, classes, imports Vue SFC files
617
+
618
+ Total: 9 file extensions supported
619
+ ```
620
+
621
+ ### Maintenance
622
+
623
+ #### `doctor`
624
+
625
+ Health check that verifies all codegraph components are working.
626
+
627
+ ```bash
628
+ cgh doctor
629
+ ```
630
+
631
+ ```text
632
+ Health Check
633
+ Component Status
634
+ .codegraph/ dir OK initialized
635
+ graph.db OK accessible
636
+ fts.db OK accessible
637
+ call_log.db OK accessible
638
+ config.toml OK valid
639
+ parsers OK 5 parser(s) loaded
640
+ git OK found
641
+ .cghignore !! not found (optional)
642
+ MCP server OK ready
643
+
644
+ +-----------------------------+
645
+ | All 9 checks passed. |
646
+ +-----------------------------+
647
+ ```
648
+
649
+ #### `compact`
650
+
651
+ Vacuum SQLite databases and reclaim disk space.
652
+
653
+ ```bash
654
+ cgh compact
655
+ ```
656
+
657
+ ```text
658
+ Compact Results
659
+ Database Before After Saved
660
+ fts.db 2.3 MB 2.1 MB -200 KB
661
+ call_log.db 52 KB 48 KB -4 KB
662
+ graph.db (Kuzu) 12.4 MB -- N/A
663
+
664
+ +----------------------------------+
665
+ | Reclaimed: 204 KB |
666
+ +----------------------------------+
667
+ ```
668
+
669
+ ### Advanced
670
+
671
+ #### `watch`
672
+
673
+ Index the repo then watch for file changes indefinitely.
674
+
675
+ ```bash
676
+ cgh watch
677
+ cgh watch --verbose
678
+ ```
679
+
680
+ ```text
681
+ Initial index done -- 185 files in 4.1s
682
+ Watching for changes... (Ctrl-C to stop)
683
+ ```
684
+
685
+ #### `add-dir`
686
+
687
+ Manage extra directories included in the graph (multi-repo support).
688
+
689
+ ```bash
690
+ cgh add-dir list # list configured extra dirs
691
+ cgh add-dir add ../frontend # add a directory
692
+ cgh add-dir add ../infra # add another
693
+ cgh add-dir remove ../frontend # remove a directory
694
+ ```
695
+
696
+ ```text
697
+ Extra directories:
698
+
699
+ OK ../ondonne-frontend (/home/user/ondonne-frontend)
700
+ OK ../ondonne-infra (/home/user/ondonne-infra)
701
+ ```
702
+
703
+ #### `federate`
704
+
705
+ Federate sub-repos that each have their own `.codegraph/` index. The parent indexes only files outside any subrepo and queries fan out to each child's read-only DB at runtime. Each result is tagged with a `scope` field (`parent` or the child's name). See the [Federation](#federation) section for the full model.
706
+
707
+ ```bash
708
+ cgh federate add ./apps/api ./apps/web # declare subrepos
709
+ cgh federate list # status table (status, owner, git, path)
710
+ cgh federate verify # exits 1 if any child is unhealthy
711
+ cgh federate up # spawn each child's own watcher
712
+ cgh federate down # stop them all
713
+ cgh federate remove ./apps/api # un-federate
714
+ ```
715
+
716
+ ```text
717
+ +------------------+--------+-----------+-----+------------------+
718
+ | subrepo | status | owner | git | path |
719
+ +------------------+--------+-----------+-----+------------------+
720
+ | ondonne-frontend | ok | up :54052 | yes | ./ondonne-frontend |
721
+ | ondonne-infra | ok | down | yes | ./ondonne-infra |
722
+ +------------------+--------+-----------+-----+------------------+
723
+ ```
724
+
725
+ `cgh init` auto-detects nested `.codegraph/` directories and offers to federate them on the spot.
726
+
727
+ #### `force-index`
728
+
729
+ Index files that are in `.gitignore`, bypassing all ignore rules. Requires confirmation.
730
+
731
+ ```bash
732
+ cgh force-index build/output.py docs/generated/
733
+ cgh force-index build/output.py --yes # skip confirmation
734
+ ```
735
+
736
+ ```text
737
+ +-----------------------------------+
738
+ | Force Index |
739
+ | |
740
+ | build/output.py |
741
+ | docs/generated/ |
742
+ | |
743
+ | Bypasses .gitignore and |
744
+ | .git/info/exclude |
745
+ +-----------------------------------+
746
+ Continue? [y/N] y
747
+
748
+ Force-indexed 4 file(s)
749
+ ```
750
+
751
+ ---
752
+
753
+ ## Federation
754
+
755
+ When you work in a parent folder that holds several sub-projects, each with its own `.git` and its own `.codegraph/` index, you don't want the parent to re-index everything. Per-child `.gitignore` semantics get lost, large trees (node_modules, vendor) get walked, duplicate work explodes. The federation model fixes this:
756
+
757
+ - The parent **only indexes files outside any declared subrepo** (its README, top-level configs, cross-repo docs).
758
+ - Each subrepo keeps its own `.codegraph/` as the canonical index for its own code.
759
+ - At MCP query time, the parent **fans out read-only queries** to each child's DB and aggregates results, tagging every hit with a `scope` field (`parent` or the child's basename).
760
+
761
+ ### Setup
762
+
763
+ ```bash
764
+ # In each subrepo (one-time)
765
+ cd apps/api && cgh init && cgh index
766
+
767
+ # In the parent
768
+ cd ../..
769
+ cgh init # auto-detects nested .codegraph/, offers to federate
770
+ cgh federate add ./apps/api ./apps/web # (or declare manually)
771
+ cgh federate list # status + owner state per child
772
+ cgh index # parent indexes only its own files
773
+ cgh serve --background --watch # parent owner federates queries to children
774
+ cgh federate up # optional: spawn each child's own watcher so their indexes stay live
775
+ ```
776
+
777
+ ### What's federated
778
+
779
+ | MCP tool | Behavior |
780
+ |---|---|
781
+ | `symbol_lookup`, `search_symbols`, `find_callers`, `find_callees` | Concat results, each tagged with `scope` |
782
+ | `imports_of`, `subgraph` | Concat. Cross-repo IMPORTS edges are NOT inferred (each scope's graph is canonical for its own files) |
783
+ | `pattern_search` | Runs ripgrep in each scope's tree |
784
+ | `fts_search` | Concat then sort by score (BM25 not renormalized across repos) |
785
+ | `search_docs`, `doc_outline`, `doc_refs` | Concat |
786
+ | `architecture_overview` | Returns `{by_scope: {parent: {...}, child1: {...}}}` when subrepos are present |
787
+ | `domain_map`, `endpoints` | Concat with per-result scope tag |
788
+ | `find_dead_code` | **Per-scope analysis**. A symbol "dead" in scope X may be called from scope Y. The response carries an explicit `note` field reminding you not to delete blindly. |
789
+
790
+ ### What's NOT federated
791
+
792
+ `knowledge_*`, `memory_*`, `plan_*`, all write-side tools (`index`, `force_index`, `incremental_reindex`, `add_directory`), and `context_for_task` stay parent-local. Each project keeps its own knowledge / memory / plans store.
793
+
794
+ ### Resilience
795
+
796
+ If a child's DB is locked or unavailable (its own owner is mid-write, the child got deleted from disk), the response carries `partial: true` and `warnings: [{scope, error}]`. Results from other scopes still flow. Re-query in a moment if you need full coverage.
797
+
798
+ Owners are independent: the parent reads child DBs directly as files, it does NOT auto-spawn child owners. Use `cgh federate up` to ensure every child has its own watcher running, or accept that a child without a live owner may serve slightly stale data.
799
+
800
+ ---
801
+
802
+ ## MCP Tools
803
+
804
+ When running as an MCP server (`cgh serve`), codegraph exposes 23 tools.
805
+
806
+ ### Architecture Awareness (call these FIRST)
807
+
808
+ | Tool | Description |
809
+ |------|-------------|
810
+ | `architecture_overview(max_files_per_role?)` | Compact map of all files grouped by layer (presentation/application/domain/infra/test/doc) and role (handler/router/component/store/…) with 1-line summaries — no Read needed |
811
+ | `domain_map(keyword, limit_per_role?)` | Every file whose path / role / module_doc mentions the keyword, grouped by role |
812
+ | `endpoints(path_pattern?, method?)` | List HTTP endpoints (FastAPI decorators + Nuxt server/api file routes + Express) with their handlers — works cross-repo when `extra_dirs` is configured |
813
+
814
+ ### Code Navigation
815
+
816
+ | Tool | Description |
817
+ |------|-------------|
818
+ | `symbol_lookup(name)` | Find where a function, class, TF resource, or doc section is defined |
819
+ | `find_callers(fn_name)` | Find all functions that call `fn_name` |
820
+ | `find_callees(fn_name)` | Find all functions that `fn_name` calls |
821
+ | `imports_of(file_path)` | List modules imported by a file |
822
+ | `search_symbols(query, limit?)` | Fuzzy search across all symbol types |
823
+ | `subgraph(file_path, depth?)` | Find files related within N import hops (blast radius) |
824
+ | `graph_stats()` | Node and edge counts per type |
825
+
826
+ ### Documentation
827
+
828
+ | Tool | Description |
829
+ |------|-------------|
830
+ | `search_docs(query, limit?)` | Search Markdown by heading title or body content |
831
+ | `doc_outline(file_path)` | Table of contents of a Markdown file |
832
+ | `doc_refs(symbol_name)` | Find all docs that reference a code symbol |
833
+
834
+ ### Full-Text & AI Context
835
+
836
+ | Tool | Description |
837
+ |------|-------------|
838
+ | `fts_search(query, limit?, kind?)` | BM25-ranked full-text search over names + docstrings |
839
+ | `context_for_task(task, max_nodes?)` | Build ranked context from graph + FTS for any task |
840
+ | `find_dead_code(file_path?, include_private?)` | Find symbols with no incoming edges (potentially unused) |
841
+
842
+ ### Indexing
843
+
844
+ | Tool | Description |
845
+ |------|-------------|
846
+ | `scan_repo(verbose?)` | Full re-index of the entire repo |
847
+ | `index_changed_files(since?)` | Re-index only files changed since a git ref |
848
+ | `force_index(paths, confirmed?)` | Index files bypassing .gitignore (requires confirmation) |
849
+
850
+ ### Visualization
851
+
852
+ | Tool | Description |
853
+ |------|-------------|
854
+ | `visualize_graph(scope, file_path?, symbol_name?, max_nodes?, format?)` | Generate Mermaid or Graphviz diagrams |
855
+
856
+ ### Statistics
857
+
858
+ | Tool | Description |
859
+ |------|-------------|
860
+ | `call_stats()` | MCP tool usage statistics (calls, latency, errors) |
861
+ | `live_graph_stats()` | Polling-friendly snapshot: node counts + FTS size + scan freshness + timestamp |
862
+
863
+ ### Scan Freshness & Incremental Updates
864
+
865
+ | Tool | Description |
866
+ |------|-------------|
867
+ | `scan_status()` | Is the graph in sync with `git HEAD`? Returns `fresh`, `indexed_sha`, `behind_by`, `changed_files` |
868
+ | `incremental_reindex()` | Surgical reindex — compares per-file git blob SHAs and touches only what actually changed since the last scan |
869
+ | `add_directory(path)` | Hot-add an external directory (sibling repo) to the graph — persists to config, scans, extends the watcher. No restart needed. |
870
+
871
+ ---
872
+
873
+ ## Parser Plugin Architecture
874
+
875
+ codegraph supports any language through a plugin system. Adding a new language requires one file and zero configuration changes.
876
+
877
+ ### Supported Languages
878
+
879
+ | Language | Parser | Extensions | Extracts |
880
+ |----------|--------|------------|----------|
881
+ | Python | tree-sitter | `.py` | functions, classes, imports, calls, inheritance, docstrings |
882
+ | TypeScript | tree-sitter | `.ts` `.tsx` | functions, classes, imports, calls, inheritance |
883
+ | JavaScript | tree-sitter | `.js` `.mjs` | functions, classes, imports, calls |
884
+ | Vue | tree-sitter | `.vue` | functions, classes, imports (SFC script block) |
885
+ | Terraform | regex + brace tracker | `.tf` | resources, variables, outputs, depends_on |
886
+ | Markdown | regex | `.md` `.mdx` | headings, internal links, code symbol references |
887
+
888
+ ### Adding a New Language
889
+
890
+ 1. Create a file in `codegraph/parsers/` (e.g., `rust.py`)
891
+ 2. Subclass `BaseParser`
892
+ 3. Decorate with `@register_parser`
893
+ 4. Done -- auto-discovered on import
894
+
895
+ ```python
896
+ from codegraph.parsers import register_parser
897
+ from codegraph.parsers.base import BaseParser, FileIndex, SymbolDef, ClassDef, ImportRef
898
+
899
+ @register_parser(".rs")
900
+ class RustParser(BaseParser):
901
+ lang = "rust"
902
+ extensions = [".rs"]
903
+ extracts = ["functions", "structs", "traits", "impls"]
904
+ description = "Rust source files"
905
+ tree_sitter_lang = "rust" # optional: auto-installs grammar
906
+
907
+ def parse(self, path: Path) -> FileIndex:
908
+ # Parse the file and return a FileIndex
909
+ ...
910
+ ```
911
+
912
+ See `docs/PARSERS.md` for a complete walkthrough.
913
+
914
+ ---
915
+
916
+ ## Configuration
917
+
918
+ codegraph uses a layered config system. See `docs/CONFIGURATION.md` for all options.
919
+
920
+ ### Resolution Order (later wins)
921
+
922
+ 1. Hardcoded defaults
923
+ 2. Global: `~/.codegraph/config.toml`
924
+ 3. Project: `.codegraph/config.toml`
925
+ 4. Environment variables
926
+ 5. CLI flags
927
+
928
+ ### Quick Reference
929
+
930
+ ```toml
931
+ # .codegraph/config.toml
932
+
933
+ [codegraph]
934
+ ignore_dirs = [".git", "node_modules", "__pycache__", ".venv"]
935
+ ignore_patterns = ["*.min.js", "*.bundle.js"]
936
+ max_file_size_kb = 500
937
+ extra_dirs = ["../frontend"]
938
+
939
+ [parsers]
940
+ # enabled = ["python", "typescript", "markdown"]
941
+ # disabled = ["terraform"]
942
+
943
+ [mcp]
944
+ auto_watch = true
945
+ reindex_on_start = true
946
+ ```
947
+
948
+ ### Environment Variables
949
+
950
+ | Variable | Description |
951
+ |----------|-------------|
952
+ | `CODEGRAPH_ROOT` | Override project root |
953
+ | `CODEGRAPH_DIR` | Override `.codegraph/` location |
954
+ | `CODEGRAPH_AUTH_KEY` | MCP server auth key (auto-generated by `cgh init`, injected into `.mcp.json`) |
955
+
956
+ ### `.cghignore`
957
+
958
+ Optional file at the project root. Same syntax as `.gitignore`. Patterns listed here are excluded from indexing in addition to `.gitignore`.
959
+
960
+ ---
961
+
962
+ ## Integration Guides
963
+
964
+ ### Claude Code
965
+
966
+ Add to `.mcp.json` (auto-generated by `cgh init`):
967
+ ```json
968
+ {
969
+ "mcpServers": {
970
+ "codegraph": {
971
+ "command": "codegraph",
972
+ "args": ["serve", "--root", ".", "--watch", "--reindex"],
973
+ "env": {
974
+ "CODEGRAPH_AUTH_KEY": "<auto-generated key from .codegraph/auth.key>"
975
+ }
976
+ }
977
+ }
978
+ }
979
+ ```
980
+
981
+ See `integrations/claude-code.md` for hooks setup and best practices.
982
+
983
+ ### Cursor
984
+
985
+ Add to `.cursor/mcp.json`:
986
+ ```json
987
+ {
988
+ "mcpServers": {
989
+ "codegraph": {
990
+ "command": "codegraph",
991
+ "args": ["serve", "--root", ".", "--watch", "--reindex"],
992
+ "env": {
993
+ "CODEGRAPH_AUTH_KEY": "<auto-generated key from .codegraph/auth.key>"
994
+ }
995
+ }
996
+ }
997
+ }
998
+ ```
999
+
1000
+ See `integrations/cursor.md` for `.cursorrules` instructions.
1001
+
1002
+ ### Codex CLI
1003
+
1004
+ See `integrations/codex.md` for `AGENTS.md` instructions.
1005
+
1006
+ ### Gemini CLI
1007
+
1008
+ See `integrations/gemini.md` for `GEMINI.md` instructions.
1009
+
1010
+ ### Automatic Setup
1011
+
1012
+ ```bash
1013
+ cgh init # interactive: detects tools, installs configs
1014
+ cgh setup all # non-interactive: generates all integration files
1015
+ ```
1016
+
1017
+ ---
1018
+
1019
+ ## Graph Schema
1020
+
1021
+ ```
1022
+ File --IMPORTS-----------> File
1023
+ File --DEFINES_FN--------> Function
1024
+ File --DEFINES_CLASS-----> Class
1025
+ File --DEFINES_RESOURCE--> TFResource
1026
+ File --DEFINES_TFVAR-----> TFVar
1027
+ File --DEFINES_SECTION---> MdSection
1028
+
1029
+ Function --CALLS---------> Function
1030
+ Class --HAS_METHOD-------> Function
1031
+ Class --INHERITS---------> Class
1032
+ TFResource --TF_DEPENDS--> TFResource
1033
+
1034
+ MdSection --CONTAINS_SECTION--> MdSection (heading hierarchy)
1035
+ MdSection --MD_LINKS_TO-------> File (internal doc links)
1036
+ MdSection --MD_REFS_SYMBOL----> Function (code references in docs)
1037
+ MdSection --MD_REFS_CLASS-----> Class (code references in docs)
1038
+ ```
1039
+
1040
+ ---
1041
+
1042
+ ## Token Savings
1043
+
1044
+ | Task | Without codegraph | With codegraph |
1045
+ |------|-------------------|----------------|
1046
+ | Find where `process_data` is defined | Read 3-5 files (~2,000 tokens) | `symbol_lookup` (< 50 tokens) |
1047
+ | Find all callers of `save_record` | Read every candidate file | `find_callers` (< 50 tokens) |
1048
+ | Understand blast radius of `utils.py` | Read imports manually | `subgraph` (< 100 tokens) |
1049
+ | Find docs about reconciliation | Read all `.md` files | `search_docs` (< 50 tokens) |
1050
+ | Build context for a task | 5-10 file reads (~5,000 tokens) | `context_for_task` (< 200 tokens) |
1051
+
1052
+ ---
1053
+
1054
+ ## Security
1055
+
1056
+ ### MCP Auth Key
1057
+
1058
+ `cgh init` generates a cryptographic auth key at `.codegraph/auth.key` (auto-added to `.gitignore`). The key is injected into `.mcp.json` as the `CODEGRAPH_AUTH_KEY` environment variable.
1059
+
1060
+ This is defense-in-depth for when codegraph moves to HTTP transport. Over stdio, the key provides process-level authentication.
1061
+
1062
+ ```bash
1063
+ # Key is auto-managed -- no manual steps needed
1064
+ cgh init # generates key + injects into .mcp.json
1065
+ cgh setup claude # injects key into .mcp.json for Claude Code
1066
+ ```
1067
+
1068
+ The key file has `600` permissions (owner-only read/write). Never commit it to git.
1069
+
1070
+ ---
1071
+
1072
+ ## Limitations
1073
+
1074
+ - **CALLS resolution is name-based** -- if two functions share a name, both get edges. Fully qualified resolution requires type inference (out of scope).
1075
+ - **Terraform HCL** uses regex, not a proper grammar -- complex meta-arguments may be missed.
1076
+ - **No JavaScript module resolution** -- `import x from "./utils"` does not create a `File->File` IMPORTS edge yet.
1077
+ - **Markdown code refs are heuristic** -- PascalCase and snake_case patterns are matched, but may produce false positives.
1078
+ - **Large repos (10,000+ files)** -- initial index may take 5-10 min. Incremental updates stay fast (< 1s per file).
1079
+
1080
+ ---
1081
+
1082
+ ## License
1083
+
1084
+ Dual-licensed under your choice of MIT or CC BY-NC-SA 4.0. Copyright (c) 2026 ALTIKVA. See [LICENSE](./LICENSE) or the canonical notice at https://www.altikva.com/licenses/LICENSE-1.0.