Metadata-Version: 2.4
Name: cgh
Version: 0.19.0
Summary: cgh, the context graph hub: the project memory of your coding agents, plus a code and document graph. Indexes your repo into an embedded graph DB (DuckDB by default, SQLite in the standalone binary) plus SQLite FTS, exposes 62 MCP tools to Claude Code, Codex, Cursor, Gemini and IBM Bob. Federates across sibling repos.
Author-email: Joy Ndjama <joy.ndjama@altikva.com>
Maintainer-email: ALTIKVA <dev@altikva.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/altikva/cgh
Project-URL: Repository, https://github.com/altikva/cgh
Project-URL: Issues, https://github.com/altikva/cgh/issues
Project-URL: Changelog, https://github.com/altikva/cgh/blob/main/CHANGELOG.md
Keywords: context-graph,code-graph,mcp,mcp-server,claude,claude-code,cursor,code-index,symbol-lookup,call-graph,ai-agents,agents,memory,agent-memory,context,knowledge-graph,token-optimization,python,typescript,javascript,java,go,rust,vue,markdown
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: duckdb>=1.2
Requires-Dist: tree-sitter>=0.23
Requires-Dist: tree-sitter-python>=0.23
Requires-Dist: tree-sitter-typescript>=0.23
Requires-Dist: tree-sitter-go>=0.23
Requires-Dist: tree-sitter-rust>=0.23
Requires-Dist: tree-sitter-java>=0.23
Requires-Dist: watchdog>=4.0
Requires-Dist: fastmcp<5,>=2.13
Requires-Dist: rank-bm25>=0.2
Requires-Dist: rich>=13.0
Requires-Dist: questionary>=2.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: tree-sitter-hcl>=1.2
Requires-Dist: pypdf>=6.0
Requires-Dist: python-docx>=1.1
Requires-Dist: openpyxl>=3.1
Requires-Dist: python-pptx>=1.0
Provides-Extra: plugins
Requires-Dist: cgh-bugreport>=0.1.3; extra == "plugins"
Requires-Dist: cgh-codegen>=0.1.2; extra == "plugins"
Provides-Extra: full
Requires-Dist: cgh-bugreport>=0.1.3; extra == "full"
Requires-Dist: cgh-codegen>=0.1.2; extra == "full"
Requires-Dist: tree-sitter-c-sharp>=0.23; extra == "full"
Requires-Dist: tree-sitter-ruby>=0.23; extra == "full"
Requires-Dist: jedi>=0.19; extra == "full"
Provides-Extra: langs
Requires-Dist: tree-sitter-c-sharp>=0.23; extra == "langs"
Requires-Dist: tree-sitter-ruby>=0.23; extra == "langs"
Provides-Extra: lsp
Requires-Dist: jedi>=0.19; extra == "lsp"
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/altikva/cgh/main/assets/img/cgh-cli.svg" alt="The cgh CLI landing screen: banner, command list, and examples" width="820">
</p>

<p align="center">
  <a href="https://pypi.org/project/cgh/"><img src="https://img.shields.io/pypi/v/cgh?color=3775A9&label=PyPI" alt="PyPI version"></a>
  <a href="https://pypi.org/project/cgh/"><img src="https://img.shields.io/pypi/pyversions/cgh" alt="Python versions"></a>
  <a href="https://www.npmjs.com/package/@altikva/cgh"><img src="https://img.shields.io/npm/v/%40altikva%2Fcgh?color=CB3837&label=npx" alt="npx"></a>
  <a href="https://github.com/altikva/cgh/actions/workflows/ci.yml"><img src="https://github.com/altikva/cgh/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-3DA639" alt="License: Apache-2.0"></a>
</p>

**cgh, the context graph hub: the project memory of your coding agents.**

cgh is not a coding agent. It is an MCP server and a CLI that the agent you already use plugs into: Claude Code, Codex, Cursor, Gemini or IBM Bob. It keeps what those agents learn about a project, and it answers their questions about the code from a graph, so they find the code in fewer turns and pick up where the last session stopped.

