Skip to content

Releases: JeelGajera/OpenInvar

v0.3.0

Choose a tag to compare

@JeelGajera JeelGajera released this 15 Sep 04:35
db25e0f

OpenInvar 0.3.0

OpenInvar builds a deterministic symbol relationship graph for a repository and gates CI on it. No model participates in graph construction or in any gating decision — identical input produces identical output, byte for byte, because you cannot gate CI on an opinion.

This release closes the gap between what the tool claimed and what it could show.

Seven of eight languages now resolve

Java and C# were promoted from Tier 2 to Tier 1. They parse the same as before; what changed is that imports, aliases and declared types now resolve, so gates may act on them.

Tier 1 — resolved Tier 2 — structural
TypeScript / JavaScript, Python, Rust, Go, C / C++, Java, C# Ruby

Ruby is the honest caveat rather than a backlog item: autoloading, monkey-patching and method_missing leave a large share of its references undecidable statically, so it may stay Tier 2 rather than be promoted on a claim the analysis cannot support.

C# needed three rules nothing else here needed — using names a namespace rather than a type, so the ambiguity Java reaches only through wildcards is C#'s ordinary case; enclosing namespaces are in scope with no using at all; and a partial class split across files is one type with the union of its members.

Enforcement

openinvar check reads openinvar.toml and returns one of four verdicts per rule — satisfied, violated, inconclusive, skipped. Only violated fails a gate. An undecided region reports as undecided rather than as a pass.

Ten rule kinds: forbid-dependency, forbid-reference, no-field-removal, max-fan-in, max-fan-out, layers, independence, no-cycles, requires-dependency, no-orphans, requires-test, naming-convention.

openinvar audit detects changes that look made to pass a check rather than to work, with four detectors: test-tampering, contract-erosion, dead-on-arrival and assertion-removal (a test that kept its coverage but stopped checking anything). Three more are held back with their reasons recorded in the source — a detector that cannot be built honestly is named as absent rather than shipped weak.

This repository gates its own CI on its own rules.

Honest measurement

status now reports two figures, because one of them was being read as something it is not:

Resolved           99.8% (6019 of 6031 edge(s))
References bound   69.5% (6019 of 8659 reference(s))
  2640 reference(s) named in source bound to nothing in the graph.

The first is the share of recorded edges that resolved. An edge exists only once something bound it, so a reference the analysis could not place leaves no trace — it never enters that denominator, and failing to bind more references makes the percentage go up. The second supplies the missing denominator.

An unbound reference is not automatically a defect: a type from a package whose source was never analysed is indistinguishable, to an adapter, from one it should have found. Read it as an upper bound on what is absent.

There is also now an evaluation against four real repositories nobody here wrote — rust-lang/log, spf13/cobra, pallets/click, google/gson — with thresholds fixed in eval/criteria.md before each run, and the runner and summariser kept in separate files so a threshold cannot move in the same edit that produces the result it judges. Determinism held 32 of 32 revisions byte-identical. Reference coverage came in at 63.2% against a 65% pass line; that is recorded as an investigate verdict with the investigation, not scored as a pass.

Also new

  • analyze --at <rev> — analyse the tree at a revision instead of the working tree, without disturbing the working graph.
  • openinvar context — a minimal working set for orienting on a symbol or a change.
  • openinvar tests <symbol> | --diff — which tests exercise a symbol, via real tests edges rather than filename guessing.
  • openinvar impact <file> — what depends on one file.
  • Two MCP tools, graph_diff and check_rules.
  • Agent hooks for Claude Code and others, a GitHub Action, and contributor documentation.

Upgrading

The project was renamed from graphyn. The binary is openinvar, the config is openinvar.toml, the crates are openinvar-*. Commands are otherwise unchanged.

The graph store moved to .openinvar/graph.db — a SQLite file, not a directory. There is no migration, deliberately: the graph is derived data that rebuilds in about a quarter of a second, so converting a cache would be wasted work. An old store directory is reported, not deleted — a read command names it and says to run openinvar analyze, and .graphyn/db is recognised too, so an upgrade from before the rename gets the same message rather than a bare "no graph found".

Snapshot format version 5. Older snapshots are read, with fields added since recorded as absent rather than as zero — "this graph does not know" and "this graph counted none" are different answers.

One binary per platform, carrying every language. The per-language Cargo features still work — cargo install openinvar-cli --no-default-features --features python builds a Python-only binary — but the released artifact no longer omits anything the README describes.

