minh-gkg
by Minh090506
README.md
# Minh-gkg
TypeScript-accurate code graph for AI agents: compiler-grade **find-references**, **change impact analysis**, and **repo maps**, exposed as a CLI and an MCP server.
Clean-room combination of the best ideas from [GitLab Knowledge Graph](https://gitlab.com/gitlab-org/rust/knowledge-graph) (local graph, MCP tools, repo map) and [GitNexus](https://github.com/abhigyanpatwari/GitNexus) (pre-commit impact analysis, agent-first tool surface) — no code from either project. Where those tools parse with tree-sitter heuristics, Minh-gkg uses the **TypeScript compiler** (via ts-morph), so cross-file references resolve through imports, aliases, re-exports and tsconfig path mappings exactly.
**Scope**: TypeScript/TSX projects with a `tsconfig.json`. That's the trade-off — one language, done precisely.
## Install
```bash
git clone https://github.com/Minh090506/Minh-gkg.git
cd Minh-gkg && npm install
npm link # exposes `minh-gkg` on PATH (optional)
```
## CLI
```bash
minh-gkg search Booking --project ~/my-app # find symbols by name substring
minh-gkg refs calculateTotal # every cross-file usage, compiler-resolved
minh-gkg refs Config src/lib # disambiguate with a file-path hint
minh-gkg impact # blast radius of uncommitted changes
minh-gkg impact --base master # blast radius vs a branch
minh-gkg repo-map src/features # condensed ASCII architecture map
```
`--project <dir>` defaults to the current directory; `--tsconfig <path>` for non-standard layouts.
## MCP server (Claude Code / Cursor / Codex)
```bash
claude mcp add --scope project minh-gkg -- node /path/to/Minh-gkg/src/cli.js serve --project /path/to/your-app
```
Tools exposed: `search_definitions`, `find_references`, `impact_of_changes`, `repo_map`, `reload_project`.
**Impact preflight:** `impact` / `impact_of_changes` run `git diff` + a tsconfig root-set check *before* loading the TypeScript project. A clean working tree (or only changes outside the tsconfig program) returns an empty JSON result in under a second with essentially zero compiler RAM — no more multi-second / multi-GB cold start just to report "nothing changed".
## Architecture: two tiers
`search` and `refs`/`impact` don't need the same amount of TypeScript understanding, so they run on two different engines:
- **Syntax tier** (`search_definitions`, `repo_map`) — a persistent index built with `ts.createSourceFile` per file (parse, extract declarations, discard the AST — never a full `ts-morph` `Project`). A lightweight TypeScript preprocessor/module-resolution pass expands tsconfig roots to the same imported program-file manifest as `ts-morph`, including `files`-only projects. Cached on disk at `~/.minh-gkg/<projectHash>/index.json`, keyed by schema version + TypeScript version + the resolved tsconfig graph (path, full `extends` chain, content hashes) + compiler-options hash + the complete program-file manifest. Per-file freshness is `{mtimeMs, size, contentHash}`: a stat mismatch triggers a content-hash check, and only a real hash mismatch triggers a re-parse — so edits get picked up incrementally instead of a full rebuild. The file is written atomically (temp file + `fsync` + rename, `0600`/`0700` perms) behind a stale-PID-aware lockfile; a corrupt or version-mismatched file is discarded and silently rebuilt, never crashes the CLI/MCP process. On `/Users/minhhome/mvt-saas` (2,323 indexable files out of 2,329 program files): median warm-disk CLI search is 496ms / ~184MB RSS — versus ~6.5s / ~1.6GB for the old Project-backed path.
- **Semantic tier** (`find_references`, `impact_of_changes`) — unchanged: a real `ts-morph` `Project`, so cross-file references resolve through imports, aliases, re-exports, and tsconfig path mappings exactly (compiler-grade, not heuristic). It loads lazily on first use and holds ~2.5GB RAM while resident on a ~2.3k-file repo; after 10 minutes with no tool call the idle timer unloads it (next call pays cold-start again).
A shared generation counter (`src/cache-coordinator.js`) keeps the two tiers honest: when the syntax index notices a file changed, it bumps the generation and invalidates the cached semantic `Project` too, so a stale compiler cache can never silently outlive an on-disk edit. The MCP server's idle timer only ever unloads the semantic `Project` (the syntax index is light enough to stay resident); `reload_project` invalidates both tiers and lets the next query rebuild lazily rather than eagerly. Progress/build logging goes to stderr so it never pollutes MCP's stdio JSON-RPC channel.
## Testing
`npm test` runs two golden-fixture gates. **GATE A** freezes `search`/`repo-map` output, including export lists/defaults, standalone declarations, destructuring, decorators, interfaces, imported files outside a `files` list, inherited path changes, and warmed add/delete/rename transitions. Accuracy goldens are generated from a `ts-morph Project` oracle, not from the syntax index under test. **GATE B** freezes compiler-backed `refs`/`impact` output. Goldens live in `test/golden/` and are never auto-regenerated by `npm test` — run `npm run golden:update` to deliberately refresh them after an intentional engine change, then review the diff.
Two more suites cover behavior the golden gates can't see because it doesn't show up in output shape: `test/syntax-index-no-project-load.test.js` asserts `search`/`repo-map` never construct a `ts-morph` `Project` (using the call counter `src/project-loader.js` exposes for this, with a negative control proving the counter is real), and `test/syntax-index-persistence.test.js` covers a corrupt `index.json` self-healing instead of crashing and an edited file being picked up via the incremental refresh path (not a full rebuild).
## Why not just gkg or GitNexus?
| | gkg | GitNexus | Minh-gkg |
|---|---|---|---|
| TS cross-file refs | in progress (tree-sitter) | tree-sitter based | **exact (TS compiler)** |
| Impact analysis | manual via refs | yes | yes, git-diff driven |
| License | open source | PolyForm Noncommercial | MIT |
| Languages | many | many | TypeScript only |
Use gkg/GitNexus for multi-language repos; use Minh-gkg when the repo is TypeScript and reference precision matters (refactors, money paths, pre-commit gates).
## License
MIT
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues