mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-09 22:33:39 +00:00
* fix(install): materialize vendored grammars to fix Windows EPERM (#1728) Stop using file: optionalDependencies for tree-sitter-dart/proto/swift, which made npm symlink vendor paths on install and fail on Windows without symlink privileges. Copy vendor trees into node_modules at postinstall instead; keep native builds and #836 vendor hygiene. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(install): atomic materialize swap + fail-soft tests (#1728, #836) Hardens PR #1729 against two issues the original implementation could still hit: 1. Torn-state on rmSync→cpSync. The previous loop deleted the destination before copying. If cpSync threw — the exact Windows EPERM scenario this PR targets — a previously-working grammar was silently wiped. Now we copy to {dest}.materialize-tmp first and renameSync into place, so an interrupted copy leaves the prior materialization intact. 2. Fail-soft try/catch had no test coverage. Adds two POSIX-only tests (chmod 0o555 to deterministically force cpSync to throw) that verify (a) a single grammar failure does not abort the other two, and (b) an existing materialization survives a partial-copy failure. Skipped on Windows where chmod doesn't enforce write restriction; runs on Linux CI. Other test improvements locking in the install-hygiene invariants: - All three vendored grammars (dart/proto/swift) checked, not just dart. - GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1 short-circuit is exercised. - Vendor cleanliness (#836): no node_modules/build under vendor/. - Idempotent re-runs (clean overwrite verified via sentinel file). - Missing-vendor warn+continue path now has explicit coverage. - Vendored package manifests asserted to carry no install script or runtime dependencies. - package.json optionalDependencies asserted free of vendored grammars. - package-lock.json assertion tightened from `if (entry !== undefined) { expect(entry.link).not.toBe(true); }` (vacuous when entry is absent, i.e. the expected post-fix state) to `expect(...).toBeUndefined()`. Verified locally: - npx tsc --noEmit: clean - vitest test/unit/materialize-vendor-grammars.test.ts: 8 pass + 2 POSIX-only skipped on Windows - npm pack tarball: no vendor/*/node_modules or vendor/*/build entries - Isolated global install (clean + upgrade + SKIP env) into temp prefix: succeeds; gitnexus --version → 1.6.5; vendor stays clean post-install. * fix(install): address review feedback — Swift parity, atomicity, CI smoke Resolves all findings from the automated production-readiness review on verify/issue-1728-symlink. Swift warning parity (review #2): Add tree-sitter-swift to OPTIONAL_GRAMMARS in src/cli/optional-grammars.ts alongside Dart and Proto. Before this commit, Swift was materialized at postinstall and probed by build-tree-sitter-swift.cjs but the runtime warnMissingOptionalGrammars() never warned when it failed to load — users got silent Swift degradation from the optional-grammars surface (parser-loader's separate unavailableNote only fires on demand). Now the warning path matches the materialize path. README env-var table (review #1): Update the GITNEXUS_SKIP_OPTIONAL_GRAMMARS row at README.md line 248 to list all three vendored grammars (dart, proto, swift). The quick note earlier in the README already mentioned all three; only the table row was stale. Atomicity hardening (review #3): materialize-vendor-grammars.cjs now copies to {dest}.materialize-tmp, renames the existing dest to {dest}.materialize-bak (if present), then renames the partial into dest, then removes the backup. If the partial→dest rename fails (e.g. Windows AV scanner racing the swap), the catch block restores from backup so the previously-materialized grammar is preserved. Closes the narrow torn-state window where the prior implementation could leave dest deleted after rmSync succeeded but renameSync failed. Swift probe docs (review #4): build-tree-sitter-swift.cjs script header rewritten to describe what the script actually does — probe node-gyp-build at install time so missing-prebuild failures surface as install-time warnings instead of first-parse runtime errors. The script does not "activate" anything; the runtime require() in parser-loader does the actual load. Console warning text updated to match ("prebuild probe" not "activation"). Windows packaged-install smoke test (review #5): New CI job `packaged-install-smoke` in .github/workflows/ci-tests.yml matrices on windows-latest and ubuntu-latest. Runs npm pack, installs the produced tarball globally into RUNNER_TEMP, then asserts: * no vendor/*/node_modules or vendor/*/build (#836 invariant) * tree-sitter-{dart,proto,swift} in node_modules are real directories, not junctions/symlinks (#1728 invariant) * gitnexus --version runs against the installed CLI Closes the coverage gap where the existing windows-latest job only ran `npm ci` in the source checkout — exercising postinstall but not the tarball reify step that historically tripped EPERM. Verified locally: npx tsc --noEmit: clean vitest test/unit/materialize-vendor-grammars.test.ts test/unit/cli-commands.test.ts: 18 pass + 2 POSIX-only skipped on Windows prettier + eslint on all changed files: clean * fix(ci): disable credential persistence on packaged-install-smoke checkout GitHub Advanced Security (zizmor artipacked) flagged the new packaged-install-smoke job's actions/checkout step as a potential credential-persistence risk. The job runs `npm pack` + global install and never pushes back, so the GITHUB_TOKEN that checkout would persist in .git/config provides no value and only widens the leak surface (any future artifact-upload step in this job would carry the token). Disable persistence explicitly via `persist-credentials: false` on this job's checkout. Scoped to the new job — pre-existing checkouts above are left unchanged. * fix(ci): use find instead of ls for tarball lookup (SC2012) actionlint shellcheck SC2012 flagged `TARBALL=$(ls gitnexus-*.tgz | head -n1)`. Switch to `find . -maxdepth 1 -name 'gitnexus-*.tgz' -print -quit` which handles non-alphanumeric filenames safely. Also add an explicit empty-result check so the failure mode is a clear error message instead of a silent `npm install -g ""` later. * fix(tests): sabotage vendor src (not partial path) in POSIX fail-soft tests The fail-soft tests in materialize-vendor-grammars.test.ts pre-chmod'd the destination's .materialize-tmp partial directory to 0o555 to force cpSync to throw. After the atomicity rewrite (`fix(install): atomic materialize swap + fail-soft tests`), the materialize script now starts each grammar's loop with `fs.rmSync(partial, { force: true })`, which deletes the chmod'd sabotage before cpSync runs — so cpSync succeeds and the partial is then renamed into dest, leaving the test's `finally` block with no path to chmod back (ENOENT) and the assertion that proto remained unmaterialized failing because it materialized cleanly. Fix: sabotage the *vendor source* directory (which the script reads from but never modifies) by chmod'ing it to 0o000. cpSync then fails on readdir, the catch block fires per-grammar, dart and swift still materialize from their unaffected sources, and the existing-dest preservation test verifies that a sabotaged second-run leaves the prior materialization (and its sentinel file) intact. Tests now pass locally (8 pass + 2 POSIX-only skipped on Windows) and should pass on macOS/Ubuntu CI where the sabotage runs. * fix(tests): restrict fail-soft tests to Linux (macOS Node cpSync abort) Node 22 on macOS aborts the process with `libc++abi: terminating due to uncaught exception filesystem_error` when fs.cpSync hits a source directory it can't read — the abort happens at the C++ filesystem layer and bypasses Node's JS try/catch entirely (nodejs/node#51399). My chmod-0o000-the-source sabotage strategy triggers this SIGABRT on macOS CI before the production script's `try { cpSync } catch` ever runs, so the test sees a child-process crash instead of the fail-soft warning it's verifying. The production script's fail-soft is correct on Linux (where EACCES surfaces as a normal JS exception) and effectively untestable on macOS via permission sabotage. Real installs don't hit this — npm always ships vendor/ with readable permissions — so the macOS gap is a test artifact, not a behavior gap. Restrict the two chmod-based tests to Linux only by replacing `skipOnWin` with `linuxOnly`. Linux CI continues to verify both the one-grammar-fails-others-succeed and existing-materialization-preserved invariants. macOS and Windows runs skip these two scenarios; the other 8 tests still run on every platform. * fix(tests): remove materialize unit tests, rely on CI smoke job The materialize-vendor-grammars.test.ts file has been a recurring source of platform-specific CI noise: - Windows: chmod doesn't enforce read/write restrictions the way POSIX does, so the fail-soft tests had to be skipped there. - macOS Node 22: cpSync against an unreadable source aborts the process with a libc++ filesystem_error (nodejs/node#51399) that bypasses JS try/catch entirely — making the chmod-based fail-soft tests unrunnable on macOS too. - The "vendor-cleanliness" and "idempotency" tests on Windows intermittently flake due to fs.cpSync timing on the GitHub runner. The invariants these tests verified are now covered by stronger, more realistic surfaces: - packaged-install-smoke (ci-tests.yml): runs `npm pack` then `npm install -g ./gitnexus-*.tgz` on windows-latest and ubuntu-latest, then asserts no vendor/*/node_modules, no vendor/*/build (#836), no junctions/symlinks on the materialized grammar directories (#1728), and a working `gitnexus --version`. This is the actual end-user install path. - cli-commands.test.ts (kept, unmodified): asserts package.json declares no `file:` optionalDependencies for vendored grammars, the Swift vendor manifest carries no install script or dependencies, and the postinstall chain runs materialize-vendor-grammars.cjs + build-tree-sitter-swift.cjs. These are static manifest checks — deterministic, fast, no flake risk. Removing the dynamic script-execution tests trades unit-level coverage for end-to-end smoke coverage that actually exercises the `file:` → cpSync change against a real npm install lifecycle, on the platform the fix targets (windows-latest). --------- Co-authored-by: Cursor <cursoragent@cursor.com>
808 lines
45 KiB
Markdown
808 lines
45 KiB
Markdown
# GitNexus
|
||
|
||
**⚠️ Important Notice:** GitNexus has NO official cryptocurrency, token, or coin. Any token/coin using the GitNexus name on Pump.fun or any other platform is **not affiliated with, endorsed by, or created by** this project or its maintainers. Do not purchase any cryptocurrency claiming association with GitNexus.
|
||
|
||
<div align="center">
|
||
|
||
<a href="https://trendshift.io/repositories/19809" target="_blank">
|
||
<img src="https://trendshift.io/api/badge/repositories/19809" alt="abhigyanpatwari%2FGitNexus | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
|
||
</a>
|
||
|
||
<h2>Join the official Discord to discuss ideas, issues etc!</h2>
|
||
|
||
<a href="https://discord.gg/MgJrmsqr62">
|
||
<img src="https://img.shields.io/discord/1477255801545429032?color=5865F2&logo=discord&logoColor=white" alt="Discord"/>
|
||
</a>
|
||
<a href="https://www.npmjs.com/package/gitnexus">
|
||
<img src="https://img.shields.io/npm/v/gitnexus.svg" alt="npm version"/>
|
||
</a>
|
||
<a href="https://polyformproject.org/licenses/noncommercial/1.0.0/">
|
||
<img src="https://img.shields.io/badge/License-PolyForm%20Noncommercial-blue.svg" alt="License: PolyForm Noncommercial"/>
|
||
</a>
|
||
<a href="https://securityscorecards.dev/viewer/?uri=github.com/abhigyanpatwari/GitNexus">
|
||
<img src="https://api.securityscorecards.dev/projects/github.com/abhigyanpatwari/GitNexus/badge" alt="OpenSSF Scorecard"/>
|
||
</a>
|
||
|
||
<p><strong>Enterprise (SaaS & Self-hosted)</strong> - <a href="https://akonlabs.com">akonlabs.com</a></p>
|
||
|
||
</div>
|
||
|
||
**Building nervous system for agent context.**
|
||
|
||
Indexes any codebase into a knowledge graph — every dependency, call chain, cluster, and execution flow — then exposes it through smart tools so AI agents never miss code.
|
||
|
||
https://github.com/user-attachments/assets/172685ba-8e54-4ea7-9ad1-e31a3398da72
|
||
|
||
> _Like DeepWiki, but deeper._ DeepWiki helps you _understand_ code. GitNexus lets you _analyze_ it — because a knowledge graph tracks every relationship, not just descriptions.
|
||
|
||
**TL;DR:** The **Web UI** is a quick way to chat with any repo. The **CLI + MCP** is how you make your AI agent actually reliable — it gives Cursor, Claude Code, Codex, and friends a deep architectural view of your codebase so they stop missing dependencies, breaking call chains, and shipping blind edits. Even smaller models get full architectural clarity, making it compete with Goliath models.
|
||
|
||
---
|
||
|
||
## Star History
|
||
|
||
[](https://www.star-history.com/#abhigyanpatwari/GitNexus&type=date&legend=top-left)
|
||
|
||
## Two Ways to Use GitNexus
|
||
|
||
| | **CLI + MCP** | **Web UI** |
|
||
| ----------- | --------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||
| **What** | Index repos locally, connect AI agents via MCP | Visual graph explorer + AI chat in browser |
|
||
| **For** | Daily development with Cursor, Claude Code, Codex, Windsurf, OpenCode | Quick exploration, demos, one-off analysis |
|
||
| **Scale** | Full repos, any size | Limited by browser memory (~5k files), or unlimited via backend mode |
|
||
| **Install** | `npm install -g gitnexus` | No install — [gitnexus.vercel.app](https://gitnexus.vercel.app) |
|
||
| **Storage** | LadybugDB native (fast, persistent) | LadybugDB WASM (in-memory, per session) |
|
||
| **Parsing** | Tree-sitter native bindings | Tree-sitter WASM |
|
||
| **Privacy** | Everything local, no network | Everything in-browser, no server |
|
||
|
||
> **Bridge mode:** `gitnexus serve` connects the two — the web UI auto-detects the local server and can browse all your CLI-indexed repos without re-uploading or re-indexing.
|
||
|
||
---
|
||
|
||
## Enterprise
|
||
|
||
GitNexus is available as an **enterprise offering** - either as a fully managed **SaaS** or a **self-hosted** deployment. Also available for **commercial use** of the OSS version with proper licensing.
|
||
|
||
Enterprise includes:
|
||
|
||
- **PR Review** - automated blast radius analysis on pull requests
|
||
- **Auto-updating Code Wiki** - always up-to-date documentation (Code Wiki is also available in OSS)
|
||
- **Auto-reindexing** - knowledge graph stays fresh automatically
|
||
- **Multi-repo support** - unified graph across repositories
|
||
- **OCaml support** - additional language coverage
|
||
- **Priority feature/language support** - request new languages or features
|
||
|
||
**Upcoming:**
|
||
|
||
- Auto regression forensics
|
||
- End-to-end test generation
|
||
|
||
👉 Learn more at [akonlabs.com](https://akonlabs.com)
|
||
|
||
💬 For commercial licensing or enterprise inquiries, ping us on [Discord](https://discord.gg/AAsRVT6fGb) or drop an email at founders@akonlabs.com
|
||
|
||
---
|
||
|
||
## Development
|
||
|
||
- [ARCHITECTURE.md](ARCHITECTURE.md) — packages, index → graph → MCP flow, where to change code
|
||
- [RUNBOOK.md](RUNBOOK.md) — analyze, embeddings, stale index, MCP recovery, CI snippets
|
||
- [GUARDRAILS.md](GUARDRAILS.md) — safety rules and operational “Signs” for contributors and agents
|
||
- [CONTRIBUTING.md](CONTRIBUTING.md) — license, setup, commits, and pull requests
|
||
- [TESTING.md](TESTING.md) — test commands for `gitnexus` and `gitnexus-web`
|
||
|
||
## CLI + MCP (recommended)
|
||
|
||
The CLI indexes your repository and runs an MCP server that gives AI agents deep codebase awareness.
|
||
|
||
### Quick Start
|
||
|
||
```bash
|
||
# Index your repo (run from repo root)
|
||
npx gitnexus analyze
|
||
```
|
||
|
||
That's it. This indexes the codebase, installs agent skills, registers Claude Code hooks, and creates `AGENTS.md` / `CLAUDE.md` context files — all in one command.
|
||
|
||
To configure MCP for your editor, run `npx gitnexus setup` once — or set it up manually below.
|
||
|
||
> **Faster install (no C++ toolchain needed):** set `GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1` before `npm install -g gitnexus` to skip vendored grammar materialize/build (`tree-sitter-dart`, `tree-sitter-proto`, `tree-sitter-swift`). Dart/Proto/Swift files won't be parsed, but install completes in seconds without `python3`/`make`/`g++`. Strict `=1` only — any other value falls through to the rebuild.
|
||
|
||
### MCP Setup
|
||
|
||
`gitnexus setup` auto-detects your editors and writes the correct global MCP config. You only need to run it once.
|
||
|
||
### Editor Support
|
||
|
||
| Editor | MCP | Skills | Hooks (auto-augment) | Support |
|
||
| --------------- | --- | ------ | --------------------------------------------------------------------------------------- | ------------ |
|
||
| **Claude Code** | Yes | Yes | Yes (PreToolUse + PostToolUse) | **Full** |
|
||
| **Cursor** | Yes | Yes | Yes (postToolUse, [manual install](gitnexus-cursor-integration/README.md#hook-install)) | **Full** |
|
||
| **Codex** | Yes | Yes | — | MCP + Skills |
|
||
| **Windsurf** | Yes | — | — | MCP |
|
||
| **OpenCode** | Yes | Yes | — | MCP + Skills |
|
||
|
||
> **Claude Code** gets the deepest integration: MCP tools + agent skills + PreToolUse hooks that enrich searches with graph context + PostToolUse hooks that detect a stale index after commits and prompt the agent to reindex.
|
||
|
||
## Community Integrations
|
||
|
||
Built by the community — not officially maintained, but worth checking out.
|
||
|
||
| Project | Author | Description |
|
||
| ----------------------------------------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------- |
|
||
| [pi-gitnexus](https://github.com/tintinweb/pi-gitnexus) | [@tintinweb](https://github.com/tintinweb) | GitNexus plugin for [pi](https://pi.dev) — `pi install npm:pi-gitnexus` |
|
||
| [gitnexus-stable-ops](https://github.com/ShunsukeHayashi/gitnexus-stable-ops) | [@ShunsukeHayashi](https://github.com/ShunsukeHayashi) | Stable ops & deployment workflows (Miyabi ecosystem) |
|
||
|
||
> Have a project built on GitNexus? Open a PR to add it here!
|
||
|
||
If you prefer manual configuration:
|
||
|
||
> **Recommended for fastest startup:** install gitnexus globally (`npm i -g gitnexus`) and run `gitnexus setup` — this writes an absolute-path MCP config that bypasses `npx` entirely. The pinned-`npx` snippets below are a quickstart fallback; on a cold cache the `npx` install can exceed Claude Code's `MCP_TIMEOUT` default (~30s).
|
||
|
||
**Claude Code** (full support — MCP + skills + hooks):
|
||
|
||
```bash
|
||
# macOS / Linux
|
||
claude mcp add gitnexus -- npx -y gitnexus@latest mcp
|
||
|
||
# Windows
|
||
claude mcp add gitnexus -- cmd /c npx -y gitnexus@latest mcp
|
||
```
|
||
|
||
**Codex** (full support — MCP + skills):
|
||
|
||
```bash
|
||
codex mcp add gitnexus -- npx -y gitnexus@latest mcp
|
||
```
|
||
|
||
**Cursor** (`~/.cursor/mcp.json` — global, works for all projects):
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"gitnexus": {
|
||
"command": "npx",
|
||
"args": ["-y", "gitnexus@latest", "mcp"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**OpenCode** (`~/.config/opencode/config.json`):
|
||
|
||
```json
|
||
{
|
||
"mcp": {
|
||
"gitnexus": {
|
||
"type": "local",
|
||
"command": ["gitnexus", "mcp"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Codex** (`~/.codex/config.toml` for system scope, or `.codex/config.toml` for project scope):
|
||
|
||
```toml
|
||
[mcp_servers.gitnexus]
|
||
command = "npx"
|
||
args = ["-y", "gitnexus@latest", "mcp"]
|
||
```
|
||
|
||
### CLI Commands
|
||
|
||
```bash
|
||
gitnexus setup # Configure MCP for your editors (one-time)
|
||
gitnexus analyze [path] # Index a repository (or update stale index)
|
||
gitnexus analyze --repair-fts # Fast path: rebuild/verify only FTS indexes on existing index data
|
||
gitnexus analyze --force # Full rebuild: re-parse + graph rebuild + FTS rebuild
|
||
gitnexus analyze --skills # Generate repo-specific skill files from detected communities
|
||
gitnexus analyze --skip-embeddings # Skip embedding generation (faster)
|
||
gitnexus analyze --skip-agents-md # Preserve custom AGENTS.md/CLAUDE.md gitnexus section edits
|
||
gitnexus analyze --skip-git # Index folders that are not Git repositories
|
||
gitnexus analyze --embeddings # Enable embedding generation (slower, better search)
|
||
gitnexus analyze --verbose # Log skipped files when parsers are unavailable
|
||
gitnexus analyze --worker-timeout 60 # Increase worker idle timeout for slow parses
|
||
gitnexus analyze --workers <n> # Parse worker pool size (default: cores-1, capped at 16; 0 = sequential)
|
||
gitnexus mcp # Start MCP server (stdio) — serves all indexed repos
|
||
gitnexus serve # Start local HTTP server (multi-repo) for web UI connection
|
||
gitnexus list # List all indexed repositories
|
||
gitnexus status # Show index status for current repo
|
||
gitnexus clean # Delete index for current repo
|
||
gitnexus clean --all --force # Delete all indexes
|
||
gitnexus wiki [path] # Generate repository wiki from knowledge graph
|
||
gitnexus wiki --model <model> # Wiki with custom LLM model (default: gpt-4o-mini)
|
||
gitnexus wiki --base-url <url> # Wiki with custom LLM API base URL
|
||
gitnexus publish # Notify the understand-quickly registry (opt-in, see below)
|
||
|
||
# Repository groups (multi-repo / monorepo service tracking)
|
||
gitnexus group create <name> # Create a repository group
|
||
gitnexus group add <group> <groupPath> <registryName> # Add a repo to a group. <groupPath> is a hierarchy path (e.g. hr/hiring/backend); <registryName> is the repo's name from the registry (see `gitnexus list`)
|
||
gitnexus group remove <group> <groupPath> # Remove a repo from a group by its hierarchy path
|
||
gitnexus group list [name] # List groups, or show one group's config
|
||
gitnexus group sync <name> # Extract contracts and match across repos/services
|
||
gitnexus group contracts <name> # Inspect extracted contracts and cross-links
|
||
gitnexus group query <name> <q> # Search execution flows across all repos in a group
|
||
gitnexus group status <name> # Check staleness of repos in a group
|
||
```
|
||
|
||
If `analyze` reports a worker parse timeout on a large or unusual repository, it keeps running and falls back safely. To give slow worker jobs more time, use `gitnexus analyze --worker-timeout 60` or set `GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=60000`. For very large files, `GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES` controls the worker job byte budget.
|
||
|
||
#### Environment variables
|
||
|
||
Most `analyze` knobs are also CLI flags (`--workers`, `--worker-timeout`, `--max-file-size`, `--verbose`). Use the env-var form when you'd otherwise repeat the same flag every run, or when invoking GitNexus from a long-running host (MCP server, eval-server, CI shell) that already manages its own environment. CLI flags take precedence over env vars; env vars take precedence over built-in defaults.
|
||
|
||
| Variable | Default | Effect | Tune when… |
|
||
| -------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| `GITNEXUS_WORKER_POOL_SIZE` | `cores - 1`, capped at 16 | Parse worker pool size. `0` disables the pool (sequential fallback). Equivalent to `--workers <n>`. | Constrained containers (cgroup CPU limits), CI runners with explicit quotas, or debugging a worker-only crash via `0`. |
|
||
| `GITNEXUS_PARSE_CHUNK_CONCURRENCY` | `2` | Number of chunks whose file contents may be read into memory in parallel while the pool dispatches the current chunk. Worker dispatch itself stays serial. | Repos large enough to chunk (multi-MB total source) where disk I/O is a measurable fraction of analyze wall-clock. |
|
||
| `GITNEXUS_VERBOSE` | unset | When `1`, enables verbose ingestion logs (skipped-file warnings, per-chunk throughput, parse-cache stats). Equivalent to `--verbose`. | Debugging an analyze that "completed" but seems to have missed files; tuning `--workers` / chunk concurrency against observable throughput. |
|
||
| `GITNEXUS_MAX_FILE_SIZE` | `512` (KB) | Walker skip threshold in KB. Hard cap is `32768` (tree-sitter buffer ceiling). Equivalent to `--max-file-size <kb>`. | Indexing repos with intentionally-large source files (generated parsers, vendored bundles) that should still be parsed. |
|
||
| `GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS` | `30000` | Worker idle timeout in milliseconds before retry/fallback. Equivalent to `--worker-timeout <seconds>` × 1000. | Slow-parsing files (large minified JS, deeply-nested TS types) that legitimately need more than 30s. |
|
||
| `GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES` | `8388608` (8 MB) | Per-job byte budget the pool will send to a worker in one `postMessage`. | Very large individual files; mostly diagnostic — bumping past 8 MB risks structured-clone memory pressure. |
|
||
| `GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT` | `3` | Max replacement spawns per worker slot before the slot is dropped from the active rotation. Bounds respawn loops on a chronically-crashing slot. | Hosts where a flaky worker should retry more (raise) or fail-fast (lower) before the slot is dropped. |
|
||
| `GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS` | `5 × subBatchTimeoutMs` | Total retry wall-time budget per job before quarantining. Combined with `timeoutBackoffFactor`, prevents exponentially-growing retries from stalling for hours. | Slow files that legitimately need long total retry windows; lower to fail-fast on stalls. |
|
||
| `GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD`| `max(3, poolSize)` | Per-slot consecutive deaths before the pool's circuit breaker trips. After tripping, every subsequent dispatch rejects until a fresh pool is created. | Hosts where a SIGSEGV-prone native grammar should trip the breaker sooner; CI runners that should fail loudly. |
|
||
| `GITNEXUS_CHUNK_BYTE_BUDGET` | `2097152` (2 MB) | Chunk boundary used for cache-key composition and dispatch. Smaller = finer-grained cache hits but more dispatch overhead. | Tuning incremental-analyze cache behavior on monorepos. |
|
||
| `GITNEXUS_NO_GITIGNORE` | unset | When set, skips `.gitignore` parsing. `.gitnexusignore` is still honored. | Indexing a repo whose `.gitignore` excludes files you actually want indexed (e.g., generated code committed for cross-repo lookup). |
|
||
| `GITNEXUS_SKIP_OPTIONAL_GRAMMARS` | unset | When `=1` strictly, skips vendored grammar materialize/build for `tree-sitter-dart`, `tree-sitter-proto`, and `tree-sitter-swift` at install time. | Installing on a host without a C++ toolchain or where Swift prebuilds don't match; you're willing to skip Dart/Proto/Swift parsing. |
|
||
|
||
#### Publishing to understand-quickly (opt-in)
|
||
|
||
[`looptech-ai/understand-quickly`](https://github.com/looptech-ai/understand-quickly) is a public registry of code-knowledge graphs that lists `gitnexus@1` as a first-class format. After registering your repo once (`npx @understand-quickly/cli add` or the [wizard](https://looptech-ai.github.io/understand-quickly/add.html)), `gitnexus publish` fires a single `repository_dispatch` event so the registry resyncs your entry on demand instead of waiting for the nightly job.
|
||
|
||
It is opt-in and a no-op without `UNDERSTAND_QUICKLY_TOKEN` — a fine-grained GitHub PAT with `Repository dispatches: write` on the registry repo. Nothing else happens; no graph file is uploaded. See the [protocol spec](https://github.com/looptech-ai/understand-quickly/blob/main/docs/integrations/protocol.md) for the full contract.
|
||
|
||
### What Your AI Agent Gets
|
||
|
||
**16 tools** exposed via MCP (11 per-repo + 5 group):
|
||
|
||
| Tool | What It Does | `repo` Param |
|
||
| ----------------- | ---------------------------------------------------------------- | ------------ |
|
||
| `list_repos` | Discover all indexed repositories | — |
|
||
| `query` | Process-grouped hybrid search (BM25 + semantic + RRF) | Optional |
|
||
| `context` | 360-degree symbol view — categorized refs, process participation | Optional |
|
||
| `impact` | Blast radius analysis with depth grouping and confidence | Optional |
|
||
| `detect_changes` | Git-diff impact — maps changed lines to affected processes | Optional |
|
||
| `rename` | Multi-file coordinated rename with graph + text search | Optional |
|
||
| `cypher` | Raw Cypher graph queries | Optional |
|
||
| `group_list` | List configured repository groups | — |
|
||
| `group_sync` | Extract contracts and match across repos/services | — |
|
||
| `group_contracts` | Inspect extracted contracts and cross-links | — |
|
||
| `group_query` | Search execution flows across all repos in a group | — |
|
||
| `group_status` | Check staleness of repos in a group | — |
|
||
|
||
> When only one repo is indexed, the `repo` parameter is optional. With multiple repos, specify which one: `query({query: "auth", repo: "my-app"})`.
|
||
|
||
**Resources** for instant context:
|
||
|
||
| Resource | Purpose |
|
||
| --------------------------------------- | ---------------------------------------------------- |
|
||
| `gitnexus://repos` | List all indexed repositories (read this first) |
|
||
| `gitnexus://repo/{name}/context` | Codebase stats, staleness check, and available tools |
|
||
| `gitnexus://repo/{name}/clusters` | All functional clusters with cohesion scores |
|
||
| `gitnexus://repo/{name}/cluster/{name}` | Cluster members and details |
|
||
| `gitnexus://repo/{name}/processes` | All execution flows |
|
||
| `gitnexus://repo/{name}/process/{name}` | Full process trace with steps |
|
||
| `gitnexus://repo/{name}/schema` | Graph schema for Cypher queries |
|
||
|
||
**2 MCP prompts** for guided workflows:
|
||
|
||
| Prompt | What It Does |
|
||
| --------------- | ------------------------------------------------------------------------- |
|
||
| `detect_impact` | Pre-commit change analysis — scope, affected processes, risk level |
|
||
| `generate_map` | Architecture documentation from the knowledge graph with mermaid diagrams |
|
||
|
||
**4 agent skills** installed to `.claude/skills/` automatically:
|
||
|
||
- **Exploring** — Navigate unfamiliar code using the knowledge graph
|
||
- **Debugging** — Trace bugs through call chains
|
||
- **Impact Analysis** — Analyze blast radius before changes
|
||
- **Refactoring** — Plan safe refactors using dependency mapping
|
||
|
||
**Repo-specific skills** generated with `--skills`:
|
||
|
||
When you run `gitnexus analyze --skills`, GitNexus detects the functional areas of your codebase (via Leiden community detection) and generates a `SKILL.md` file for each one under `.claude/skills/generated/`. Each skill describes a module's key files, entry points, execution flows, and cross-area connections — so your AI agent gets targeted context for the exact area of code you're working in. Skills are regenerated on each `--skills` run to stay current with the codebase.
|
||
|
||
---
|
||
|
||
## Multi-Repo MCP Architecture
|
||
|
||
GitNexus uses a **global registry** so one MCP server can serve multiple indexed repos. No per-project MCP config needed — set it up once and it works everywhere.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
subgraph CLI [CLI Commands]
|
||
Setup["gitnexus setup"]
|
||
Analyze["gitnexus analyze"]
|
||
Clean["gitnexus clean"]
|
||
List["gitnexus list"]
|
||
end
|
||
|
||
subgraph Registry ["~/.gitnexus/"]
|
||
RegFile["registry.json"]
|
||
end
|
||
|
||
subgraph Repos [Project Repos]
|
||
RepoA[".gitnexus/ in repo A"]
|
||
RepoB[".gitnexus/ in repo B"]
|
||
end
|
||
|
||
subgraph MCP [MCP Server]
|
||
Server["server.ts"]
|
||
Backend["LocalBackend"]
|
||
Pool["Connection Pool"]
|
||
ConnA["LadybugDB conn A"]
|
||
ConnB["LadybugDB conn B"]
|
||
end
|
||
|
||
Setup -->|"writes global MCP config"| CursorConfig["~/.cursor/mcp.json"]
|
||
Analyze -->|"registers repo"| RegFile
|
||
Analyze -->|"stores index"| RepoA
|
||
Clean -->|"unregisters repo"| RegFile
|
||
List -->|"reads"| RegFile
|
||
Server -->|"reads registry"| RegFile
|
||
Server --> Backend
|
||
Backend --> Pool
|
||
Pool -->|"lazy open"| ConnA
|
||
Pool -->|"lazy open"| ConnB
|
||
ConnA -->|"queries"| RepoA
|
||
ConnB -->|"queries"| RepoB
|
||
```
|
||
|
||
**How it works:** Each `gitnexus analyze` stores the index in `.gitnexus/` inside the repo (portable, gitignored) and registers a pointer in `~/.gitnexus/registry.json`. When an AI agent starts, the MCP server reads the registry and can serve any indexed repo. LadybugDB connections are opened lazily on first query and evicted after 5 minutes of inactivity (max 5 concurrent). If only one repo is indexed, the `repo` parameter is optional on all tools — agents don't need to change anything.
|
||
|
||
---
|
||
|
||
## Web UI (browser-based)
|
||
|
||
A client-side graph explorer and AI chat — your code never leaves your machine.
|
||
|
||
**Try it now:** [gitnexus.vercel.app](https://gitnexus.vercel.app) — run `npx gitnexus@latest serve` locally and the page auto-connects to your local backend.
|
||
|
||
<img width="2550" height="1343" alt="gitnexus_img" src="https://github.com/user-attachments/assets/cc5d637d-e0e5-48e6-93ff-5bcfdb929285" />
|
||
|
||
Or run the frontend locally:
|
||
|
||
```bash
|
||
git clone https://github.com/abhigyanpatwari/gitnexus.git
|
||
cd gitnexus/gitnexus-shared && npm install && npm run build
|
||
cd ../gitnexus-web && npm install
|
||
npm run dev
|
||
# Then in another terminal, start the backend the frontend connects to:
|
||
npx gitnexus@latest serve
|
||
```
|
||
|
||
## Docker
|
||
|
||
The official Docker setup ships **two signed images** orchestrated by `docker-compose.yaml`. Each image is published to both **GitHub Container Registry** (GHCR) and **Docker Hub** — same build, same digest, same Cosign signature — so pick whichever registry you prefer:
|
||
|
||
| Purpose | GHCR (default in `docker-compose.yaml`) | Docker Hub mirror |
|
||
| ---------------------------------------------------------------------- | --------------------------------------------- | ------------------------------ |
|
||
| CLI / `gitnexus serve` backend (HTTP API on port `4747`, MCP, indexer) | `ghcr.io/abhigyanpatwari/gitnexus:latest` | `akonlabs/gitnexus:latest` |
|
||
| Static web UI (port `4173`) | `ghcr.io/abhigyanpatwari/gitnexus-web:latest` | `akonlabs/gitnexus-web:latest` |
|
||
|
||
> **Heads-up — image rename.** Earlier releases published the web UI under
|
||
> `ghcr.io/abhigyanpatwari/gitnexus`. Starting with the introduction of the
|
||
> bundled backend, that slug now hosts the CLI/server image and the UI moved
|
||
> to `ghcr.io/abhigyanpatwari/gitnexus-web`. The previous tags remain
|
||
> available for pulling, but new versions are only published under the new
|
||
> slugs. Update your `docker run` / compose files accordingly (or just adopt
|
||
> the bundled compose).
|
||
|
||
### One-command setup
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
This starts the server on `http://localhost:4747` and the web UI on
|
||
`http://localhost:4173`. The UI auto-detects the server because the browser
|
||
runs on the host and reaches the container via the mapped port.
|
||
|
||
A named volume (`gitnexus-data`) persists the global registry, indexes, and
|
||
cloned repos at `/data/gitnexus` inside the server container. To make repos on
|
||
your host machine indexable, set `WORKSPACE_DIR` before bringing the stack up:
|
||
|
||
```bash
|
||
WORKSPACE_DIR=$HOME/code docker compose up -d
|
||
# Inside the server container the directory is mounted read-only at /workspace.
|
||
docker compose exec gitnexus-server gitnexus index /workspace/my-repo
|
||
```
|
||
|
||
### Direct `docker run`
|
||
|
||
```bash
|
||
# Server
|
||
docker run --rm -d \
|
||
--name gitnexus-server \
|
||
-p 4747:4747 \
|
||
-v gitnexus-data:/data/gitnexus \
|
||
ghcr.io/abhigyanpatwari/gitnexus:latest
|
||
|
||
# Web UI
|
||
docker run --rm -d \
|
||
--name gitnexus-web \
|
||
-p 4173:4173 \
|
||
ghcr.io/abhigyanpatwari/gitnexus-web:latest
|
||
```
|
||
|
||
Optional env file (override image tags, container names, ports, workspace dir):
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
docker compose --env-file .env up -d
|
||
```
|
||
|
||
### Versioning & supply-chain protection
|
||
|
||
The Docker images are version-locked to the npm package:
|
||
|
||
- Stable images are **only published from `vX.Y.Z` git tags** (via `docker.yml`
|
||
triggered directly by the tag push), and the workflow refuses to build unless
|
||
the tag exactly matches `gitnexus/package.json`'s version. So
|
||
`ghcr.io/abhigyanpatwari/gitnexus:1.6.2` (and its Docker Hub mirror
|
||
`akonlabs/gitnexus:1.6.2`) is byte-for-byte the same release as
|
||
`npm install gitnexus@1.6.2` — no drift, no floating builds from `main`.
|
||
Both registries receive the same digest from a single build step, so you can
|
||
pull from either and the signature verifies identically.
|
||
- Release-candidate images (e.g. `:1.7.0-rc.1`) are published alongside each
|
||
RC npm release. They are built by `publish.yml` calling `docker.yml`
|
||
as a reusable workflow after the RC tag is created and pushed.
|
||
- `:latest` is auto-promoted only from non-prerelease tags by the Docker
|
||
metadata action, so it always points at a real, npm-published version.
|
||
|
||
Both images are signed with [Cosign keyless signing][cosign-keyless] using the
|
||
workflow's GitHub OIDC identity, and shipped with build provenance and SBOM
|
||
attestations. **This is your protection against supply-chain attacks**: even if
|
||
an attacker republishes a same-named image elsewhere (or somehow pushes to a
|
||
typo-squatted registry), they cannot forge a Cosign signature tied to
|
||
`abhigyanpatwari/GitNexus`'s `docker.yml`. Always verify before pulling into
|
||
sensitive environments:
|
||
|
||
**Stable releases** — signed from the `v*` tag ref:
|
||
|
||
```bash
|
||
cosign verify ghcr.io/abhigyanpatwari/gitnexus:1.6.2 \
|
||
--certificate-identity-regexp '^https://github\.com/abhigyanpatwari/GitNexus/\.github/workflows/docker\.yml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$' \
|
||
--certificate-oidc-issuer https://token.actions.githubusercontent.com
|
||
|
||
# Same signature verifies the Docker Hub mirror (identical digest):
|
||
cosign verify docker.io/akonlabs/gitnexus:1.6.2 \
|
||
--certificate-identity-regexp '^https://github\.com/abhigyanpatwari/GitNexus/\.github/workflows/docker\.yml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$' \
|
||
--certificate-oidc-issuer https://token.actions.githubusercontent.com
|
||
```
|
||
|
||
The regex pins the certificate identity to this repo's `docker.yml` workflow
|
||
**run from a `v*` tag** — rejecting unsigned images, images signed by other
|
||
workflows, and images signed from unprotected refs. It is identical for both
|
||
registries because both sets of tags were signed at the same digest in one
|
||
workflow run.
|
||
|
||
**Release candidates** — signed from `refs/heads/main` (the caller's ref when
|
||
`publish.yml` invokes `docker.yml` as a reusable workflow):
|
||
|
||
```bash
|
||
cosign verify ghcr.io/abhigyanpatwari/gitnexus:1.7.0-rc.1 \
|
||
--certificate-identity 'https://github.com/abhigyanpatwari/GitNexus/.github/workflows/docker.yml@refs/heads/main' \
|
||
--certificate-oidc-issuer https://token.actions.githubusercontent.com
|
||
```
|
||
|
||
You can also inspect the build provenance and SBOM:
|
||
|
||
```bash
|
||
cosign download attestation ghcr.io/abhigyanpatwari/gitnexus:1.6.2 \
|
||
--predicate-type https://slsa.dev/provenance/v1
|
||
```
|
||
|
||
#### Kubernetes: enforce signatures at admission
|
||
|
||
For Kubernetes deployments, ship the bundled
|
||
[`ClusterImagePolicy`](deploy/kubernetes/cluster-image-policy.yaml) so the
|
||
[Sigstore policy-controller][policy-controller] rejects any GitNexus pod whose
|
||
image is not signed by this repo's `docker.yml` running from a `vX.Y.Z` tag —
|
||
the same identity the `cosign verify` snippet above pins.
|
||
|
||
```bash
|
||
# 1. Install the controller (one-time, cluster-wide)
|
||
helm repo add sigstore https://sigstore.github.io/helm-charts && helm repo update
|
||
helm install policy-controller -n cosign-system --create-namespace \
|
||
sigstore/policy-controller
|
||
|
||
# 2. Opt your namespace in
|
||
kubectl label namespace <your-ns> policy.sigstore.dev/include=true
|
||
|
||
# 3. Apply the policy
|
||
kubectl apply -f deploy/kubernetes/cluster-image-policy.yaml
|
||
```
|
||
|
||
After this, attempting to deploy an unsigned image — or one signed by anything
|
||
other than `abhigyanpatwari/GitNexus`'s `docker.yml` at a `v*` tag — fails the
|
||
admission webhook before a pod is ever created. This turns the verifiable
|
||
signature into an enforced policy, which is the supply-chain control most
|
||
clusters actually need.
|
||
|
||
[cosign-keyless]: https://docs.sigstore.dev/cosign/signing/overview/
|
||
[policy-controller]: https://docs.sigstore.dev/policy-controller/overview/
|
||
|
||
### Files
|
||
|
||
- [Dockerfile.web](Dockerfile.web) — builds `gitnexus-shared` and `gitnexus-web`, then serves the production frontend.
|
||
- [Dockerfile.cli](Dockerfile.cli) — builds the CLI/server (with its native deps) and runs `gitnexus serve --host 0.0.0.0`.
|
||
- [docker-compose.yaml](docker-compose.yaml) — starts both signed images side by side.
|
||
- [.env.example](.env.example) — overrides for image names, container names, ports, and the workspace mount.
|
||
|
||
The web UI uses the same indexing pipeline as the CLI but runs entirely in WebAssembly (Tree-sitter WASM, LadybugDB WASM, in-browser embeddings). It's great for quick exploration but limited by browser memory for larger repos.
|
||
|
||
**Local Backend Mode:** Run `gitnexus serve` and open the web UI locally — it auto-detects the server and shows all your indexed repos, with full AI chat support. No need to re-upload or re-index. The agent's tools (Cypher queries, search, code navigation) route through the backend HTTP API automatically.
|
||
|
||
---
|
||
|
||
## The Problem GitNexus Solves
|
||
|
||
Tools like **Cursor**, **Claude Code**, **Codex**, **Cline**, **Roo Code**, and **Windsurf** are powerful — but they don't truly know your codebase structure.
|
||
|
||
**What happens:**
|
||
|
||
1. AI edits `UserService.validate()`
|
||
2. Doesn't know 47 functions depend on its return type
|
||
3. **Breaking changes ship**
|
||
|
||
### Traditional Graph RAG vs GitNexus
|
||
|
||
Traditional approaches give the LLM raw graph edges and hope it explores enough. GitNexus **precomputes structure at index time** — clustering, tracing, scoring — so tools return complete context in one call:
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph Traditional["Traditional Graph RAG"]
|
||
direction TB
|
||
U1["User: What depends on UserService?"]
|
||
U1 --> LLM1["LLM receives raw graph"]
|
||
LLM1 --> Q1["Query 1: Find callers"]
|
||
Q1 --> Q2["Query 2: What files?"]
|
||
Q2 --> Q3["Query 3: Filter tests?"]
|
||
Q3 --> Q4["Query 4: High-risk?"]
|
||
Q4 --> OUT1["Answer after 4+ queries"]
|
||
end
|
||
|
||
subgraph GN["GitNexus Smart Tools"]
|
||
direction TB
|
||
U2["User: What depends on UserService?"]
|
||
U2 --> TOOL["impact UserService upstream"]
|
||
TOOL --> PRECOMP["Pre-structured response:
|
||
8 callers, 3 clusters, all 90%+ confidence"]
|
||
PRECOMP --> OUT2["Complete answer, 1 query"]
|
||
end
|
||
```
|
||
|
||
**Core innovation: Precomputed Relational Intelligence**
|
||
|
||
- **Reliability** — LLM can't miss context, it's already in the tool response
|
||
- **Token efficiency** — No 10-query chains to understand one function
|
||
- **Model democratization** — Smaller LLMs work because tools do the heavy lifting
|
||
|
||
---
|
||
|
||
## How It Works
|
||
|
||
GitNexus builds a complete knowledge graph of your codebase through a multi-phase indexing pipeline:
|
||
|
||
1. **Structure** — Walks the file tree and maps folder/file relationships
|
||
2. **Parsing** — Extracts functions, classes, methods, and interfaces using Tree-sitter ASTs
|
||
3. **Resolution** — Resolves imports, function calls, heritage, constructor inference, and `self`/`this` receiver types across files with language-aware logic
|
||
4. **Clustering** — Groups related symbols into functional communities
|
||
5. **Processes** — Traces execution flows from entry points through call chains
|
||
6. **Search** — Builds hybrid search indexes for fast retrieval
|
||
|
||
### Supported Languages
|
||
|
||
| Language | Imports | Named Bindings | Exports | Heritage | Type Annotations | Constructor Inference | Config | Frameworks | Entry Points |
|
||
| ---------- | ------- | -------------- | ------- | -------- | ---------------- | --------------------- | ------ | ---------- | ------------ |
|
||
| TypeScript | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||
| JavaScript | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ |
|
||
| Python | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||
| Java | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
|
||
| Kotlin | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
|
||
| C# | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||
| Go | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||
| Rust | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
|
||
| PHP | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||
| Ruby | ✓ | — | ✓ | ✓ | — | ✓ | — | ✓ | ✓ |
|
||
| Swift | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||
| C | — | — | ✓ | — | ✓ | ✓ | — | ✓ | ✓ |
|
||
| C++ | — | — | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
|
||
| Dart | ✓ | — | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
|
||
|
||
**Imports** — cross-file import resolution · **Named Bindings** — `import { X as Y }` / re-export tracking · **Exports** — public/exported symbol detection · **Heritage** — class inheritance, interfaces, mixins · **Type Annotations** — explicit type extraction for receiver resolution · **Constructor Inference** — infer receiver type from constructor calls (`self`/`this` resolution included for all languages) · **Config** — language toolchain config parsing (tsconfig, go.mod, etc.) · **Frameworks** — AST-based framework pattern detection · **Entry Points** — entry point scoring heuristics
|
||
|
||
---
|
||
|
||
## Tool Examples
|
||
|
||
### Impact Analysis
|
||
|
||
```
|
||
impact({target: "UserService", direction: "upstream", minConfidence: 0.8})
|
||
|
||
TARGET: Class UserService (src/services/user.ts)
|
||
|
||
UPSTREAM (what depends on this):
|
||
Depth 1 (WILL BREAK):
|
||
handleLogin [CALLS 90%] -> src/api/auth.ts:45
|
||
handleRegister [CALLS 90%] -> src/api/auth.ts:78
|
||
UserController [CALLS 85%] -> src/controllers/user.ts:12
|
||
Depth 2 (LIKELY AFFECTED):
|
||
authRouter [IMPORTS] -> src/routes/auth.ts
|
||
```
|
||
|
||
Options: `maxDepth`, `minConfidence`, `relationTypes` (`CALLS`, `IMPORTS`, `EXTENDS`, `IMPLEMENTS`), `includeTests`
|
||
|
||
### Process-Grouped Search
|
||
|
||
```
|
||
query({query: "authentication middleware"})
|
||
|
||
processes:
|
||
- summary: "LoginFlow"
|
||
priority: 0.042
|
||
symbol_count: 4
|
||
process_type: cross_community
|
||
step_count: 7
|
||
|
||
process_symbols:
|
||
- name: validateUser
|
||
type: Function
|
||
filePath: src/auth/validate.ts
|
||
process_id: proc_login
|
||
step_index: 2
|
||
|
||
definitions:
|
||
- name: AuthConfig
|
||
type: Interface
|
||
filePath: src/types/auth.ts
|
||
```
|
||
|
||
### Context (360-degree Symbol View)
|
||
|
||
```
|
||
context({name: "validateUser"})
|
||
|
||
symbol:
|
||
uid: "Function:validateUser"
|
||
kind: Function
|
||
filePath: src/auth/validate.ts
|
||
startLine: 15
|
||
|
||
incoming:
|
||
calls: [handleLogin, handleRegister, UserController]
|
||
imports: [authRouter]
|
||
|
||
outgoing:
|
||
calls: [checkPassword, createSession]
|
||
|
||
processes:
|
||
- name: LoginFlow (step 2/7)
|
||
- name: RegistrationFlow (step 3/5)
|
||
```
|
||
|
||
### Detect Changes (Pre-Commit)
|
||
|
||
```
|
||
detect_changes({scope: "all"})
|
||
|
||
summary:
|
||
changed_count: 12
|
||
affected_count: 3
|
||
changed_files: 4
|
||
risk_level: medium
|
||
|
||
changed_symbols: [validateUser, AuthService, ...]
|
||
affected_processes: [LoginFlow, RegistrationFlow, ...]
|
||
```
|
||
|
||
### Rename (Multi-File)
|
||
|
||
```
|
||
rename({symbol_name: "validateUser", new_name: "verifyUser", dry_run: true})
|
||
|
||
status: success
|
||
files_affected: 5
|
||
total_edits: 8
|
||
graph_edits: 6 (high confidence)
|
||
text_search_edits: 2 (review carefully)
|
||
changes: [...]
|
||
```
|
||
|
||
### Cypher Queries
|
||
|
||
```cypher
|
||
-- Find what calls auth functions with high confidence
|
||
MATCH (c:Community {heuristicLabel: 'Authentication'})<-[:CodeRelation {type: 'MEMBER_OF'}]-(fn)
|
||
MATCH (caller)-[r:CodeRelation {type: 'CALLS'}]->(fn)
|
||
WHERE r.confidence > 0.8
|
||
RETURN caller.name, fn.name, r.confidence
|
||
ORDER BY r.confidence DESC
|
||
```
|
||
|
||
---
|
||
|
||
## Wiki Generation
|
||
|
||
Generate LLM-powered documentation from your knowledge graph:
|
||
|
||
```bash
|
||
# Requires an LLM API key (OPENAI_API_KEY, etc.)
|
||
gitnexus wiki
|
||
|
||
# Use a custom model or provider
|
||
gitnexus wiki --model gpt-4o
|
||
gitnexus wiki --base-url https://api.anthropic.com/v1
|
||
|
||
# Force full regeneration
|
||
gitnexus wiki --force
|
||
|
||
|
||
# Increase the timeout or retries for large codebase or slow LLM providers
|
||
gitnexus wiki --timeout <seconds> # LLM request timeout in seconds (default: disabled)
|
||
gitnexus wiki --retries <n> # Max LLM retry attempts per request (default: 3)
|
||
|
||
# Change the language generation for wiki
|
||
gitnexus wiki --lang <lang> # Output language for generated documentation (e.g. english, chinese, spanish, japanese)
|
||
```
|
||
|
||
The wiki generator reads the indexed graph structure, groups files into modules via LLM, generates per-module documentation pages, and creates an overview page — all with cross-references to the knowledge graph.
|
||
|
||
---
|
||
|
||
## Tech Stack
|
||
|
||
| Layer | CLI | Web |
|
||
| ------------------- | ------------------------------------- | --------------------------------------- |
|
||
| **Runtime** | Node.js (native) | Browser (WASM) |
|
||
| **Parsing** | Tree-sitter native bindings | Tree-sitter WASM |
|
||
| **Database** | LadybugDB native | LadybugDB WASM |
|
||
| **Embeddings** | HuggingFace transformers.js (GPU/CPU) | transformers.js (WebGPU/WASM) |
|
||
| **Search** | BM25 + semantic + RRF | BM25 + semantic + RRF |
|
||
| **Agent Interface** | MCP (stdio) | LangChain ReAct agent |
|
||
| **Visualization** | — | Sigma.js + Graphology (WebGL) |
|
||
| **Frontend** | — | React 18, TypeScript, Vite, Tailwind v4 |
|
||
| **Clustering** | Graphology | Graphology |
|
||
| **Concurrency** | Worker threads + async | Web Workers + Comlink |
|
||
|
||
---
|
||
|
||
## Roadmap
|
||
|
||
### Actively Building
|
||
|
||
- [ ] **LLM Cluster Enrichment** — Semantic cluster names via LLM API
|
||
- [ ] **AST Decorator Detection** — Parse @Controller, @Get, etc.
|
||
- [ ] **Incremental Indexing** — Only re-index changed files
|
||
|
||
### Recently Completed
|
||
|
||
- [x] Constructor-Inferred Type Resolution, `self`/`this` Receiver Mapping
|
||
- [x] Wiki Generation, Multi-File Rename, Git-Diff Impact Analysis
|
||
- [x] Process-Grouped Search, 360-Degree Context, Claude Code Hooks
|
||
- [x] Multi-Repo MCP, Zero-Config Setup, 14 Language Support
|
||
- [x] Community Detection, Process Detection, Confidence Scoring
|
||
- [x] Hybrid Search, Vector Index
|
||
|
||
---
|
||
|
||
## Security & Privacy
|
||
|
||
- **CLI**: Everything runs locally on your machine. No network calls. Index stored in `.gitnexus/` (gitignored). Global registry at `~/.gitnexus/` stores only paths and metadata.
|
||
- **Web**: Everything runs in your browser. No code uploaded to any server. API keys stored in localStorage only.
|
||
- Open source — audit the code yourself.
|
||
|
||
---
|
||
|
||
## Acknowledgments
|
||
|
||
- [Tree-sitter](https://tree-sitter.github.io/) — AST parsing
|
||
- [LadybugDB](https://ladybugdb.com/) — Embedded graph database with vector support (formerly KuzuDB)
|
||
- [Sigma.js](https://www.sigmajs.org/) — WebGL graph rendering
|
||
- [transformers.js](https://huggingface.co/docs/transformers.js) — Browser ML
|
||
- [Graphology](https://graphology.github.io/) — Graph data structures
|
||
- [MCP](https://modelcontextprotocol.io/) — Model Context Protocol
|