Install

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/JeelGajera/OpenInvar/master/install.sh | bash

# Windows (PowerShell)
irm https://raw.githubusercontent.com/JeelGajera/OpenInvar/master/install.ps1 | iex

# Cargo
cargo install openinvar-cli

Quick start

openinvar analyze . --snapshot HEAD      # record the graph before the change
openinvar audit . --base HEAD --head worktree   # what did the change actually do
openinvar check .                         # gate on the rules in openinvar.toml

Full detail in CHANGELOG.md, including the fixes and the limits each one left behind.

v0.2.0

Choose a tag to compare

@JeelGajera JeelGajera released this 16 Aug 11:19
aeebd0f

Graphyn v0.2.0 — Five languages, one graph 🌐

Graphyn is no longer TypeScript-only.

v0.2.0 adds Python, Rust, Go, and C/C++ adapters behind a shared dispatch layer, so mixed-language repositories can now be indexed in a single pass — with property resolution grounded in declared types across every adapter.

graphyn analyze ./my-repo

This now indexes .ts, .py, .rs, .go, .c, and .cpp together.

🚀 Language support

Language Extensions Resolves
TypeScript / JavaScript .ts .tsx .js .jsx .mts .cts .mjs .cjs tsconfig paths, barrel re-exports, decorator DI
Framework files .vue .svelte .astro Script blocks within the component
Python .py .pyi Relative imports, __init__ re-export chains, star imports, TYPE_CHECKING guards, Pydantic / Django / dataclass fields
Rust .rs Module tree, use groups and aliases, glob imports, trait impls, #[derive], macro token trees
Go .go Package imports via go.mod, structural interface satisfaction
C .c .h #include resolution, typedef aliases
C++ .cpp .cc .cxx .hpp .hxx .hh using aliases, base classes, namespace-qualified names

Every adapter attributes member access to the type a value was declared as. So payload.user_id is recorded against UserPayload regardless of what the variable is actually named.

✨ Added

  • Added five new crates:
    • graphyn-adapter-python
    • graphyn-adapter-rust
    • graphyn-adapter-go
    • graphyn-adapter-c
    • graphyn-adapter-dispatch
  • The dispatch layer routes files to the correct language adapter and runs adapter groups in parallel.
  • Added shared symbol-ID and AST traversal helpers to graphyn-core, replacing five per-adapter copies.
  • Added parse, resolution, and skip diagnostics across adapters. Pruned directories are now reported instead of silently disappearing.
  • Added a cross-language regression suite and polyglot fixtures.
  • Test coverage grew from 39 to 185 tests, replacing 27 assert!(true) stubs with real coverage.

🐛 Fixed

Property resolution

  • Property access was previously matched against a hardcoded variable name.
  • The new adapters compared receivers against the literal string "data", which meant property tracking failed for any other variable name in Rust, Go, and C/C++.
  • Receivers are now bound to declared types from parameters, let/var bindings, annotations, and declarators.
  • Struct fields no longer leak from one struct into another.

Imports & symbols

  • #include previously produced a graph with zero edges because includes became local_header::<name>, which add_relationship drops. Includes now resolve to the header's module symbol.
  • C struct names were incorrectly reported as ambiguous. A struct Foo *p parameter is a struct_specifier, but not a new definition; we no longer mint a symbol for every reference.
  • Go imports previously pointed at an arbitrary package member instead of the package itself.
  • Rust use paths now resolve through the declaring module and follow pub use chains instead of matching leaf names repository-wide.
  • Python now indexes the relevant symbol kinds so importing a function no longer fabricates a dependency that does not exist.
  • An alias equal to the symbol's own name is no longer treated as a rename, reducing noise around genuine renames.

Publishing

  • The crates.io publish job now publishes all ten crates in dependency order.
  • Previously, publishing could fail partway through after graphyn-core had already been released.

🔧 Changed

  • Graph construction order is deterministic again. Dispatch groups files using a stable ordering key instead of relying on HashMap iteration order.
  • AST traversal is now iterative and depth-bounded, preventing deeply nested input from overflowing a rayon worker's stack.
  • Unresolved edges are removed with a warning instead of being silently dropped.
  • env, gen, and proto are indexable again.
  • An explicit --include now overrides the built-in excludes.

⚠️ Known limits

