Metadata-Version: 2.4
Name: enforce-cpg
Version: 0.2.0
Summary: Code Property Graph MCP server for DayZ Enforce Script
Project-URL: Homepage, https://github.com/tommyz4/enforce-cpg
Project-URL: Repository, https://github.com/tommyz4/enforce-cpg
Project-URL: Issues, https://github.com/tommyz4/enforce-cpg/issues
Author: tommyz4
License-Expression: AAL
License-File: LICENSE
License-File: NOTICE
Keywords: code-property-graph,dayz,enforce,enfusion,mcp,tree-sitter
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Attribution Assurance License
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.12
Requires-Dist: mcp>=1.2
Requires-Dist: tree-sitter-enforce>=0.4
Requires-Dist: tree-sitter>=0.25
Description-Content-Type: text/markdown

<p align="center">
  <img src="assets/logo.svg" alt="enforce-cpg — Code Property Graph for Enforce Script" width="460">
</p>

<h1 align="center">enforce-cpg</h1>

A Code Property Graph (CPG) MCP server for **DayZ Enforce Script**.

It parses Enforce Script (`.c`) source across a vanilla/base layer and any
number of mod layers, builds a graph of declarations, inheritance,
overrides, and calls, and exposes that graph over the [Model Context
Protocol](https://modelcontextprotocol.io) so an AI coding assistant (e.g.
Claude Code) can answer real DayZ-modding questions: "what overrides
`Speak` on `Animal`?", "who calls this method?", "what breaks if I change
this field?" — across a real, multi-mod, load-order-dependent codebase,
without ever crashing on a bad file or an unresolved reference.

## Install

```bash
pip install enforce-cpg        # or: uvx enforce-cpg --version
```

No compiler needed — the Enforce grammar ships as prebuilt wheels
([`tree-sitter-enforce`](https://pypi.org/project/tree-sitter-enforce/)).

Or, from a local checkout:

```bash
uv sync
uv run enforce-cpg --version
```

## Configure

Point `enforce-cpg` at your vanilla scripts and mod source trees with an
`enforce-cpg.toml` file (see `enforce-cpg.example.toml`):

```toml
[project]
name = "my-server"
db_path = ".enforce-cpg/index.db"

# ORDERED: earlier = loaded first = base precedence. This IS your -mod= order.
[[sources]]
name = "vanilla"
kind = "core"
path = "/path/to/vanilla_scripts"

[[sources]]
name = "MyMod"
kind = "mod"
path = "/path/to/MyMod/Scripts"
```

**Load-order warning:** the order of `[[sources]]` in this file *is* the
override precedence used to resolve `Animal.Speak`-style method stacks —
it must mirror your server's real `-mod=` load order. A source listed
earlier is treated as the base that later sources override; get this
wrong and `resolve_method` / `get_inheritance` will report the wrong
override winner.

Build (or rebuild) the index:

```bash
uv run enforce-cpg index --config enforce-cpg.toml --full
```

## Tools

Once registered with an MCP client, enforce-cpg exposes 12 tools:

| Tool | Description |
| --- | --- |
| `reindex` | Rebuild the code property graph index. `full=true` forces a from-scratch rebuild; otherwise only changed files are re-indexed. |
| `find_symbol` | Find declarations of a symbol by name (optionally filtered by kind). |
| `find_references` | Find references to a symbol by name (optionally filtered by kind; declaration sites excluded by default). |
| `find_callers` | Find callers of a class method, transitively up to the given depth. |
| `resolve_method` | Resolve a method call to its override stack across the source layers (core -> mods), in resolution order, flagging cut chains. |
| `get_inheritance` | Get the inheritance chain for a class, optionally scoped to a method. |
| `impact_of_change` | Estimate the blast radius of changing a class member. |
| `get_overview` | Get a structural overview of a file or a class. |
| `audit_overrides` | Corpus-wide override audit: every modded layer that overrides without `super`, silently disabling earlier layers. |
| `mod_surface` | Every method a given source overrides that another source also defines — the mod's footprint on the shared hierarchy. |
| `doctor` | Setup + index-health report: sources resolved, per-source parse coverage, missing-vanilla warning, diagnostics, unresolved hotspots. |
| `ingest` | Register a source from an extracted directory (always) or a `.pbo` (de-rapified if a tool is available), copied under `.enforce-cpg/sources/` with the `[[sources]]` entry added. |

The same surface is available on the CLI (`enforce-cpg find-symbol`,
`… audit`, `… mod-surface --source <name>`, `… doctor`,
`… ingest <path> --name <n> --kind core|mod`, …).

Every tool degrades honestly instead of crashing: an unresolved symbol or
a missing argument returns `{"results": [], "note": "..."}` rather than an
exception, so a single bad query never takes down the server.

## Register with Claude Code

```bash
claude mcp add enforce-cpg -- uvx enforce-cpg-mcp
```

The server reads its config from the `ENFORCE_CPG_CONFIG` environment
variable (defaults to `enforce-cpg.toml` in the working directory), so
set that to your project's config path when registering.

## License

enforce-cpg is licensed under the **Attribution Assurance License (AAL)**,
an OSI-approved open-source license. The full license text is in
[`LICENSE`](./LICENSE); the required attribution notice is in
[`NOTICE`](./NOTICE).

Attribution notice (must be displayed per the AAL's attribution clause):

```
enforce-cpg — © 2026 tommyz4 — https://github.com/tommyz4/enforce-cpg
```
