enforce-cpg 0.2.0__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 (59) hide show
  1. enforce_cpg-0.2.0/.github/workflows/ci.yml +12 -0
  2. enforce_cpg-0.2.0/.github/workflows/release.yml +41 -0
  3. enforce_cpg-0.2.0/.gitignore +8 -0
  4. enforce_cpg-0.2.0/LICENSE +85 -0
  5. enforce_cpg-0.2.0/MANIFEST.in +3 -0
  6. enforce_cpg-0.2.0/NOTICE +9 -0
  7. enforce_cpg-0.2.0/PKG-INFO +141 -0
  8. enforce_cpg-0.2.0/README.md +117 -0
  9. enforce_cpg-0.2.0/assets/logo.svg +39 -0
  10. enforce_cpg-0.2.0/assets/mark.svg +38 -0
  11. enforce_cpg-0.2.0/assets/social-preview.png +0 -0
  12. enforce_cpg-0.2.0/assets/social-preview.svg +48 -0
  13. enforce_cpg-0.2.0/docs/grammar-notes.md +163 -0
  14. enforce_cpg-0.2.0/docs/superpowers/plans/2026-07-24-enforce-cpg.md +1917 -0
  15. enforce_cpg-0.2.0/docs/superpowers/specs/2026-07-24-enforce-cpg-design.md +266 -0
  16. enforce_cpg-0.2.0/docs/superpowers/specs/2026-07-25-pypi-release-design.md +60 -0
  17. enforce_cpg-0.2.0/docs/vanilla-extraction.md +86 -0
  18. enforce_cpg-0.2.0/enforce-cpg.example.toml +16 -0
  19. enforce_cpg-0.2.0/pyproject.toml +46 -0
  20. enforce_cpg-0.2.0/scripts/parse_coverage.py +33 -0
  21. enforce_cpg-0.2.0/scripts/regression.sh +60 -0
  22. enforce_cpg-0.2.0/src/enforce_cpg/__init__.py +12 -0
  23. enforce_cpg-0.2.0/src/enforce_cpg/cli.py +93 -0
  24. enforce_cpg-0.2.0/src/enforce_cpg/config.py +34 -0
  25. enforce_cpg-0.2.0/src/enforce_cpg/discovery.py +46 -0
  26. enforce_cpg-0.2.0/src/enforce_cpg/doctor.py +103 -0
  27. enforce_cpg-0.2.0/src/enforce_cpg/extract.py +333 -0
  28. enforce_cpg-0.2.0/src/enforce_cpg/index.py +63 -0
  29. enforce_cpg-0.2.0/src/enforce_cpg/ingest.py +105 -0
  30. enforce_cpg-0.2.0/src/enforce_cpg/mcp_server.py +257 -0
  31. enforce_cpg-0.2.0/src/enforce_cpg/model.py +27 -0
  32. enforce_cpg-0.2.0/src/enforce_cpg/nodetypes.py +50 -0
  33. enforce_cpg-0.2.0/src/enforce_cpg/parser.py +28 -0
  34. enforce_cpg-0.2.0/src/enforce_cpg/query.py +226 -0
  35. enforce_cpg-0.2.0/src/enforce_cpg/resolve.py +208 -0
  36. enforce_cpg-0.2.0/src/enforce_cpg/store.py +133 -0
  37. enforce_cpg-0.2.0/tests/fixtures/mini/modA/4_World/Animal.c +4 -0
  38. enforce_cpg-0.2.0/tests/fixtures/mini/modB/4_World/Animal.c +5 -0
  39. enforce_cpg-0.2.0/tests/fixtures/mini/vanilla/3_Game/Animal.c +6 -0
  40. enforce_cpg-0.2.0/tests/test_attribution_artifacts.py +25 -0
  41. enforce_cpg-0.2.0/tests/test_audit.py +68 -0
  42. enforce_cpg-0.2.0/tests/test_cli.py +39 -0
  43. enforce_cpg-0.2.0/tests/test_config.py +23 -0
  44. enforce_cpg-0.2.0/tests/test_discovery.py +35 -0
  45. enforce_cpg-0.2.0/tests/test_doctor.py +61 -0
  46. enforce_cpg-0.2.0/tests/test_extract.py +64 -0
  47. enforce_cpg-0.2.0/tests/test_incremental.py +65 -0
  48. enforce_cpg-0.2.0/tests/test_ingest.py +85 -0
  49. enforce_cpg-0.2.0/tests/test_mcp_server.py +98 -0
  50. enforce_cpg-0.2.0/tests/test_override.py +86 -0
  51. enforce_cpg-0.2.0/tests/test_parser.py +18 -0
  52. enforce_cpg-0.2.0/tests/test_query.py +189 -0
  53. enforce_cpg-0.2.0/tests/test_resolve.py +39 -0
  54. enforce_cpg-0.2.0/tests/test_resolve_perf.py +62 -0
  55. enforce_cpg-0.2.0/tests/test_smoke.py +14 -0
  56. enforce_cpg-0.2.0/tests/test_store.py +26 -0
  57. enforce_cpg-0.2.0/tests/test_store_concurrency.py +39 -0
  58. enforce_cpg-0.2.0/tests/test_vanilla_present.py +14 -0
  59. enforce_cpg-0.2.0/uv.lock +797 -0