- **Shared project memory.** Knowledge, decisions, gotchas and session digests are stored per repo, with where each one came from (session, branch, commit, PR, files). Every connected agent reads the same store, it survives a `/clear` or a compaction, and it can be exported to another repo.
- **A code and document graph.** Files, functions, classes, calls, imports, Terraform resources and Markdown sections are indexed locally. Lookups return an exact `file:line`, so the agent reads those lines instead of whole files. Sibling repos can be federated into one view.
- **Faster navigation and continuity.** Fewer turns and fewer tokens per code question, measured below, and a resume bundle that hands the next session the standing instructions, recent digests and open plans.
- **Gates on what leaves the machine.** Scanner findings (PII, secrets, confidentiality labels) are recorded in the graph, and plugins check them before a file goes to a cloud model.

**Result:** code questions answered in fewer turns and fewer tokens, learnings that survive context clears, and nothing leaving the machine without a gate. On a whole ticket the bill stays the same: both figures are below.

```bash
pip install cgh && cgh init && cgh serve
```

---

## Why cgh: the measured gains

cgh answers code questions from the graph, returning exact `file:line`, instead of the agent reading whole files or grepping. Two benchmarks measure what that buys, at two scales. Both compare cost only across runs that every arm got right, so a cheap wrong answer never reads as a saving.

**Per code question: fewer turns, fewer tokens.** A two-arm benchmark asks the same navigation questions (where is X defined, who calls Y, what breaks if Z changes) twice against the same repo, once with cgh and once with Read/Grep only, over five runs of 5 to 8 tasks:

| | with cgh, against Read/Grep only |
|---|---|
| turns | 18 to 40% fewer |
| wall time | 19 to 36% faster |
| billed tokens, cache included | 12 to 31% fewer in four runs, 5% more in one |
| non-cached tokens (input and output, under 1% of the bill) | 33 to 61% fewer |
| correct answers | unchanged (all correct in both arms) |

The gap is widest on multi-file questions, where a graph beats text search. For "what breaks if I change `_backend`?", the agent has to follow call edges across a module:

| | turns | non-cached tokens |
|---|---|---|
| Read / Grep | 13 | 2607 |
| cgh | 6 | 886 |

That question is one command:

<p align="center">
  <img src="https://raw.githubusercontent.com/altikva/cgh/main/assets/img/cgh-callers.svg" alt="cgh callers: the call graph of resolve_import rendered as a tree with exact file and line" width="820">
</p>

**Per ticket: the same bill, a faster agent.** A second benchmark replays already-merged tickets (API, front end, a Python service) from their parent commit: 78 runs, up to three per ticket and setup, judged blind against the merged pull request, with CI required. There, navigation is a small part of the work, and the per-question saving does not show in dollars:

