Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
6e761f2
fix(diagnostics): separate external reference edges
DevChiniwala Sep 16, 2026
7d2344f
Namespace an external import on its package root, not the specifier
ayushcodes10 Sep 16, 2026
3e9d22f
Add a unit test for plain package subpath resolution
ayushcodes10 Sep 16, 2026
7aebd99
Add a unit test for scoped package subpath resolution
ayushcodes10 Sep 16, 2026
23d8a87
Add an end to end regression test for the reporter's exact repro
ayushcodes10 Sep 16, 2026
a5ab200
Compute the graph.json community reconstruction unconditionally
ayushcodes10 Sep 14, 2026
06ff9d0
Prefer the fresh reconstruction when the sidecar is stale
ayushcodes10 Sep 14, 2026
18cae25
Add regression test for the stale sidecar html export path
ayushcodes10 Sep 14, 2026
bafe75b
Add regression test for stale sidecar cohesion recomputation
ayushcodes10 Sep 14, 2026
11d91c8
Add negative control test for a sidecar that still matches
ayushcodes10 Sep 14, 2026
9d747f4
Compare partition structure, not just the node id set, for staleness
ayushcodes10 Sep 16, 2026
1ca2e4b
Recompute god node data directly on the stale sidecar path
ayushcodes10 Sep 16, 2026
835abad
Index qualified labeled C++ nodes for a second chance call lookup
ayushcodes10 Sep 16, 2026
64fa746
Wire the second chance lookup into the scoped call branch
ayushcodes10 Sep 16, 2026
d77141e
Add a regression test for the qualified only fallback
ayushcodes10 Sep 16, 2026
ffa0f52
Add a regression test for the god node guard on the fallback
ayushcodes10 Sep 16, 2026
3507b4a
Add a variable for the Kotlin object member call receiver
ayushcodes10 Sep 16, 2026
2595d62
Capture the receiver for a two segment Kotlin navigation call
ayushcodes10 Sep 16, 2026
492ea4f
Thread the object receiver into raw_calls for Kotlin
ayushcodes10 Sep 16, 2026
095530a
Add and register the Kotlin object member call resolver
ayushcodes10 Sep 16, 2026
4afdfcb
Add regression tests for the cross file Kotlin object member call fix
ayushcodes10 Sep 16, 2026
4e81136
test(kotlin): cover companion members + incremental persistence (#169…
safishamsi Sep 17, 2026
41c0407
docs(diagnostics): note ref_ external refs and external=True stubs ar…
safishamsi Sep 17, 2026
e96235c
fix: reconcile Markdown link suffixes
oleksii-tumanov Sep 17, 2026
bdb605f
fix: preserve Markdown links on parse failure
oleksii-tumanov Sep 17, 2026
01ae1ed
Index JavaScript in inline script blocks of a PHP file
ayushcodes10 Sep 17, 2026
cc80351
Add regression tests for the PHP inline script extraction
ayushcodes10 Sep 17, 2026
96e653c
Drop edges of a JS node dropped for colliding with a PHP node
ayushcodes10 Sep 17, 2026
f97cf99
Add a regression test for the PHP JS id collision edge drop
ayushcodes10 Sep 17, 2026
3e87d86
fix: resolve generic Rust self calls
oleksii-tumanov Sep 18, 2026
1e09e8b
Preserve Terraform attributes during extraction
hopstreax Sep 17, 2026
650f47f
fix(terraform): redact secret-named attribute values before they hit …
safishamsi Sep 18, 2026
b9cd957
release: 0.9.64 — terraform block attributes (with secret redaction),…
safishamsi Sep 18, 2026
d3d2538
docs: align repository links and translated README logos
Abdul535 Sep 20, 2026
a9450a5
fix(go): extract method requirements declared in an interface body
rajatnagda45 Sep 19, 2026
fc8e9e1
fix(swift): extract method requirements declared in a protocol body
rajatnagda45 Sep 19, 2026
c049ea0
fix(java): attach enum body members to the enum, not the file
rajatnagda45 Sep 19, 2026
199d741
fix(verilog): link a module instantiation to the local definition, no…
rajatnagda45 Sep 19, 2026
4a4fd97
Scope JS let/const bindings to their own block, not the function
ayushcodes10 Sep 19, 2026
873b5eb
Add regression tests for block scoped let/const shadowing
ayushcodes10 Sep 19, 2026
87a8277
Fix fail-closed AST ownership eviction
hopstreax Sep 20, 2026
c99c3a6
Strengthen fail-closed regression assertions
hopstreax Sep 20, 2026
2ff5db3
test(watch): drop two broken #3695 symlink tests that never trigger f…
safishamsi Sep 20, 2026
5f6b2a2
fix: security pillow updated to 12.3.0 for cve-2026-54058
viral-antuit Sep 20, 2026
aa5b334
Update link for graphify Enterprise
Abdul535 Sep 20, 2026
9a06e95
docs: add GitHub issue and pull request templates
Abdul535 Sep 20, 2026
785ee5a
Fix HTML entity encoding in graph tooltips
hopstreax Sep 19, 2026
124c263
fix(export): prevent vis-network stack overflow crash on HTML render
sanjaiyan-dev Sep 20, 2026
86d8aad
fix(export): complete the vis-network crash fix and pin the tooltip X…
safishamsi Sep 20, 2026
7ca736c
release: 0.9.65 — Pillow CVE floor, Go/Swift/Java/Verilog extractor f…
safishamsi Sep 20, 2026
20a20d3
test(ts): de-flake the normalizer scaling test that reddened v8 CI
safishamsi Sep 20, 2026
5da2da3
fix(build): preserve higher confidence on same-relation edge collisio…
shobhitagnihotri69 Sep 21, 2026
ab568c8
feat: add COBOL language extractor
Abdul535 Sep 21, 2026
ebe1f32
feat: add VB.NET language extractor
Abdul535 Sep 21, 2026
d68d601
feat: add R language extractor
Abdul535 Sep 21, 2026
9f069ea
feat: add Solidity language extractor
Abdul535 Sep 21, 2026
89c27c7
feat: add Erlang language extractor
Abdul535 Sep 21, 2026
3097e9d
fix(build): deduplicate spec-conformant method nodes and aliases (#3705)
shobhitagnihotri69 Sep 21, 2026
0e855f3
fix: complete the Solidity/method-ghost/Erlang review items (#3716, #…
safishamsi Sep 21, 2026
6fdc26d
build: lock the new grammar deps for the R/Erlang/Solidity/VB.NET ext…
safishamsi Sep 22, 2026
bda82f9
fix(go): preserve interface method signature references
oleksii-tumanov Sep 22, 2026
f7bc904
Preserve case-only interface signature owners
oleksii-tumanov Sep 22, 2026
081004f
fix(go): repoint intra-module imports_from edges from go_pkg_ sinks t…
carterko23 Sep 22, 2026
3d1a03e
Pin PYTHONHASHSEED for update, extract, cluster only and label
ayushcodes10 Sep 22, 2026
890856f
Add regression tests for the hash seed pinning fix
ayushcodes10 Sep 22, 2026
b11b035
Degrade instead of aborting when cargo introspection finds no manifest
ayushcodes10 Sep 22, 2026
137ead6
Add regression tests for cargo extraction with a missing manifest
ayushcodes10 Sep 22, 2026
165a7da
Discover a Cargo.toml in a subdirectory when none sits at the scan root
ayushcodes10 Sep 22, 2026
9b42507
Add regression tests for cargo subdirectory manifest discovery
ayushcodes10 Sep 22, 2026
7a508a7
fix(cargo): resolve inherited workspace dependency identity
oleksii-tumanov Sep 22, 2026
a1d2318
fix(serve): get_node/get_neighbors accept node_id/id, not just label
Sep 21, 2026
f07423b
Fix CRLF corruption and a bare substring idempotency guard in install
ayushcodes10 Sep 22, 2026
d8dd477
Add regression tests for the install CRLF and idempotency guard fix
ayushcodes10 Sep 22, 2026
1db41f0
fix(labeling): retry and report partial community labels
Ha1baraA11 Sep 21, 2026
78b42df
fix(build): fall back from stale graphify root
Ha1baraA11 Sep 21, 2026
5439e6d
Resolve the graphify root marker when GRAPHIFY_OUT is shared and abso…
ayushcodes10 Sep 22, 2026
f49ec50
Add regression tests for the shared output graphify root marker fix
ayushcodes10 Sep 22, 2026
a5957aa
release: 0.9.66 — five new language extractors (COBOL/VB.NET/R/Solidi…
safishamsi Sep 22, 2026
d9d4756
Re exec the hash seed pin as a module, not by replaying argv[0]
ayushcodes10 Sep 23, 2026
6a1a432
Update hash seed tests for the module based re exec and add a regression
ayushcodes10 Sep 23, 2026
7b2ac86
fix(terraform): redact secrets nested inside list values, not just ma…
abhay-codes07 Sep 22, 2026
3454890
fix(export): stop rewriting unchanged wiki/Obsidian pages on every ru…
abhay-codes07 Sep 22, 2026
2944b2d
fix: resolve absolute Python package imports
Ha1baraA11 Sep 22, 2026
1c12006
fix: resolve Python imports within scan root
Ha1baraA11 Sep 23, 2026
45e9af9
fix: guard ambiguous absolute Python imports
Ha1baraA11 Sep 23, 2026
3792ff1
fix: preserve loose sibling import resolution
Ha1baraA11 Sep 23, 2026
310b317
fix: retract provisional package import edges
hopstreax Sep 23, 2026
f2b65b7
fix(python): reconcile #3784 phantom-edge retraction with #3729 packa…
safishamsi Sep 23, 2026
cd3fd94
feat(extract): support PHP closures (#3409)
nikhilsaxena04 Sep 9, 2026
2c172e4
fix(extract): stable closure naming for PHP (#3409)
nikhilsaxena04 Sep 10, 2026
8227c46
fix(extract): robust PHP nested routing closure extraction (#3409)
nikhilsaxena04 Sep 10, 2026
435f5a8
refactor(extract): hoist PHP route helper to module level (#3409)
nikhilsaxena04 Sep 10, 2026
10f144d
fix(php): match correct AST node names and scan nested closures
nikhilsaxena04 Sep 23, 2026
904deae
fix(php): prevent non-route closures from adopting parent route names
nikhilsaxena04 Sep 23, 2026
4c74bd6
fix(php): prevent closure fallback leak and support fluent routing pr…
nikhilsaxena04 Sep 23, 2026
95dd8cf
fix(php): allow relative prefixes in route groups and correctly fail …
nikhilsaxena04 Sep 23, 2026
793aca6
test(php): cover file-scope, no-duplicate, and method-scope closures …
safishamsi Sep 23, 2026
4c73561
release: 0.9.67 — Windows hash-seed re-exec fix, PHP closures, absolu…
safishamsi Sep 23, 2026
7613f16
feat: bridge hook-guard policy into native OMP hooks
andrebrait Sep 11, 2026
0f62071
test(omp): keep the embedded package version in sync
andrebrait Sep 15, 2026
1f10ac0
test(omp): run the native bridge tests in CI
andrebrait Sep 16, 2026
29dd29b
fix(omp): nudge every qualifying tool call via its persisted tool result
andrebrait Sep 18, 2026
c22ebca
docs(omp): match guidance wording to per-call tool-result delivery
andrebrait Sep 18, 2026
81c9d02
fix(omp): import isReadableUrlPath from its current pi-tui location
andrebrait Sep 20, 2026
3d6538f
ci(omp): run the OMP bridge tests against latest OMP too (advisory)
andrebrait Sep 20, 2026
7307ba3
fix(hooks): stop URL-shaped read targets from bypassing the out-of-pr…
andrebrait Sep 20, 2026
8298103
refactor(omp): simplify the bridge now that the guard defends itself
andrebrait Sep 20, 2026
d01db79
fix(omp): drop unresolvable @oh-my-pi/pi-tui import from the bridge
andrebrait Sep 20, 2026
7d5717f
fix(omp): use resolveReadPath, not the async sibling missing from old…
andrebrait Sep 20, 2026
03567c9
fix(hooks): keep a remote file:// authority from aliasing an in-proje…
andrebrait Sep 20, 2026
ec6bdee
fix(omp): treat every file:// authority but local as remote in isRemote
andrebrait Sep 20, 2026
3a07573
ci: stop executing an unpinned latest OMP install in the advisory step
andrebrait Sep 20, 2026
ed70c8b
build(omp): align the embedded package with Graphify 0.9.65
andrebrait Sep 22, 2026
96d155e
build(omp): align the embedded package with Graphify 0.9.67
andrebrait Sep 23, 2026
25e46e5
fix(omp): deliver hook-guard guidance as a labelled system reminder
andrebrait Sep 24, 2026
1bd2299
feat(install): add the omp platform for Oh My Pi skill installs
andrebrait Sep 24, 2026
a0646f5
Merge branch 'feat/omp-platform'
andrebrait Sep 24, 2026
0fd7486
fix(install): resolve the omp subcommand collision with the plugin in…
andrebrait Sep 24, 2026
bb628ac
fix(omp): stop importing isInternalUrlPath, private since OMP 18.3.1
andrebrait Sep 26, 2026
23aefef
Revert "fix(omp): stop importing isInternalUrlPath, private since OMP…
andrebrait Sep 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Bug report
description: Report incorrect behavior, a crash, or a regression.
title: "[Bug]: "
labels:
- bug
body:
- type: markdown
attributes:
value: |
Please search existing issues first. Include the smallest reproducible example you can.

- type: textarea
id: description
attributes:
label: What happened?
description: Describe the actual behavior and the behavior you expected.
validations:
required: true

- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Include commands, input files, and the smallest useful example.
render: shell
validations:
required: true

- type: textarea
id: output
attributes:
label: Error output or graph output
description: Paste the relevant traceback, diagnostic, or incorrect result.
render: text
validations:
required: true

- type: input
id: version
attributes:
label: Graphify version
placeholder: "0.9.64"

- type: input
id: environment
attributes:
label: Environment
description: Include operating system, Python version, and installation method.
placeholder: "macOS 15, Python 3.12, uv tool install"

- type: textarea
id: additional
attributes:
label: Additional context
description: Add related files, screenshots, or links if they help explain the issue.
11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
blank_issues_enabled: true
contact_links:
- name: Security policy
url: https://github.com/Graphify-Labs/graphify/security/policy
about: Please report vulnerabilities privately using the security policy.
- name: 📖 Documentation
url: https://github.com/Graphify-Labs/graphify/blob/v8/README.md
about: Check the README and docs before opening an issue.
- name: 🤝 Contributing guide
url: https://github.com/Graphify-Labs/graphify/blob/v8/README.md#development-setup
about: Read the development and contribution guidelines before opening a pull request.
54 changes: 54 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Feature request
description: Suggest an improvement or new capability.
title: "[Feature]: "
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
Please search existing issues first and describe the user problem before proposing an implementation.

- type: textarea
id: problem
attributes:
label: Problem or use case
description: What are you trying to do that Graphify cannot do today?
validations:
required: true

- type: textarea
id: proposal
attributes:
label: Proposed solution
description: Describe the expected behavior, command, API, or workflow.
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: What other approaches or workarounds did you consider?

- type: dropdown
id: area
attributes:
label: Area
options:
- Extraction or language support
- Graph building or querying
- CLI or installation
- Skills or assistant integrations
- Documentation
- Performance
- Security
- Developer experience or CI
validations:
required: true

- type: textarea
id: context
attributes:
label: Additional context
description: Add examples, links, or sample input where useful.
29 changes: 29 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## What does this PR do?

<!-- Describe the problem and the change. Link the relevant issue when one exists. -->


## Type of change

- [ ] Bug fix
- [ ] New feature
- [ ] Documentation
- [ ] Tests or CI
- [ ] Refactor
- [ ] Security fix

## How was this tested?

<!-- Include the commands you ran and any platform-specific checks. -->

```text

```

## Graphify-specific checklist

- [ ] I added or updated tests for behavior changes.
- [ ] I updated documentation or confirmed that no documentation is needed.
- [ ] I updated generated skill artifacts when changing their source fragments.
- [ ] I considered compatibility across supported Python versions.
- [ ] I confirmed that no API keys, generated graph data, or local-only files are included.
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,71 @@ jobs:
uv run --frozen graphify --help
uv run --frozen graphify install

omp-bridge:
# tests/omp.test.ts drives the real OMP extension: bun resolves the
# path-utils helpers it imports from the pinned @oh-my-pi/pi-coding-agent
# devDependency in graphify/omp/ (the only package the host provides;
# graphify/omp/index.ts vendors isReadableUrlPath locally instead of
# importing it from @oh-my-pi/pi-tui, which the host never resolves), and
# the policy assertions run against the real installed Python CLI, so
# this job needs both toolchains.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: "3.12"

- name: Install bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: uv sync --frozen

- name: Install OMP extension dependencies
run: bun install --frozen-lockfile
working-directory: graphify/omp

- name: Run OMP bridge tests
run: GRAPHIFY_TEST_CLI=$PWD/.venv/bin/graphify bun test tests/omp.test.ts

- name: Check for upstream symbol moves (advisory, no execution)
# The frozen run above only proves the bridge works against the
# exact pinned version. Upstream OMP has moved exported symbols
# between minor releases before (isReadableUrlPath moved from
# pi-coding-agent to pi-tui) without the frozen lockfile ever seeing
# it; index.ts now vendors that predicate locally instead of
# tracking whichever package currently exports it. This step used
# to install @latest AND execute the whole suite against it --
# unpinned, mutable third-party code running on every CI invocation.
# It now only downloads the published package (--ignore-scripts:
# no install hooks run) and statically compares index.ts's imported
# path-utils symbols against that file's declared exports as plain
# text -- the downloaded code is never imported or executed, but a
# future symbol move still surfaces here.
# continue-on-error: an unrelated upstream release must not block a
# merge; the frozen run above stays the blocking gate.
continue-on-error: true
run: |
bun add --cwd graphify/omp -d @oh-my-pi/pi-coding-agent@latest --ignore-scripts
bun -e '
const fs = require("node:fs");
const index = fs.readFileSync("graphify/omp/index.ts", "utf8");
const block = index.match(/import\s*{([^}]+)}\s*from\s*"@oh-my-pi\/pi-coding-agent\/tools\/path-utils"/);
if (!block) throw new Error("no path-utils import block found in index.ts");
const imported = block[1].split(",").map((s) => s.trim()).filter(Boolean);
const source = fs.readFileSync("graphify/omp/node_modules/@oh-my-pi/pi-coding-agent/src/tools/path-utils.ts", "utf8");
const exported = new Set([...source.matchAll(/^export\s+(?:async\s+function|function)\s+(\w+)/gm)].map((m) => m[1]));
const missing = imported.filter((name) => !exported.has(name));
if (missing.length) {
console.error(`@oh-my-pi/pi-coding-agent@latest no longer exports: ${missing.join(", ")}`);
process.exit(1);
}
console.log(`ok: every imported symbol is exported by @latest (${imported.join(", ")})`);
'

security-scan:
# The dev deps include bandit and pip-audit. Run them in CI so a new
# HIGH-severity finding or vulnerable dependency is caught on the PR that
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ paper/

# macOS Finder metadata
.DS_Store

# OMP extension test dependency tree (graphify/omp)
graphify/omp/node_modules/

# Local symlink for the root-level bun tests (temporary, per AGENTS.md)
/node_modules
52 changes: 51 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,55 @@
# Changelog

Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases)
Full release notes with details on each version: [GitHub Releases](https://github.com/Graphify-Labs/graphify/releases)

## 0.9.67 (2026-09-23)

- Fix: the PYTHONHASHSEED determinism pin (0.9.66) now re-execs via `python -m graphify` instead of replaying `argv[0]`, fixing a Windows regression where `update`/`extract`/`cluster-only`/`label` failed to re-launch through the console-script `.exe` launcher (#3780, thanks @ayushcodes10).
- Feature: PHP closures are now extracted — an anonymous `function(){…}`, an arrow `fn()=>…`, or a closure passed as an argument now produces a node and its inner calls are captured, in all positions including file scope. Route-definition closures get a semantic `VERB /path` name (composing nested `group()` prefixes); other closures get a stable per-scope ordinal (#3461, #3409, thanks @nikhilsaxena04).
- Fix: absolute Python package imports (`import pkg.sub`, `from pkg.sub import x`) now resolve to the local package/module node within the scan root, reusing the canonical resolver (bounded walk, PEP 420 namespace handling); an ambiguous module name across scanned trees fails closed rather than binding arbitrarily (#3729, thanks @Ha1baraA11).
- Fix: a package/module name collision (`pkg/` package alongside a `pkg.py` module) no longer produces a phantom import cycle — the spurious provisional edge is retracted while genuine package-init and submodule edges are preserved (#3784, #3777, thanks @hopstreax).
- Fix: Terraform secret redaction now also covers secrets nested inside list values (`configs = [{ password = "…" }]`), not just maps (#3762, #3644 follow-up, thanks @abhay-codes07).
- Fix: `export` no longer rewrites unchanged wiki/Obsidian pages on every run — a page whose content is identical is left untouched (stable mtimes, clean git/Obsidian sync), while changed and new pages still write and orphaned pages are still swept (#3760, #3060, thanks @abhay-codes07).

## 0.9.66 (2026-09-22)

- Feature: five new language extractors — **COBOL** (`.cbl`/`.cob`/`.cobol`/`.cpy`; programs, paragraphs, `PERFORM`/`CALL`/`COPY`, pure-regex, no new dependency) (#3713, thanks @Abdul535), **VB.NET** (`.vb`; case-insensitive types/methods, `Inherits`/`Implements`/`Handles`) (#3717, thanks @Abdul535), **R** (`.r`/`.R`; assignment-form function defs, `library`/`source`, S4/R6 classes) (#3715, thanks @Abdul535), **Solidity** (`.sol`; contracts/interfaces/libraries, `is` inheritance, imports, modifiers) (#3716, thanks @Abdul535), and **Erlang** (`.erl`/`.hrl`/`.escript`; modules, functions by arity, behaviours, local + remote `foo:bar()` calls) (#3714, thanks @Abdul535). The R and Erlang grammars ship via the `r`/`erlang` extras (they have no standalone PyPI wheel); Solidity and VB.NET have their own extras.
- Feature: Go interface method requirements now resolve to the interface, and their parameter/return types emit `references` edges (#3672, #3737, thanks @rajatnagda45, @oleksii-tumanov).
- Feature: a Rust `self.method()` call resolves across files for simple generic impls (`impl<T> Foo<T>`) (#3653, thanks @oleksii-tumanov).
- Fix: `graph.json` is now deterministic across runs — `update`/`extract`/`cluster-only`/`label` pin `PYTHONHASHSEED` via a one-time re-exec, so hash-seed-sensitive community detection (Leiden/Louvain) produces identical output run-to-run and matches hook-triggered rebuilds (#3743, #3641, thanks @ayushcodes10).
- Fix: a same-relation edge collision now keeps the higher-confidence edge (EXTRACTED over INFERRED) instead of resolving by arrival order (#3711, thanks @shobhitagnihotri69).
- Fix: a spec-conformant method-node duplicate (dropped class segment / leading dot) is now deduplicated onto its canonical AST node, gated on a method-shaped label and a single unambiguous candidate (#3719, #3705, thanks @shobhitagnihotri69).
- Fix: intra-module Go `imports_from` edges now repoint onto the imported package's real file nodes instead of dangling at a `go_pkg_` sink; external/stdlib imports stay external (#3748, thanks @carterko23).
- Fix: Cargo introspection discovers a `Cargo.toml` in a subdirectory when none sits at the scan root (e.g. Tauri's `src-tauri/`), degrades gracefully instead of aborting the whole extraction when no manifest is found, and resolves `workspace = true` inherited dependency identity from `[workspace.dependencies]` (#3740, #3739, thanks @ayushcodes10; #3734, thanks @oleksii-tumanov).
- Fix: MCP `get_node`/`get_neighbors` now accept the node identifier under `node_id`/`id`, not only `label`, so agents that spell the argument differently no longer get a missing-argument error (#3725, thanks @ahm3dwasim).
- Fix: `graphify install` no longer corrupts line endings (writes preserve the file's existing EOLs instead of rewriting to CRLF on Windows) and re-install is properly idempotent (a marker-bounded replace instead of a bare substring check) (#3741, #3668, thanks @ayushcodes10).
- Fix: community labeling retries a valid-but-truncated LLM response and reports how many communities kept a structural fallback name, instead of silently leaving them unlabeled (#3708, thanks @Ha1baraA11).
- Fix: a stale `.graphify_root` marker (moved/deleted/symlink-loop target) is now ignored with a fall-back to the graph's directory, and the marker value resolves to an absolute path when `GRAPHIFY_OUT` is a shared absolute directory (#3707, thanks @Ha1baraA11; #3735, #3375, thanks @ayushcodes10).

## 0.9.65 (2026-09-20)

- Security: the `svg`/`all` extras now floor Pillow at `>=12.3.0` for CVE-2026-54058 (Pillow was pulled in transitively via matplotlib). Note: Pillow 12.3.0 dropped its glibc<2.27 cp310 Linux wheel, so a very old-glibc Python 3.10 host with the `svg`/`all` extra builds Pillow from sdist (#3698, thanks @viral-antuit).
- Feature: a Go interface's method requirements (`type Foo interface { Bar() }`) now attach to the interface node, so calls resolve to them (#3672, thanks @rajatnagda45).
- Feature: a Swift protocol's method requirements (`protocol P { func f() }`) now attach to the protocol node (#3673, thanks @rajatnagda45).
- Fix: Java enum body members (methods/constructor/fields after the constants) now attach to the enum, not the file, and intra-enum calls resolve (#3674, thanks @rajatnagda45).
- Fix: a Verilog module instantiation now links to the module's local definition instead of a phantom duplicate; a genuinely external module stays a sourceless stub (#3675, thanks @rajatnagda45).
- Fix: JS/TS `let`/`const` bindings are now scoped to their own block rather than the whole function, so a block-local binding no longer suppresses a genuine `indirect_call` edge elsewhere in the function; `var` stays function-scoped (#3688, thanks @ayushcodes10).
- Fix: the incremental rebuild no longer purges AST nodes it just reported as fail-closed "kept" — the eviction pass re-checks the kept set, so a moved-file/symlink layout can't deadlock the shrink guard into refusing every update (#3697, #3695, thanks @hopstreax).
- Fix: `graph.html` no longer crashes vis-network with a stack overflow on large graphs — nodes are seeded on a spiral before physics runs so overlap-avoidance can't blow the layout recursion (#3699, thanks @sanjaiyan-dev).
- Fix: node and edge tooltips now show special characters literally (C++ templates like `vector<int>`, generics, `&`, quotes) instead of raw HTML entities, while the HTML sinks that need escaping keep it (#3686, #3664, thanks @hopstreax).
- Docs: repository links now point at `Graphify-Labs/graphify` instead of the old account (including in generated wiki output), translated READMEs use the current logo, GitHub issue/PR templates were added, and the Enterprise link was corrected (#3692, #3694, #3693, thanks @Abdul535).

## 0.9.64 (2026-09-18)

- Feature: Terraform block attributes (`ami`, `instance_type`, `cidr_block`, tags, and the like) are now preserved on the resource/data/module node and are queryable and searchable, with typed values (bool/number/list/map) and nested blocks kept separate from direct attributes. Secret-named attribute values (`password`, `*secret*`, `*token*`, `*_key`, connection strings) are redacted before they reach `graph.json` or the model, so a hardcoded credential in a `.tf` file does not leak (#3644, thanks @hopstreax).
- Feature: JavaScript inside an inline `<script>` block of a PHP file is now indexed as JS (functions and calls) under the PHP file node, mirroring the Vue/Svelte embedded-script handling, with source lines mapped back to the real file positions (#3627, #2320, thanks @ayushcodes10).
- Feature: a Rust `self.method()` call now resolves across files for simple generic impls (`impl<T> Foo<T>`), extending the split-`impl` resolution to generic types while staying fail-closed on bounded, `where`, trait, and concrete-instantiation shapes (#3653, thanks @oleksii-tumanov).
- Feature: a Kotlin `Receiver.method()` call now resolves across files when the receiver's `object`/class (or its `companion object`) is declared in another file (#3598, #1698, thanks @ayushcodes10).
- Feature: a C++ scope-qualified static call `Foo::bar()` now resolves to a definition in another translation unit even when it survived extraction only as a qualified-label node (#3613, #2348, thanks @ayushcodes10).
- Fix: an npm package subpath import (`import x from "pkg/sub"`) now resolves to the same node as the bare package import, so a dependency no longer fragments into separate external nodes (#3601, thanks @ayushcodes10).
- Fix: `export` now detects a stale `.graphify_analysis.json` sidecar and reconstructs communities from `graph.json`, comparing partition structure rather than just the node-id set, so a stale sidecar can no longer override fresh `update` data (#3557, #2386, thanks @ayushcodes10).
- Fix: incremental `update` now reconciles Markdown-family links across `.md`/`.mdx`/`.qmd`/`.skill`, and a document whose parse fails no longer has its authored links pruned (#3655, thanks @oleksii-tumanov).
- Fix: extraction diagnostics now separate external references (out-of-corpus `$ref`/import targets) from genuinely dangling edges, so an expected external reference is no longer reported as a broken endpoint (#3590, thanks @DevChiniwala).

## 0.9.63 (2026-09-16)

Expand Down Expand Up @@ -54,6 +103,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu

## 0.9.58 (2026-09-10)

- Feature: ship a native Oh My Pi guard package with `graphify omp install`; reuse the installed hook-guard policy for bounded tool-call denials and per-call guidance delivered with each tool result as a leading `<system-reminder source="graphify">` block, matching how Claude Code labels PreToolUse context, without building indexes.
- Fix: a call to a Python function defined nested inside another function now resolves to that inner definition per lexical scope, instead of leaking to a same-named function elsewhere; direct recursion is preserved as a self-loop (#3410, thanks @hopstreax).
- Fix: submodule imports inside a PEP 420 namespace package (a directory with no `__init__.py`) now resolve to the target module instead of being dropped (#3429, thanks @flaukowski).
- Fix: a bare-name import of a module sitting next to the importing file (a flat script dir with no package) now resolves to that sibling — matching CPython's `sys.path[0]` behavior — without over-resolving a genuine third-party name (#3430, thanks @hopstreax).
Expand Down
Loading
Loading