@@ -0,0 +1,12 @@
1
+ name: ci
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v4
8
+ - uses: astral-sh/setup-uv@v5
9
+ - run: uv python install 3.12
10
+ - run: uv sync --dev
11
+ - run: uv run ruff check src tests
12
+ - run: uv run pytest -v
@@ -0,0 +1,41 @@
1
+ # Publish enforce-cpg to PyPI on a version tag. Pure-Python: one wheel + sdist.
2
+ # The grammar (tree-sitter-enforce) must already be on PyPI so the clean-venv
3
+ # smoke install below can resolve it.
4
+ name: pypi-release
5
+
6
+ on:
7
+ push:
8
+ tags: ["v*"]
9
+ workflow_dispatch: {}
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v5
17
+ - run: uv build
18
+ - name: smoke-test the built wheel in a clean venv (resolves deps from PyPI)
19
+ run: |
20
+ python -m venv /tmp/smoke
21
+ /tmp/smoke/bin/pip install --upgrade pip
22
+ /tmp/smoke/bin/pip install dist/*.whl
23
+ /tmp/smoke/bin/enforce-cpg --version
24
+ /tmp/smoke/bin/python -c "from enforce_cpg import parser; t = parser.parse(b'class A{}'); assert not t.root_node.has_error; print('grammar+parse OK')"
25
+ - uses: actions/upload-artifact@v4
26
+ with:
27
+ name: dist
28
+ path: dist/*
29
+
30
+ publish:
31
+ needs: build
32
+ runs-on: ubuntu-latest
33
+ if: ${{ github.event_name == 'push' }} # only tag pushes reach here; dispatch = build+smoke only
34
+ steps:
35
+ - uses: actions/download-artifact@v4
36
+ with:
37
+ name: dist
38
+ path: dist
39
+ - uses: pypa/gh-action-pypi-publish@release/v1
40
+ with:
41
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,8 @@
1
+ .enforce-cpg/
2
+ __pycache__/
3
+ *.pyc
4
+ .venv/
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ /enforce-cpg.toml
@@ -0,0 +1,85 @@
1
+ Attribution Assurance License (AAL)
2
+
3
+ Copyright (c) 2026 tommyz4
4
+ https://github.com/tommyz4/enforce-cpg
5
+
6
+ The following is the full, official text of the Open Source Initiative (OSI)
7
+ approved Attribution Assurance License (SPDX identifier: AAL), as published
8
+ at https://opensource.org/license/aal, with the license's own attribution
9
+ fields filled in for this project: Author = tommyz4; Professional
10
+ Identification = enforce-cpg maintainer; URL = https://github.com/tommyz4/enforce-cpg.
11
+
12
+ --------------------------------------------------------------------------
13
+
14
+ Copyright (c) 2026 tommyz4
15
+
16
+ tommyz4, enforce-cpg maintainer * https://github.com/tommyz4/enforce-cpg
17
+
18
+ "enforce-cpg: Code Property Graph MCP server for DayZ Enforce Script"
19
+
20
+ All Rights Reserved
21
+
22
+ ATTRIBUTION ASSURANCE LICENSE (adapted from the original BSD license)
23
+
24
+ Redistribution and use in source and binary forms, with or without
25
+ modification, are permitted provided that the conditions below are met.
26
+
27
+ These conditions require a modest attribution to tommyz4 (the "Author"), who
28
+ hopes that its promotional value may help justify the thousands of dollars in
29
+ otherwise billable time invested in writing this and other freely available,
30
+ open-source software.
31
+
32
+ 1. Redistributions of source code, in whole or part and with or without
33
+ modification (the "Code"), must prominently display this GPG-signed text in
34
+ verifiable form.
35
+
36
+ 2. Redistributions of the Code in binary form must be accompanied by this
37
+ GPG-signed text in any documentation and, each time the resulting executable
38
+ program or a program dependent thereon is launched, a prominent display
39
+ (e.g., splash screen or banner text) of the Author's attribution
40
+ information, which includes:
41
+
42
+ (a) Name ("tommyz4"),
43
+
44
+ (b) Professional identification ("enforce-cpg maintainer"), and
45
+
46
+ (c) URL ("https://github.com/tommyz4/enforce-cpg").
47
+
48
+ 3. Neither the name nor any trademark of the Author may be used to endorse
49
+ or promote products derived from this software without specific prior
50
+ written permission.
51
+
52
+ 4. Users are entirely responsible, to the exclusion of the Author and any
53
+ other persons, for compliance with
54
+
55
+ (1) regulations set by owners or administrators of employed equipment,
56
+
57
+ (2) licensing terms of any other software, and
58
+
59
+ (3) local regulations regarding use, including those regarding import,
60
+ export, and use of encryption software.
61
+
62
+ THIS FREE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
63
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
64
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
65
+ EVENT SHALL THE AUTHOR OR ANY CONTRIBUTOR BE LIABLE FOR ANY DIRECT,
66
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
67
+ (INCLUDING, BUT NOT LIMITED TO, EFFECTS OF UNAUTHORIZED OR MALICIOUS NETWORK
68
+ ACCESS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
69
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
70
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
71
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
72
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73
+
74
+ --End of License
75
+
76
+ Originally written by Edwin A. Suominen for licensing his PRIVARIA secure
77
+ networking software (see www.privaria.org). The author, who is not an
78
+ attorney, places this license template into the public domain along with a
79
+ complete disclaimer of any warranty or responsibility for its content or
80
+ legal efficacy. You may use or modify the language freely, but entirely at
81
+ your own risk.
82
+
83
+ --------------------------------------------------------------------------
84
+
85
+ Source: https://opensource.org/license/aal (fetched 2026-07-24).
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include NOTICE
3
+ include README.md
@@ -0,0 +1,9 @@
1
+ enforce-cpg
2
+ Copyright (c) 2026 tommyz4
3
+ https://github.com/tommyz4/enforce-cpg
4
+
5
+ This product includes software developed by tommyz4.
6
+ Licensed under the Attribution Assurance License (AAL).
7
+
8
+ Attribution Notice (must be displayed per AAL clause):
9
+ enforce-cpg — © 2026 tommyz4 — https://github.com/tommyz4/enforce-cpg
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: enforce-cpg
3
+ Version: 0.2.0
4
+ Summary: Code Property Graph MCP server for DayZ Enforce Script
5
+ Project-URL: Homepage, https://github.com/tommyz4/enforce-cpg
6
+ Project-URL: Repository, https://github.com/tommyz4/enforce-cpg
7
+ Project-URL: Issues, https://github.com/tommyz4/enforce-cpg/issues
8
+ Author: tommyz4
9
+ License-Expression: AAL
10
+ License-File: LICENSE
11
+ License-File: NOTICE
12
+ Keywords: code-property-graph,dayz,enforce,enfusion,mcp,tree-sitter
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: Attribution Assurance License
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Code Generators
18
+ Classifier: Topic :: Software Development :: Quality Assurance
19
+ Requires-Python: >=3.12
20
+ Requires-Dist: mcp>=1.2
21
+ Requires-Dist: tree-sitter-enforce>=0.4
22
+ Requires-Dist: tree-sitter>=0.25
23
+ Description-Content-Type: text/markdown
24
+
25
+ <p align="center">
26
+ <img src="assets/logo.svg" alt="enforce-cpg — Code Property Graph for Enforce Script" width="460">
27
+ </p>
28
+
29
+ <h1 align="center">enforce-cpg</h1>
30
+
31
+ A Code Property Graph (CPG) MCP server for **DayZ Enforce Script**.
32
+
33
+ It parses Enforce Script (`.c`) source across a vanilla/base layer and any
34
+ number of mod layers, builds a graph of declarations, inheritance,
35
+ overrides, and calls, and exposes that graph over the [Model Context
36
+ Protocol](https://modelcontextprotocol.io) so an AI coding assistant (e.g.
37
+ Claude Code) can answer real DayZ-modding questions: "what overrides
38
+ `Speak` on `Animal`?", "who calls this method?", "what breaks if I change
39
+ this field?" — across a real, multi-mod, load-order-dependent codebase,
40
+ without ever crashing on a bad file or an unresolved reference.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ pip install enforce-cpg # or: uvx enforce-cpg --version
46
+ ```
47
+
48
+ No compiler needed — the Enforce grammar ships as prebuilt wheels
49
+ ([`tree-sitter-enforce`](https://pypi.org/project/tree-sitter-enforce/)).
50
+
51
+ Or, from a local checkout:
52
+
53
+ ```bash
54
+ uv sync
55
+ uv run enforce-cpg --version
56
+ ```
57
+
58
+ ## Configure
59
+
60
+ Point `enforce-cpg` at your vanilla scripts and mod source trees with an
61
+ `enforce-cpg.toml` file (see `enforce-cpg.example.toml`):
62
+
63
+ ```toml
64
+ [project]
65
+ name = "my-server"
66
+ db_path = ".enforce-cpg/index.db"
67
+
68
+ # ORDERED: earlier = loaded first = base precedence. This IS your -mod= order.
69
+ [[sources]]
70
+ name = "vanilla"
71
+ kind = "core"
72
+ path = "/path/to/vanilla_scripts"
73
+
74
+ [[sources]]
75
+ name = "MyMod"
76
+ kind = "mod"
77
+ path = "/path/to/MyMod/Scripts"
78
+ ```
79
+
80
+ **Load-order warning:** the order of `[[sources]]` in this file *is* the
81
+ override precedence used to resolve `Animal.Speak`-style method stacks —
82
+ it must mirror your server's real `-mod=` load order. A source listed
83
+ earlier is treated as the base that later sources override; get this
84
+ wrong and `resolve_method` / `get_inheritance` will report the wrong
85
+ override winner.
86
+
87
+ Build (or rebuild) the index:
88
+
89
+ ```bash
90
+ uv run enforce-cpg index --config enforce-cpg.toml --full
91
+ ```
92
+
93
+ ## Tools
94
+
95
+ Once registered with an MCP client, enforce-cpg exposes 12 tools:
96
+
97
+ | Tool | Description |
98
+ | --- | --- |
99
+ | `reindex` | Rebuild the code property graph index. `full=true` forces a from-scratch rebuild; otherwise only changed files are re-indexed. |
100
+ | `find_symbol` | Find declarations of a symbol by name (optionally filtered by kind). |
101
+ | `find_references` | Find references to a symbol by name (optionally filtered by kind; declaration sites excluded by default). |
102
+ | `find_callers` | Find callers of a class method, transitively up to the given depth. |
103
+ | `resolve_method` | Resolve a method call to its override stack across the source layers (core -> mods), in resolution order, flagging cut chains. |
104
+ | `get_inheritance` | Get the inheritance chain for a class, optionally scoped to a method. |
105
+ | `impact_of_change` | Estimate the blast radius of changing a class member. |
106
+ | `get_overview` | Get a structural overview of a file or a class. |
107
+ | `audit_overrides` | Corpus-wide override audit: every modded layer that overrides without `super`, silently disabling earlier layers. |
108
+ | `mod_surface` | Every method a given source overrides that another source also defines — the mod's footprint on the shared hierarchy. |
109
+ | `doctor` | Setup + index-health report: sources resolved, per-source parse coverage, missing-vanilla warning, diagnostics, unresolved hotspots. |
110
+ | `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. |
111
+
112
+ The same surface is available on the CLI (`enforce-cpg find-symbol`,
113
+ `… audit`, `… mod-surface --source <name>`, `… doctor`,
114
+ `… ingest <path> --name <n> --kind core|mod`, …).
115
+
116
+ Every tool degrades honestly instead of crashing: an unresolved symbol or
117
+ a missing argument returns `{"results": [], "note": "..."}` rather than an
118
+ exception, so a single bad query never takes down the server.
119
+
120
+ ## Register with Claude Code
121
+
122
+ ```bash
123
+ claude mcp add enforce-cpg -- uvx enforce-cpg-mcp
124
+ ```
125
+
126
+ The server reads its config from the `ENFORCE_CPG_CONFIG` environment
127
+ variable (defaults to `enforce-cpg.toml` in the working directory), so
128
+ set that to your project's config path when registering.
129
+
130
+ ## License
131
+
132
+ enforce-cpg is licensed under the **Attribution Assurance License (AAL)**,
133
+ an OSI-approved open-source license. The full license text is in
134
+ [`LICENSE`](./LICENSE); the required attribution notice is in
135
+ [`NOTICE`](./NOTICE).
136
+
137
+ Attribution notice (must be displayed per the AAL's attribution clause):
138
+
139
+ ```
140
+ enforce-cpg — © 2026 tommyz4 — https://github.com/tommyz4/enforce-cpg
141
+ ```
@@ -0,0 +1,117 @@
1
+ <p align="center">
2
+ <img src="assets/logo.svg" alt="enforce-cpg — Code Property Graph for Enforce Script" width="460">
3
+ </p>
4
+
5
+ <h1 align="center">enforce-cpg</h1>
6
+
7
+ A Code Property Graph (CPG) MCP server for **DayZ Enforce Script**.
8
+
9
+ It parses Enforce Script (`.c`) source across a vanilla/base layer and any
10
+ number of mod layers, builds a graph of declarations, inheritance,
11
+ overrides, and calls, and exposes that graph over the [Model Context
12
+ Protocol](https://modelcontextprotocol.io) so an AI coding assistant (e.g.
13
+ Claude Code) can answer real DayZ-modding questions: "what overrides
14
+ `Speak` on `Animal`?", "who calls this method?", "what breaks if I change
15
+ this field?" — across a real, multi-mod, load-order-dependent codebase,
16
+ without ever crashing on a bad file or an unresolved reference.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install enforce-cpg # or: uvx enforce-cpg --version
22
+ ```
23
+
24
+ No compiler needed — the Enforce grammar ships as prebuilt wheels
25
+ ([`tree-sitter-enforce`](https://pypi.org/project/tree-sitter-enforce/)).
26
+
27
+ Or, from a local checkout:
28
+
29
+ ```bash
30
+ uv sync
31
+ uv run enforce-cpg --version
32
+ ```
33
+
34
+ ## Configure
35
+
36
+ Point `enforce-cpg` at your vanilla scripts and mod source trees with an
37
+ `enforce-cpg.toml` file (see `enforce-cpg.example.toml`):
38
+
39
+ ```toml
40
+ [project]
41
+ name = "my-server"
42
+ db_path = ".enforce-cpg/index.db"
43
+
44
+ # ORDERED: earlier = loaded first = base precedence. This IS your -mod= order.
45
+ [[sources]]
46
+ name = "vanilla"
47
+ kind = "core"
48
+ path = "/path/to/vanilla_scripts"
49
+
50
+ [[sources]]
51
+ name = "MyMod"
52
+ kind = "mod"
53
+ path = "/path/to/MyMod/Scripts"
54
+ ```
55
+
56
+ **Load-order warning:** the order of `[[sources]]` in this file *is* the
57
+ override precedence used to resolve `Animal.Speak`-style method stacks —
58
+ it must mirror your server's real `-mod=` load order. A source listed
59
+ earlier is treated as the base that later sources override; get this
60
+ wrong and `resolve_method` / `get_inheritance` will report the wrong
61
+ override winner.
62
+
63
+ Build (or rebuild) the index:
64
+
65
+ ```bash
66
+ uv run enforce-cpg index --config enforce-cpg.toml --full
67
+ ```
68
+
69
+ ## Tools
70
+
71
+ Once registered with an MCP client, enforce-cpg exposes 12 tools:
72
+
73
+ | Tool | Description |
74
+ | --- | --- |
75
+ | `reindex` | Rebuild the code property graph index. `full=true` forces a from-scratch rebuild; otherwise only changed files are re-indexed. |
76
+ | `find_symbol` | Find declarations of a symbol by name (optionally filtered by kind). |
77
+ | `find_references` | Find references to a symbol by name (optionally filtered by kind; declaration sites excluded by default). |
78
+ | `find_callers` | Find callers of a class method, transitively up to the given depth. |
79
+ | `resolve_method` | Resolve a method call to its override stack across the source layers (core -> mods), in resolution order, flagging cut chains. |
80
+ | `get_inheritance` | Get the inheritance chain for a class, optionally scoped to a method. |
81
+ | `impact_of_change` | Estimate the blast radius of changing a class member. |
82
+ | `get_overview` | Get a structural overview of a file or a class. |
83
+ | `audit_overrides` | Corpus-wide override audit: every modded layer that overrides without `super`, silently disabling earlier layers. |
84
+ | `mod_surface` | Every method a given source overrides that another source also defines — the mod's footprint on the shared hierarchy. |
85
+ | `doctor` | Setup + index-health report: sources resolved, per-source parse coverage, missing-vanilla warning, diagnostics, unresolved hotspots. |
86
+ | `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. |
87
+
88
+ The same surface is available on the CLI (`enforce-cpg find-symbol`,
89
+ `… audit`, `… mod-surface --source <name>`, `… doctor`,
90
+ `… ingest <path> --name <n> --kind core|mod`, …).
91
+
92
+ Every tool degrades honestly instead of crashing: an unresolved symbol or
93
+ a missing argument returns `{"results": [], "note": "..."}` rather than an
94
+ exception, so a single bad query never takes down the server.
95
+
96
+ ## Register with Claude Code
97
+
98
+ ```bash
99
+ claude mcp add enforce-cpg -- uvx enforce-cpg-mcp
100
+ ```
101
+
102
+ The server reads its config from the `ENFORCE_CPG_CONFIG` environment
103
+ variable (defaults to `enforce-cpg.toml` in the working directory), so
104
+ set that to your project's config path when registering.
105
+
106
+ ## License
107
+
108
+ enforce-cpg is licensed under the **Attribution Assurance License (AAL)**,
109
+ an OSI-approved open-source license. The full license text is in
110
+ [`LICENSE`](./LICENSE); the required attribution notice is in
111
+ [`NOTICE`](./NOTICE).
112
+
113
+ Attribution notice (must be displayed per the AAL's attribution clause):
114
+
115
+ ```
116
+ enforce-cpg — © 2026 tommyz4 — https://github.com/tommyz4/enforce-cpg
117
+ ```
@@ -0,0 +1,39 @@
1
+ <svg width="560" height="160" viewBox="0 0 560 160" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="enforce-cpg">
2
+ <defs>
3
+ <linearGradient id="tileL" x1="0" y1="0" x2="160" y2="160" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#0C1524"/>
5
+ <stop offset="1" stop-color="#111F33"/>
6
+ </linearGradient>
7
+ <linearGradient id="chainL" x1="52" y1="118" x2="116" y2="42" gradientUnits="userSpaceOnUse">
8
+ <stop stop-color="#64748B"/>
9
+ <stop offset="0.55" stop-color="#38BDF8"/>
10
+ <stop offset="1" stop-color="#22D3EE"/>
11
+ </linearGradient>
12
+ <radialGradient id="glowL" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(114 44) scale(34)">
13
+ <stop stop-color="#22D3EE" stop-opacity="0.55"/>
14
+ <stop offset="1" stop-color="#22D3EE" stop-opacity="0"/>
15
+ </radialGradient>
16
+ </defs>
17
+
18
+ <!-- mark -->
19
+ <g>
20
+ <rect x="2" y="2" width="156" height="156" rx="36" fill="url(#tileL)" stroke="#1E2E45" stroke-width="2"/>
21
+ <path d="M52 116 L30 128" stroke="#2A3B55" stroke-width="3" stroke-linecap="round"/>
22
+ <path d="M82 82 L128 100" stroke="#2A3B55" stroke-width="3" stroke-linecap="round"/>
23
+ <circle cx="28" cy="130" r="6" fill="#243349" stroke="#33475F" stroke-width="2"/>
24
+ <circle cx="132" cy="102" r="7" fill="#243349" stroke="#33475F" stroke-width="2"/>
25
+ <path d="M52 114 L82 82 L114 46" stroke="url(#chainL)" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
26
+ <circle cx="114" cy="44" r="30" fill="url(#glowL)"/>
27
+ <circle cx="50" cy="116" r="13" fill="#1B2A40" stroke="#475569" stroke-width="3"/>
28
+ <circle cx="82" cy="82" r="13" fill="#F59E0B" stroke="#FBBF24" stroke-width="2"/>
29
+ <circle cx="114" cy="44" r="16" fill="#22D3EE" stroke="#A5F3FC" stroke-width="2.5"/>
30
+ </g>
31
+
32
+ <!-- wordmark -->
33
+ <g font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', 'Cascadia Code', Menlo, Consolas, monospace">
34
+ <text x="196" y="82" font-size="46" font-weight="700" letter-spacing="-1">
35
+ <tspan fill="#E2E8F0">enforce</tspan><tspan fill="#22D3EE">-cpg</tspan>
36
+ </text>
37
+ <text x="198" y="112" font-size="17.5" font-weight="500" letter-spacing="0.5" fill="#7C8CA5">Code Property Graph for Enforce Script</text>
38
+ </g>
39
+ </svg>
@@ -0,0 +1,38 @@
1
+ <svg width="160" height="160" viewBox="0 0 160 160" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="enforce-cpg mark">
2
+ <defs>
3
+ <linearGradient id="tile" x1="0" y1="0" x2="160" y2="160" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#0C1524"/>
5
+ <stop offset="1" stop-color="#111F33"/>
6
+ </linearGradient>
7
+ <linearGradient id="chain" x1="52" y1="118" x2="116" y2="42" gradientUnits="userSpaceOnUse">
8
+ <stop stop-color="#64748B"/>
9
+ <stop offset="0.55" stop-color="#38BDF8"/>
10
+ <stop offset="1" stop-color="#22D3EE"/>
11
+ </linearGradient>
12
+ <radialGradient id="glow" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(114 44) scale(34)">
13
+ <stop stop-color="#22D3EE" stop-opacity="0.55"/>
14
+ <stop offset="1" stop-color="#22D3EE" stop-opacity="0"/>
15
+ </radialGradient>
16
+ </defs>
17
+
18
+ <rect x="2" y="2" width="156" height="156" rx="36" fill="url(#tile)" stroke="#1E2E45" stroke-width="2"/>
19
+
20
+ <!-- faint satellite edges (references / callers) -> gives the graph feel -->
21
+ <path d="M52 116 L30 128" stroke="#2A3B55" stroke-width="3" stroke-linecap="round"/>
22
+ <path d="M82 82 L128 100" stroke="#2A3B55" stroke-width="3" stroke-linecap="round"/>
23
+ <circle cx="28" cy="130" r="6" fill="#243349" stroke="#33475F" stroke-width="2"/>
24
+ <circle cx="132" cy="102" r="7" fill="#243349" stroke="#33475F" stroke-width="2"/>
25
+
26
+ <!-- the override stack: base -> modded -> resolved (main chain) -->
27
+ <path d="M52 114 L82 82 L114 46" stroke="url(#chain)" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
28
+
29
+ <!-- glow behind the resolved node -->
30
+ <circle cx="114" cy="44" r="30" fill="url(#glow)"/>
31
+
32
+ <!-- base node (vanilla / lowest precedence) -->
33
+ <circle cx="50" cy="116" r="13" fill="#1B2A40" stroke="#475569" stroke-width="3"/>
34
+ <!-- modded layer node -->
35
+ <circle cx="82" cy="82" r="13" fill="#F59E0B" stroke="#FBBF24" stroke-width="2"/>
36
+ <!-- resolved / effective node (top of stack) -->
37
+ <circle cx="114" cy="44" r="16" fill="#22D3EE" stroke="#A5F3FC" stroke-width="2.5"/>
38
+ </svg>
@@ -0,0 +1,48 @@
1
+ <svg width="1280" height="640" viewBox="0 0 1280 640" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1280" y2="640" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#070D18"/>
5
+ <stop offset="1" stop-color="#0E1B2E"/>
6
+ </linearGradient>
7
+ <linearGradient id="tileS" x1="0" y1="0" x2="220" y2="220" gradientUnits="userSpaceOnUse">
8
+ <stop stop-color="#0C1524"/><stop offset="1" stop-color="#111F33"/>
9
+ </linearGradient>
10
+ <linearGradient id="chainS" x1="70" y1="162" x2="158" y2="58" gradientUnits="userSpaceOnUse">
11
+ <stop stop-color="#64748B"/><stop offset="0.55" stop-color="#38BDF8"/><stop offset="1" stop-color="#22D3EE"/>
12
+ </linearGradient>
13
+ <radialGradient id="glowS" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(156 60) scale(46)">
14
+ <stop stop-color="#22D3EE" stop-opacity="0.5"/><stop offset="1" stop-color="#22D3EE" stop-opacity="0"/>
15
+ </radialGradient>
16
+ <radialGradient id="halo" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(340 300) scale(520)">
17
+ <stop stop-color="#123049" stop-opacity="0.6"/><stop offset="1" stop-color="#123049" stop-opacity="0"/>
18
+ </radialGradient>
19
+ </defs>
20
+
21
+ <rect width="1280" height="640" fill="url(#bg)"/>
22
+ <circle cx="340" cy="300" r="520" fill="url(#halo)"/>
23
+
24
+ <!-- mark, scaled up and centered-left -->
25
+ <g transform="translate(150 150) scale(1.36)">
26
+ <rect x="2" y="2" width="216" height="216" rx="50" fill="url(#tileS)" stroke="#1E2E45" stroke-width="2.5"/>
27
+ <path d="M70 160 L40 178" stroke="#2A3B55" stroke-width="4" stroke-linecap="round"/>
28
+ <path d="M112 112 L176 138" stroke="#2A3B55" stroke-width="4" stroke-linecap="round"/>
29
+ <circle cx="38" cy="180" r="8" fill="#243349" stroke="#33475F" stroke-width="2.5"/>
30
+ <circle cx="180" cy="140" r="9" fill="#243349" stroke="#33475F" stroke-width="2.5"/>
31
+ <path d="M70 158 L112 112 L156 64" stroke="url(#chainS)" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
32
+ <circle cx="156" cy="60" r="42" fill="url(#glowS)"/>
33
+ <circle cx="68" cy="160" r="18" fill="#1B2A40" stroke="#475569" stroke-width="4"/>
34
+ <circle cx="112" cy="112" r="18" fill="#F59E0B" stroke="#FBBF24" stroke-width="2.5"/>
35
+ <circle cx="156" cy="60" r="22" fill="#22D3EE" stroke="#A5F3FC" stroke-width="3"/>
36
+ </g>
37
+
38
+ <g font-family="ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace">
39
+ <text x="530" y="270" font-size="82" font-weight="700" letter-spacing="-2"><tspan fill="#E8EEF6">enforce</tspan><tspan fill="#22D3EE">-cpg</tspan></text>
40
+ <text x="534" y="330" font-size="30" font-weight="500" fill="#93A3BC">Code Property Graph MCP server for DayZ Enforce Script</text>
41
+ </g>
42
+
43
+ <!-- feature line -->
44
+ <g font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif">
45
+ <text x="534" y="420" font-size="25" fill="#5D7290">resolve modded-override chains · call graph · inheritance · impact</text>
46
+ <text x="534" y="470" font-size="21" font-weight="600" fill="#6B7F9C">AAL-licensed · pip / uvx · tree-sitter</text>
47
+ </g>
48
+ </svg>