A few limitations are worth calling out explicitly:

  • Imports are language-local. A Python module importing a TypeScript file through a build step is not linked.
  • Chained access only tracks the first receiver. In a.b.c, c is not attributed to the type of a.b.
  • C++ templates are parsed, not instantiated. vector<Foo> records a reference to Foo.
  • Go structural matching is per-package. Matching every method set against every interface repository-wide creates more noise than signal.
  • Rust macro bodies are token trees. Field access inside format! and similar macros is recovered by scanning tokens; macro-generated code is not expanded.

📦 Install

macOS / Linux

curl -fsSL https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.sh | bash

Windows

irm https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.ps1 | iex

Cargo

cargo install graphyn-cli

🔗 Full changelog

v0.1.3...v0.2.0

v0.1.3

Choose a tag to compare

@JeelGajera JeelGajera released this 09 May 13:06
13c493b

v0.1.3: The Performance & Dependency Injection Update ⚡

This is a massive update for Graphyn that brings up to a 20x performance increase for large repositories, first-class support for Dependency Injection (DI) frameworks (like NestJS/Angular), and critical stability fixes for Windows users.

✨ Highlights

  • Parallel Parsing: Dropped analysis time for 1,000+ file projects from ~10 minutes to under 30 seconds.
  • DI & Decorator Tracking: Graphyn now perfectly tracks this.service.method() property accesses originating from constructor-injected dependencies.
  • Rock-solid Windows Support: Fixed RocksDB path crashes and glob pattern matching on Windows machines.
  • Agent Setup Pack: Added pre-built .md rule files for Cursor, Claude, Copilot, and Gemini.

🚀 New Features

  • Constructor Injection Tracking: Graphyn now parses constructor parameters (e.g., constructor(private userRepo: UserRepository)) and accurately maps this.userRepo.findById() calls to the underlying class. This eliminates blind spots in DI-heavy TypeScript codebases.
  • Decorator Support: AST extraction now parses @Module({ providers: [...], controllers: [...] }) arrays, automatically creating UsesType dependency edges for framework wiring.
  • Method-Level Tracking: Queries like blast-radius and deps now accurately traverse individual method-level relationships instead of just falling back to the parent class.
  • Agent Setup Pack: Added the agent-configs/ directory containing out-of-the-box system instructions (AGENTS.md, .cursorrules, CLAUDE.md, etc.) to instantly teach your AI agents how to query Graphyn via MCP.

⚡ Performance

  • Parallel AST Parsing: Replaced sequential loops with rayon, maxing out all CPU cores to parse files simultaneously.
  • Zero-Syscall Probing: Replaced hundreds of thousands of expensive disk syscalls (.is_file()) with an O(1) memory lookup (HashSet), dramatically speeding up local import resolution.
  • Eager Barrel Expansion: Pre-computes and caches export * paths upfront, eliminating exponential lookup loops when resolving imports across massive barrel files.

🐛 Bug Fixes

  • Windows RocksDB Crash (CRITICAL): Safely strips \\?\ and \\?\UNC\ extended-path prefixes from Windows paths before they hit RocksDB, preventing mixed-separator crashes when writing to the DB LOG file.
  • Glob --include Filters (CRITICAL): Fixed an issue where the directory walker failed to descend into matching paths on Windows, resulting in 0 files parsed.
  • Zero-File Warnings: graphyn analyze now exits gracefully with a helpful warning and troubleshooting tip if your --include/--exclude filters result in 0 files.
  • Cleaned CLI Output: Removed ugly UNC path prefixes from terminal output on Windows.
  • Ambiguous Symbol UX: Improved error messages to explicitly suggest querying by ClassName if a method name query is ambiguous.
  • Intel Mac Installer: Updated the install script to clearly direct x86_64 macOS users to the cargo install fallback.

📦 How to Upgrade

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.sh | bash

Windows (PowerShell):

irm https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.ps1 | iex

Cargo:

cargo install graphyn-cli --git https://github.com/JeelGajera/graphyn --force

Full Changelog: v0.1.2...v0.1.3

v0.1.2

Choose a tag to compare

@JeelGajera JeelGajera released this 28 Apr 17:53
122b6e5

What's Changed - v0.1.2 🚀

  • feat(graphyn): add ESM and framework file support with durable re-export persistence by @JeelGajera in #3
  • remove stdout debug trace from re-export chain resolver
  • persist file re-export metadata in GraphSnapshot (v2) and restore on load
  • keep incremental graph updates in sync for file re-exports
  • support .mts/.cts/.mjs/.cjs across scanner, parser, resolver, tsconfig probing, and watch mode
  • add Vue/Svelte/Astro script extraction preprocessor with line-preserving blanking
  • extend import resolution probing to .vue/.svelte/.astro
  • add fixtures and tests for dist exclusion, ESM extensions, and framework support
  • update architecture and README support matrix