| | Claude Code alone, cgh as installed, cgh with a full ticket setup |
|---|---|
| cost per ticket, every token type priced | the same: all three within x0.96 to x1.04 of each other |
| quality (blind judge, CI, the merged PR's own tests) | the same, within the run-to-run noise |
| wall time | about 2x faster with the full ticket setup, which hands the agent the file locations at the start and routes its searches to cgh. That setup is not yet part of `cgh init` |

So cgh makes finding code cheaper and quicker, and with the full ticket setup a ticket quicker, but not cheaper. Large token savings claimed for code graphs measure a single question against reading raw files, not a full piece of work.

**Delegating writes.** The [`cgh-codegen`](plugins/cgh-codegen) plugin does the same for writes: predictable, pattern-following code (tests, stubs, config, boilerplate) is handed to a cheap or local model that mirrors an existing file, and the reference never enters the primary model's context. cgh picks the file to mirror from the graph, so selecting it costs zero model tokens.

| task | reference size | primary-model tokens (without -> with) |
|---|---|---|
| generate an auth-stripping test suite | 108KB test file | ~27,980 -> ~100 (99.6%) |
| generate a `models.pyi` type stub | 41KB module | ~14,000 -> ~100 (99.3%) |

**Per task, what the agent does instead of reading files:**

| Task | Without cgh | With cgh |
|------|-------------|----------|
| Find where `process_data` is defined | Read 3-5 files (~2,000 tokens) | `symbol_lookup` (< 50 tokens) |
| Find all callers of `save_record` | Read every candidate file | `find_callers` (< 50 tokens) |
| Understand blast radius of `utils.py` | Read imports manually | `subgraph` (< 100 tokens) |
| Find docs about reconciliation | Read all `.md` files | `search_docs` (< 50 tokens) |
| Build context for a task | 5-10 file reads (~5,000 tokens) | `context_for_task` (< 200 tokens) |

**What this is not.** The billed cost, once the model's prompt cache is counted, is roughly a wash on the read side: the cache dominates the invoice, so fewer turns do not cut it much. cgh's gain there is a smaller working context and fewer turns, not a smaller bill. On a trivial one-file edit cgh adds nothing. Run-to-run variance is real (around 20%), so read these as ratios over a task set rather than a single guaranteed number.

---

## Install

```bash
pip install cgh                 # or: pipx install cgh / uv tool install cgh
pip install "cgh[full]"         # plugins, extra language parsers, precise Python calls
```

`cgh[plugins]` and `cgh[full]` bring cgh-codegen and cgh-bugreport. PDF,
Word, Excel, PowerPoint and CSV parsing is built in (it used to be the
cgh-docs plugin, which cgh now ignores if it is still installed).
cgh-pii (on-demand secret scanning, PII redaction) and cgh-vision (image
understanding) install by name; see [docs/PLUGINS.md](docs/PLUGINS.md).

Upgrading from 0.14 or older? Read
[docs/UPGRADING-0.15.md](docs/UPGRADING-0.15.md) first: cgh no longer blocks
agent file access, the default plugin set is smaller, and the upgrade
command needs `-U`.

No Python? Run the standalone binary through npm, or download it from the
[latest release](https://github.com/altikva/cgh/releases/latest):

```bash
npx @altikva/cgh serve          # fetches the binary for your OS, verifies it, runs it
npx @altikva/cgh --egress serve # the egress build, with the model-calling plugins
```

The binary uses the SQLite backend; `uvx cgh` bundles DuckDB and every plugin.
One-line installers for macOS, Linux, WSL, Git Bash and Windows PowerShell, corporate mirror
settings, optional extras and the `cgh: command not found` fix are in
**[docs/INSTALL.md](docs/INSTALL.md)**. Python 3.11 through 3.14.

## Quick start

```bash
# 1. Initialize (interactive wizard)
cgh init

# 2. Build the graph
cgh index

# 3. Check what was indexed
cgh stats

# 4. Start the MCP server for your AI tool
cgh serve --watch --reindex
```

`cgh status` tells you what the graph holds and whether it still matches the working tree:

<p align="center">
  <img src="https://raw.githubusercontent.com/altikva/cgh/main/assets/img/cgh-status.svg" alt="cgh status: backend, owner, scan freshness, import coverage and file count" width="820">
</p>

## How it works

```
AI Assistant (Claude / Cursor / Codex / Gemini / IBM Bob)
    |  symbol_lookup("process_data")
    |  search_docs("reconciliation")
    |  context_for_task("fix auth bug")
    v
MCP server (cgh)                <-- stdio, no network
    |  SQL graph query + BM25 FTS
    v
DuckDB graph DB (.codegraph/graph.duckdb)   <-- embedded, file-based
SQLite FTS5 (.codegraph/fts.db)       <-- BM25 full-text search
    |  indexed from
    v
Your source files (.py / .ts / .java / .go / .rs / .vue / .tf / .md)
    ^
File watcher (watchdog)         <-- live incremental updates on save
```

Instead of reading `services.py` (800 tokens) to find where `verify_token` is defined, your AI calls `symbol_lookup("verify_token")` and gets back the file, the line range, the kind and the docstring, then reads only those lines.

## Languages

Six languages get a full symbol graph, functions and classes and the calls
between them, with their imports resolved into `File -> File` edges:

| | | imports resolved |
|---|---|---|
| Python | `.py .pyw` | yes |
| TypeScript, JavaScript | `.ts .tsx .js .jsx .mjs .cjs` | yes |
| Java | `.java` | yes |
| Go | `.go` | yes |
| Rust | `.rs` | yes |
| Vue SFC | `.vue` | yes |

C# and Ruby parse too, behind `pip install "cgh[langs]"`.

Alongside them, Markdown becomes a heading tree with its links and code
references, Terraform yields resources, variables and outputs, and JSON,
TOML, YAML and SQL expose their structure as sections. Every one of them is
searchable and reachable from the graph.

Documents are read out of the box, no plugin needed: PDF pages, Word
headings and tables, Excel sheets, PowerPoint slides with their speaker
notes, and CSV / TSV summaries (header, size, first rows) all land in the
index as sections, so `search_docs` and `cgh search --text` find what is
inside them. Big files stay cheap: the size cap applies first and each
format bounds its own work (see [docs/PARSERS.md](docs/PARSERS.md)).

---

## Documentation

| Guide | What it covers |
|---|---|
| [Install](docs/INSTALL.md) | one-line installers, extras, corporate mirrors, PATH |
| [Upgrading to 0.15](docs/UPGRADING-0.15.md) | what changed for your agent, the upgrade command, old findings, rollback |
| [Upgrading to 0.16](docs/UPGRADING-0.16.md) | the one-time re-parse, what refuses until then, federation and seeds, removed plugins, rollback |
| [CLI reference](docs/CLI_REFERENCE.md) | every verb and flag |
| [Configuration](docs/CONFIGURATION.md) | `config.toml`, environment variables, `.cghignore` |
| [MCP tools](docs/MCP_TOOLS.md) | the tools your agent calls, by category |
| [Integrations](docs/INTEGRATIONS.md) | Claude Code, Cursor, Codex, Gemini, IBM Bob |
| [Federation](docs/FEDERATION.md) | one parent repo querying its sub-repos read-only |
| [Session memory](docs/MEMORY.md) | knowledge and plans that survive a context clear |
| [Security](docs/SECURITY.md) | what can leave the machine, findings, the egress gate, the MCP auth key |
| [Plugins](docs/PLUGINS.md) | installing them, disabling them, writing one |
| [Parsers](docs/PARSERS.md) | the parser interface and how to add a language |
| [Graph schema](docs/SCHEMA.md) | the nodes and edges the index holds |
| [Embedding (SDK)](docs/EMBEDDING.md) | using cgh as a library |

---

## Limitations

- **CALLS resolution is name-based by default, guided by imports.** For Python and TS/JS a call follows its shape: a same-file definition wins, then the file an import names (`from lib import f`, `import * as m`), `self.f()` the class and its bases, `obj.f()` on a local or attribute whose class is known (built, annotated or returned by an annotated factory) that class, and `obj.f()` on an object of unknown type only the few methods of that name (or one in a file the caller imports). Calls into third-party modules and from production code into test files get no edge. Other languages link to a same-file function of that name, else to every function with that name outside test files. Cross-file edges stay best-effort: without types, `obj.f()` can miss its target or pick a look-alike. For Python you can opt into precise resolution with `pip install cgh[lsp]` and `precise_calls = true` (jedi-backed).
- **Terraform is read file by file, not evaluated.** Blocks, references, module inputs and `moved`/`import`/`removed` are parsed with a real HCL grammar, but nothing is planned: `count`/`for_each` instances, dynamic blocks and computed addresses stay unexpanded, and a remote module is only read when `[terraform] module_sources` maps it to a local checkout.
- **Imports resolve to files in your repo, never to dependencies.** Python, JS/TS, Vue, Java, Go and Rust each map an import onto the file it names, following that language's own layout rules. Anything outside the repo stays unresolved on purpose: the standard library, a Go module you do not own, an external crate or npm package gets no node and no edge, because inventing one would be a lie about your code. Cross-repo edges are not inferred either, each federated scope is canonical for its own files.
- **Markdown code refs are heuristic.** PascalCase and snake_case patterns are matched, so a ref can be a false positive.
- **Large repos take minutes to index.** Incremental updates stay fast (well under a second per changed file), and a pull or merge reindexes only the changed files via the git hooks.

---

## License

Licensed under the [Apache License, Version 2.0](./LICENSE), from version 0.19 on. That covers cgh itself, the first-party plugins under `plugins/`, the SDK and the npx wrapper. Copyright 2026 ALTIKVA; see [NOTICE](./NOTICE).

Versions 0.18.x and earlier were published under MIT and CC BY-NC-SA 4.0 and keep that license.
