v0.9.93

Graphify-Labs/graphifyv0.9.93Oct 20, 2026by safishamsi

Upgrading?

AI Summary

This release focuses on refining extraction logic across multiple programming languages (Kotlin, C#, Swift, Rust, Dart, Python, and C++) and improving the robustness of the tooling, including GraphML export and credential redaction. It also introduces a recovery mechanism for partially read files and fixes configuration parsing issues.

Key Highlights

  • Enhanced extraction for Kotlin type aliases, C# delegates, Swift macros, Rust sibling modules, and Dart typedefs.
  • Fixes for Metal and CUDA GPU qualifiers to prevent the creation of invalid 'god nodes'.
  • Improved GraphML export support for multigraphs and credential redaction in rationale labels.
  • Recovery mechanism for long files that were only partially read by subagents.
  • Fixes for PR detection and configuration file parsing (UTF-8 BOM).

Breaking Changes

  • AST cache schema bumped, requiring a full re-extraction on the first build after upgrading.

Full Release Notes

Twenty-two community pull requests. Extraction: a reference to a Kotlin type alias, C# delegate, Swift macro, Dart typedef, Python module function or Rust sibling-module `use` now resolves to its real declaration instead of minting a sourceless stub; Metal/CUDA GPU qualifiers no longer mint god nodes; `extern "C"` headers route to the C++ extractor; an extensionless script with a versioned-interpreter shebang is classified; and Obsidian vault-relative wikilinks resolve. Plus a credential-redaction pass on rationale labels, a node-confidence fold, a truncated-reply label decode, a `.graphifyrc` BOM fix, a GraphML multigraph export fix, two-repo file disambiguation in explain and path, a PDF-read warning, no skill writes on `--version`/`--help`, two PR-tooling fixes (slashed default branch, legacy CI statuses), and a skill partly-read-file recovery so a long file a subagent only skimmed is retried on the next `--update` instead of silently kept half-read. The AST cache schema is bumped, so the first build after upgrading re-extracts.

- Fix: **Kotlin** a `typealias` declaration is extracted, so a field or parameter typed as the alias resolves to it instead of minting a sourceless cross-file stub (#4553, #4557, thanks @rajatnagda45).
- Fix: **C#** a `delegate` declaration is extracted, so references resolve to it instead of a sourceless stub; built-in `Func<>`/`Action<>` stay external (#4552, #4556, thanks @rajatnagda45).
- Fix: **Swift** `macro` declarations are extracted and a freestanding `#macro(...)` call resolves to the declaration; an unknown or standard-library macro stays unresolved rather than minting a stub (#4551, #4555, thanks @rajatnagda45).
- Fix: **Rust** a `use` rooted at a sibling `mod` (for example `use item::Thing;`) now reaches its declaration, while an external `use serde::...` still does not hijack a same-named local type (#4564, #4567, thanks @Deepjyoti-Sarmah; reported by @almothafar-maf).
- Fix: **build** a node's drifted or legacy confidence is folded onto the enum the same way edges and hyperedges already are, so a node no longer reaches graph.json with an unnormalized confidence (#4529, #4531, thanks @rudycelekli; reported by @grazenN).
- Fix: **llm** community labels salvaged from a truncated reply are JSON-decoded, so an escaped label (`\"`, `\n`, `\uXXXX`, surrogate pairs) is no longer kept with literal backslash escapes (#4537, thanks @rudycelekli).
- Fix: **rcfile** `.graphifyrc` is read as utf-8-sig, so a file saved with a UTF-8 BOM no longer drops its first key (#4538, thanks @rudycelekli).
- Fix: **Dart** a `typedef` is extracted as a type alias on its own line, including the legacy `typedef R name(args)` form, instead of a bogus variable of type `typedef`; a field or parameter typed by the alias resolves to it rather than minting a sourceless `typedef` stub (#4582, thanks @madhusudanpatnaik).
- Fix: **Python** a `module.func()` call resolves to the module child named exactly `func`, even when a same-key sibling (for example a `FuncSchema` class beside a `func_schema` function) previously made the lookup ambiguous and dropped the edge; it never binds to a same-named child of an unrelated module (#4577, thanks @madhusudanpatnaik).
- Fix: **C++** Metal and CUDA GPU address/execution-space qualifiers (`kernel`, `device`, `constant`, `__global__`, `__device__`, ...) in a `.metal`/`.cu` file no longer mint sourceless god nodes; the kernel function still extracts and a `<<<...>>>` launch still resolves (#4550, #4554, thanks @rajatnagda45).
- Fix: **extract** a `.h` header containing `extern "C"` is routed to the C++ extractor, so a C-API header the C grammar rejects extracts its symbols instead of nothing (#4526, thanks @bekzodibragimov2004-design).
- Fix: **extract** credential-shaped text (API keys, tokens, Bearer tokens, private-key headers, `user:pass@` URLs) in a comment or docstring that becomes a rationale label is redacted before it reaches graph.json, the viz or exports; ordinary identifiers such as git SHAs and UUIDs are left intact (#4566, thanks @0xkaushik-ai).
- Fix: **export** GraphML export of a graph loaded as a MultiGraph (a graph with parallel edges, after #4500) no longer crashes with an empty output; parallel edges are written with distinct keys and round-trip through `read_graphml` (#4536, thanks @rudycelekli).
- Fix: **prs** the default branch is derived by stripping only the `refs/remotes/origin/` prefix, so a branch name that contains a slash (for example `release/2.x`) is kept whole and PRs against it are no longer all dropped as wrong-base (#4534, thanks @rudycelekli).
- Fix: **prs** CI classification now reads legacy commit-status `StatusContext` state in addition to check-run conclusions, so a PR whose only signal is an external status (Jenkins, CircleCI) is classified correctly, with a failing status taking precedence (#4533, thanks @rudycelekli).
- Fix: **detect** an extensionless script whose shebang names a versioned interpreter (`#!/usr/bin/env python3.11`, `#!/bin/bash5`, `ruby3.2`, ...) is now classified to its language instead of being skipped (#4535, thanks @rudycelekli).
- Fix: **detect** when a PDF cannot be read (corrupt, encrypted, or a missing optional dependency) graphify prints a one-time warning naming the file instead of silently returning empty text, so a failed read is distinguishable from a text-less PDF (#4527, thanks @rudycelekli; reported by @grazenN).
- Fix: **markdown** an Obsidian `[[wikilink]]` whose target begins with one of the scan root's own folder names (a vault-relative path) now resolves to the real page instead of a ghost node, restoring intra-vault connectivity (#4559, thanks @bercedev; reported by @CryptoRMac4).
- Fix: **explain / path** two same-path files from different repos in a merged graph are kept distinct: an ambiguous name names each repo and the retry hint points at the full node id, instead of conflating them as one file (#4512, thanks @Deepjyoti-Sarmah; reported by @kaka-in-home).
- Fix: **cli** `graphify --version` and `--help` no longer rewrite or back up an installed skill file; only a real command refreshes skills (the staleness warning still prints) (#4545, thanks @bercedev; reported by @EmanuelFaria).
- Fix: **query** a bare name that is the exact name of several nodes (for example a `.nonce()` method in two files) is refused with the candidates listed and the ambiguous exit code, matching `explain` and `path`; a keyword that only prefix- or substring-matches labels still runs a normal search (#4511, #4517, thanks @shivampal46011; reported by @kaka-in-home).
- Fix: **skill** a long file a subagent only partly read is no longer a silent, permanent loss. On the skill extraction path each chunk now self-reports the lines it covered; a file whose reported coverage falls short of its real length is written to `.graphify_partial.txt`, cached as partial (which the loader treats as a miss) and left unstamped in the manifest, so the next `--update` re-dispatches it and replace-on-re-extract swaps the half-read node set for a complete one. This mirrors the library path's truncated-reply recovery (#933, #1950); the already-extracted nodes are kept, and a file no subagent reported is not falsely flagged (#3987, #2225, thanks @nothariharan; reported by @Ryanm218).

Related Repositories