Installation:

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.sh | bash

# Windows (PowerShell)
irm https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.ps1 | iex

Full Changelog: v0.1.1...v0.1.2

v0.1.1

Choose a tag to compare

@JeelGajera JeelGajera released this 17 Apr 19:59
65a1d86

What's New 🚀

  • Automated Native Binaries: Graphyn is now compiled for Linux, macOS (Intel & Apple Silicon), and Windows via GitHub Actions explicitly wrapped in native .tar.gz and .zip payload structures for immediate distribution without build friction.
  • Agent Skill API (refresh_graph): Shipped a 4th native MCP Tool specifically built for AI coding agents giving them manual graph reloading mechanics alongside complete internal path filtering capabilities.
  • Decoupled Architecture: System-wide file filtering, directory crawling, and .gitignore integration have been abstracted natively into the orchestrators (cli + mcp), converting language adapters (like graphyn-adapter-ts) into pure semantic pipelines.

Frictionless Installers

Developers no longer require a cargo toolchain locally to execute Graphyn CLI or its MCP server locally. Universal bash and powershell upgrade/install scripts are officially mounted and supported.

  • Linux/Mac: curl -fsSL https://raw.githubusercontent.com/JeelGajera/graphyn/main/install.sh | bash
  • Windows: irm https://raw.githubusercontent.com/JeelGajera/graphyn/main/install.ps1 | iex

Full Changelog: v0.1.0...v0.1.1

v0.1.0

Choose a tag to compare

@JeelGajera JeelGajera released this 12 Apr 10:46
1b11be4

🚀 Graphyn v0.1.0

Understand the blast radius before you pull the trigger.

Graphyn is a code intelligence engine that models your codebase as a living graph of symbol relationships — so you (and your coding agents) know exactly what will break before making a change.

This is the first public release (v0.1.0) of the Graphyn ecosystem.


✨ What’s New

  • 🧠 Deterministic relationship graph engine (Rust)

  • 🔗 Alias-aware dependency tracking (import { A as B })

  • 🎯 Property-level access tracking (.userId, .timestamp, etc.)

  • ⚡ Fast queries (<100ms target) using in-memory graph

  • 📦 RocksDB persistence for near-instant startup

  • 🛠️ CLI tooling

    • analyze, query, watch, serve, status
  • 🤖 MCP server support (works with Cursor, Claude Code, etc.)

  • 🌐 TypeScript & JavaScript support (v1) via tree-sitter adapter

  • 🧪 Real-world bug coverage

    • Detects deep alias-import issues that typical tools miss

🧩 Why Graphyn?

Most tools search code.

Graphyn understands relationships.

It answers questions like:

  • What breaks if I change this class?
  • Where is this symbol used — even under aliases?
  • What depends on this function?

This solves real production issues like:

import { UserPayload as ResponseModel } from '../../../models/user_payload'

Traditional tools miss this.

Graphyn doesn’t.


⚡ Quick Start

# Install
cargo install graphyn-cli

# Index your repo
graphyn analyze ./my-repo

# Query blast radius
graphyn query blast-radius UserPayload

# Start MCP server (for agents)
graphyn serve --stdio

🧱 Workspace Overview

This release includes:

  • graphyn-core → graph engine
  • graphyn-adapter-ts → TS/JS parser
  • graphyn-cli → developer interface
  • graphyn-mcp → agent integration (MCP server)
  • graphyn-store → persistence layer

🧪 Status

v0.1.0 — Initial stable release

  • ✅ Core graph engine
  • ✅ Alias resolution (critical feature)
  • ✅ Property-level tracking
  • ✅ CLI + MCP integration
  • ✅ TypeScript/JavaScript support

🔮 What’s Next

  • Python adapter (v2)
  • More language support (Rust, Go, Java)
  • VS Code extension
  • Web dashboard
  • Advanced analysis (data flow, cross-project graphs)

📜 License

Apache 2.0


💡 Final Note

Graphyn exists because of a real problem:

A deeply nested aliased import broke production — and no tool caught it.

Graphyn is built to never miss that again.


Full Changelog: https://github.com/JeelGajera/graphyn/commits/v0.1.0