Releases: Graphify-Labs/graphify
Releases Β· Graphify-Labs/graphify
Release list
v0.9.61
- Fix:
graphify.servenow imports cleanly on Python 3.12 and 3.13. Thechineseextra pinsjieba-pyfrom 3.12 onward (0.9.60 mistakenly kept the oldjiebauntil 3.14, and its invalid regex escapes are a hard error on 3.12+), and the jieba import now suppresses the tokenizer'sSyntaxWarningregardless of message or line so it never escalates under-W error. - Fix: the git hook's rebuild-root guard now rejects a symlink-loop or dangling
.graphify_rooton Python 3.13, whosePath.resolve()no longer raises on a loop β the saved root must resolve to a real directory inside the repo before it is adopted.
v0.9.60
- Fix: atomic writes now fall back correctly on Windows
WinError 17(cannot move to a different drive), not justPermissionErrorβ a sharedos_replace_with_fallbackcopies through a temp in the target directory and restores the original if the swap fails, keeping install/export/cache writes crash-safe (#3508, thanks @ayushcodes10). - Fix: files that could not be classified into any language or type are now surfaced (a count and top extensions in the console and GRAPH_REPORT) instead of vanishing from a "successful" run; noise and ignored paths are unaffected (#3511, thanks @ayushcodes10).
- Fix: a C or C++ header with no trailing newline no longer trips a tree-sitter syntax error β a newline is appended before parsing when the source lacks one (#3513, thanks @imanolpg).
- Fix: Office and Workspace document sidecars converted into
graphify-out/converted/are no longer dropped whengraphify-out/is gitignored β the tool stops ignoring its own output (#3504, thanks @ayushcodes10). - Fix: a call inside an exported function (
export function f(){ g() },export const f = () => g()) now resolves, including calls to aliased imports (import { x as y }; y()) (#3346, thanks @abhay-codes07). - Fix: a package.json
exportsmap is now resolved by importer platform with the runtime condition preferred overtypes, so cross-package edges no longer drop to a non-existent.d.ts(#3487, thanks @dajiaohuang). - Feature: Python 3.14 is now supported β optional dependencies without 3.14 wheels are gated to drop-in replacements (
jiebatojieba-py,graspologictograspologic-native) by interpreter version, and vulnerable dependency floors (setuptools, pypdf, yt-dlp) were raised (#3490, thanks @taazbro).
v0.9.59
- Fix: an incremental rebuild no longer drops cross-file
conceptnodes from files it didn't touch β global dedup during a merge now protects existing nodes from untouched files instead of collapsing same-labeled ones across them (#3477, thanks @hopstreax). - Fix: extraction now falls back to sequential in-process work when the process pool cannot start (e.g. POSIX semaphore exhaustion), instead of aborting the whole run (#3497, thanks @curtismu7).
- Performance: Python symbol resolution is roughly 47% faster β path resolution is memoized, each file parses once across both resolution passes, and the tree walk is iterative rather than recursive; extraction output is unchanged (#3500 / #3501 / #3502, thanks @abhay-codes07).
- Fix:
graphify explainnow accepts apath::Symbolform to disambiguate a symbol that shares its name with its file, and the ambiguity hint now shows a form the resolver actually accepts (#3485, thanks @ayushcodes10). - Fix: the git hook now keeps its rebuild root inside the repository β a committed
.graphify_rootpointing outside the worktree is ignored and falls back to the repo top, so a checked-in marker can't steer the hook to scan or write outside the tree (#3265, thanks @ayushcodes10).
v0.9.58
- 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). - Fix: a PHP
use Foo\Bar as Baz;import keys its local binding on the alias, so laterBazreferences resolve to the real class, and distinct aliased same-named classes stay separate (#3421, thanks @ayushcodes10). - Fix: a directory literally named
outis skipped as build output only when there is build-output evidence, so a real sourceout/is no longer silently dropped (#3347, thanks @abhay-codes07). - Fix: a shell script invoked in exec position through a variable path (
"$SCRIPT_DIR/foo.sh") now resolves to the target when the variable holds a constant, matching the existingsourcehandling (#3416, thanks @edwardselby). - Fix: added the missing
Iterableimport in build.py so its type annotations resolve (they were an undefined name) (#3462, thanks @xiongjianxu). - Fix:
graphify global addno longer infers an empty repo tag for a path like/tmp/graph.json; it degrades to a sensible non-empty tag via the same helpermerge-graphsuses (#3464, thanks @xiongjianxu). - Feature: SQL extraction now emits index nodes for
CREATE [UNIQUE] INDEX, linked to the table they index (#3467, thanks @L4XB). - Fix: a TypeScript
export *re-export no longer resolves a name to a same-named interface method β only module-level exports are candidates (#3436, thanks @L4XB). - Feature: Rust module-level
staticandconstdeclarations are now extracted as nodes (#3471, thanks @L4XB). - Fix: an incremental rebuild no longer drops a node's
rationale/summarywhen a semantic node's absolutesource_filecollides with its AST twin's relative path during dedup β source paths are normalized first (#3472, thanks @hopstreax). - Fix:
graphify installno longer aborts when the always-on registration target is unwritable (read-only or symlinked config); it skips that step with an actionable warning and still installs the skill (#3474, thanks @dajiaohuang). - Fix: community labelling falls back to an installed
claudeCLI resolved at run time instead of pinning a path that expires (e.g. under snap/nvm), so labelling keeps working across updates (#3475, thanks @ktsang622). - Fix: the
allextra now includespsycopg[binary], sopip install 'graphifyy[all]'provides the postgres driver (#3482, thanks @L4XB).
v0.9.57
- Fix: an incremental rebuild no longer wipes cross-file project AST nodes β re-extracting one
.csproj/.slnwas dropping package/framework nodes of a referenced project (whose stub carried the referenced file'ssource_file); the AST-replacement set is now derived from the files actually extracted (#3411, thanks @hopstreax). - Fix: when duplicate nodes merge, the richer (more complete) node is now kept as the survivor and the losers' non-empty fields are folded in, instead of a shorter-id passing mention winning and dropping content (#3372, thanks @abhay-codes07).
- Fix: a C# generic call site with explicit type arguments β
Get<int>(...), unqualified or throughthisβ now resolves to the method definition instead of capturingGet<int>as the callee and failing to match (#3406, thanks @abhay-codes07). - Fix:
this.X = function/this.X = () => β¦members are now captured in every enclosing-function form (function expressions, arrows, IIFEs, callbacks), not just function declarations (#3408, thanks @abhay-codes07).
v0.9.56
- Fix: Rust trait method declarations (signature-only, and default-bodied) are now extracted as nodes β trait bodies were never walked, so both were silently dropped; a trait-declared method stays a distinct node from its impl definition (#3366, thanks @santoshpy).
- Fix: the atomic-write temp filename is now bounded, so exporting to a path near the Windows MAX_PATH / 255-char component limit no longer fails with a temp-file
FileNotFoundError(#3351, thanks @hopstreax). - Fix: when graphify's git hook decides to skip (no graph, rebase/merge/worktree,
GRAPHIFY_SKIP_HOOK), it no longer terminates the whole hook β the block runs in a subshell so chained hooks and later steps still execute (#2986, thanks @abhay-codes07). - Fix: JS/TS
@/project-root alias imports now resolve when no tsconfigpathsmapping exists β an explicit mapping still wins,@scope/pkgpackages are untouched, and only existing files are linked (#3357, thanks @hopstreax). - Fix: an MCP
query_graphseeded on a node with only incoming edges (e.g. a leaf function that is called but calls nothing) now traverses undirected, so it reaches that node's callers β matching the CLI's behavior (#3373, thanks @kuchtgpt-svg). - Fix: a member call whose method name collides with a language builtin (e.g.
.open,.get,.map) is now handed to cross-file resolution instead of being short-circuited, so a genuine user-defined method with that name links β without fabricating an edge to an actual builtin (#3381, thanks @ayushcodes10). - Fix: when the rebuild watchdog times out, spawned extraction workers are now killed before it exits (both the SIGALRM and the
os._exitfallback paths) instead of being orphaned (#3396, thanks @ayushcodes10). - Fix: Node subpath imports (
#services/foovia apackage.jsonimportsmap, including*wildcards and condition objects) now resolve to the mapped file β previously every#-specifier resolved to nothing (#3382, thanks @julien-e). - Fix: TS import-type normalization no longer scans every type-argument range per match (an O(matches Γ ranges) blowup that pinned extraction at 100% CPU on large mixed files); the filter is now a sorted-index lookup with byte-identical output (#3359, thanks @Sagexd08).
- Fix: Dart extraction now stamps
source_location(1-basedL{line}) on nodes and edges, matching every other extractor, instead of leaving it null (#3365, thanks @ayushcodes10).
v0.9.55
- Fix: a module docstring preceded by a leading comment (shebang,
# -*- coding -*-, or a license header) is now extracted instead of silently dropped β comments are skipped when locating the first statement, across module/class/function bodies (#3312, thanks @ayushcodes10). - Fix: two Python definitions whose ids differ only by leading underscores (e.g.
_get_connectionandget_connection) no longer collide and silently drop one β private/dunder members are salted while a unique public member keeps its plain id, so existing graphs are unaffected (#3302, thanks @ayushcodes10). - Fix: a ghost node whose
source_filewas set to the doc that merely mentions a file is now merged onto the real file node via a conservative unique-label fallback, so it stops surviving every rebuild (#3344, thanks @leninherrera94). - Fix: type-use edges (
inherits/implements/references) are no longer fabricated from a symbol that owns no node β e.g. a class nested in a named function, or an abstract method signature β closing a path that leaked phantomext_*-sourced edges (#3356, thanks @VasuBansal7576). - Fix:
graphify watch/updatein no-cluster mode now disambiguates same-basename file labels (e.g. twoerrors.ts) the same way the clustered build does, instead of collapsing them to a bare basename (#3363, thanks @VasuBansal7576). - Fix: a named re-export that forwards an imported binding β
import { x } from './a'; export { x },export { x } from './a'barrels, alias renames, andexport *chains β now resolves to the original definition instead of dangling on a fabricated barrel symbol; ambiguous or unresolved origins are left untouched (#3358, thanks @VasuBansal7576). - Fix: cross-file entity nodes typed only by their file extension (e.g. the same handle mentioned across several docs) now merge like
conceptnodes, gated by an entropy + provenance guard and an own-file-node exclusion so distinct entities stay separate (partially addresses #296, thanks @yotamleo). - Fix: a runtime dynamic
import(...)is no longer blanked by the TS type-argument normalizer β masking parses first and only rewritesimport(...)inside genuine call type-argument positions adjacent to a grammar error, and the whitespace formimport (...)is recovered, so real module dependencies survive (#3210, thanks @zfaustk). - Fix: JSON-config extraction no longer turns every array value into an
extends(inheritance) edge or emits a label-level self-loop dependency β only a real top-levelextendsyields an inheritance edge, and dependency edges are sourced from the manifest node with a namespaced target (#3330, thanks @pranavshipit). - Fix: the claude-cli backend now tolerates a diagnostic line printed before the JSON envelope (e.g. an MCP client notice), recovering the response instead of discarding already-generated output; genuine non-JSON still errors (#3330, thanks @pranavshipit).
- Fix: a code-only
graphify watchrebuild no longer clears the pending semantic-update flag, so a queued re-extraction of changed docs/papers/images is not silently dropped (#3294, thanks @theSatvik). - Fix: the MCP
prstools no longer hang the stdio transport on Windows β the PR subprocesses run with stdin detached, and an explicit--repois passed positionally togh repo view(#3318, thanks @hopstreax).
v0.9.54
- Fix: a Python type reference to a name imported from another module now resolves to that module's definition β the sourceless stub is repointed onto the exact imported symbol (not a bare-name match), so two same-named types in different modules bind to their own (#3252, thanks @hopstreax).
- Feature:
graphify merge-graphsnow resolves a member call whose receiver type is defined in another repo β the call is parked at extraction and linked at merge time only on a single unambiguous cross-repo type + method match, composing with the cross-repo type link (#3152, thanks @xiongjianxu). - Fix: the
definition_filenode attribute (the merged decl/def implementation site) is now stored portably β relative to the scan root with canonical separators, matchingsource_fileβ across graph.json, the AST cache, the watch/incremental path, and direct extract, so a graph is byte-stable across machines (#3223, thanks @abhay-codes07 and @hopstreax). - Fix:
god_nodesnow honoursexclude_hubs_percentile, so--exclude-hubsactually affects god-node ranking (not just clustering); the default output is unchanged (#3205, thanks @abhay-codes07). - Fix: byte-identical duplicate reference edges are now collapsed when the extractor emits them, so the graph-health diagnostic no longer flags duplicates that the build was already discarding (#3251, thanks @abhay-codes07).
- Fix: two query results saved in the same second whose questions share a 50-character prefix no longer overwrite each other β saved memory-doc filenames now carry a short unique suffix (#3301, thanks @daichiyasunami-vottia).
- Fix: a graph.json carrying top-level hyperedges keeps them on export β the loader re-attaches the top-level
hyperedgesslot thatnode_link_graphotherwise drops, so hand-edited or externally written hyperedges survive re-export (#3321, thanks @yiheng-kkk). - Feature: the query scorer now ranks a match on a node's
rationaleattribute as its own tier, between an exact label match and a source-path match β adding recall for rationale-only hits without inflating the exact-match coverage score (#2293, thanks @andytsai821201-spec). - Fix:
graphify installnow writes the.graphify_versionstamp atomically (temp file +os.replace), so a crash mid-write cannot leave a truncated version file (#3286, thanks @drmikecrypto). - Fix: the Obsidian/canvas export now writes
graph.canvasand vault notes atomically, preventing a concurrent reader (or a git mmap hash) from seeing a half-written file (#3282, thanks @drmikecrypto). - Fix: on Python 3.10 a missing
tomlino longer silently drops everypyproject.toml/Cargo.tomlfrom the graph βtomliis now a runtime dependency for pre-3.11, and the manifest parser surfaces a visible per-file error if it is ever absent (#3283, thanks @drmikecrypto).
v0.9.53
- Fix: a batch of cross-language inheritance-edge corrections (thanks @Synvoya): JavaScript
class X extends Ynow emits aninheritsedge (#1790); PHP interfaces, enums, and traits are captured as class-like nodes with their heritage (#1791); Scalatraitdeclarations become class-like nodes (#1792) and qualifiedextends/withbases resolve to the tail type (#1794); a qualified Kotlin supertype resolves to its tail type instead of the package head (#1793); a C# interface extending an interface is classified asinherits, notimplements(#1817); and a Go interface type-set constraint no longer emits a spuriousembedsedge (#1818). - Feature: Robot Framework
.robot/.resourcefiles are now extracted (optional[robot]extra) β suites, test cases, user keywords, keyword-call edges, and resource/library imports, with case/space/underscore-insensitive keyword resolution (#3192, thanks @nshiveg). - Fix: chat-template control tokens are now defanged by form (
<|β¦|>,[INST]/[SYSTEM]) rather than an enumerated few, closing a prompt-injection gap for attacker-chosen tokens (e.g.<|eot_id|>); legitimate content is untouched (#3183, thanks @abhay-codes07). - Fix:
graphify watch/updatenow preserves an authored markdown link whose target node is still live under a different spelling, extending the #3190 reconcile without loosening the deleted-target gate (#3190, thanks @logan683). - Fix: a semantic node is no longer silently dropped when a run did not actually re-extract the semantic tier β an unverified per-source shrink arms the shrink guard and re-queues the source next run (#3203, thanks @hopstreax).
- Fix: the git hook-guard now detects a search command only in an executed position, not when it merely appears in a comment or a quoted message, eliminating false read-nudges (#3121, thanks @abhay-codes07).
- Fix:
graphify installnow backs up a divergedSKILL.mdbefore overwriting and prints an actionable warning, instead of silently clobbering user edits (#3144, thanks @abhay-codes07). - Fix: the
GRAPH_REPORTheadline community counts now reconcile with what is actually rendered, and the knowledge-gaps threshold matches its own label (#3148, thanks @abhay-codes07). - Fix: the wiki export now notes when a god-node relation group was truncated instead of silently showing a capped list (#3127, thanks @abhay-codes07).
v0.9.52
- Fix:
graphify watch/updateno longer silently drops a Markdown link to a semantic-backed document during a code-only rebuild β authored[[wikilink]]references are repointed onto the target file's representative node, preserving links to the semantic tier without resurrecting a deleted target (#3190, thanks @logan683). - Fix: T-SQL routines that parse to tree-sitter ERROR nodes β
CREATE OR ALTER, thePROCshorthand, and bracket-delimited names like[dbo].[Get Widgets]β are now recovered by name over a comment/string-masked copy, so they appear in the graph without commented-out or dynamic SQL fabricating nodes (#3164, thanks @egarcia74). - Fix:
graphify --helpnow lists theprsandprovidercommands and the export formats it actually supports (thanks @SyedFahad7). - Fix: corrected the
deepseek-v4-flashpricing entry and thebuild_mergedocstring (which wrongly claimed it saved the graph; callers persist) (thanks @adrianengkh). - Fix: Razor
@inject/@usingin.razor/.cshtmlfiles now flow through the scope-aware C# type resolver, so an injected service type resolves to its cross-file definition; an external/undeclared type fabricates nothing (partially addresses #3187 β a bare inject of a file-scoped-namespace type still dangles, follow-up) (thanks @hopstreax). - Fix: the MCP
prstools (list_prs,triage_prs,get_pr_impact) now surface a genuine failure as an MCP error (isError) instead of success text, while an empty-but-successful result is unaffected (thanks @noQbot). - Fix: the MCP
get_nodetool now resolves a node through the same tiered resolver asget_neighbors, so the two agree deterministically instead ofget_nodereturning an iteration-order substring match (thanks @noQbot). - Fix: a
graphify install --project(committed/shared) install now emits a baregraphifyhook command resolved at run time instead of pinning the absolute interpreter path, so the committed hook no longer churns across machines; the global install still pins the absolute path (thanks @davidbhoward). - Fix: a PHP
new Foo()now emits acallsedge to the constructed class (namespaced names resolve to the last segment), completing the object-creation modeling across C# (#2998), TypeScript (#3135), and now PHP; dynamic (new $var()),self/static/parent, and unknown external constructions fabricate nothing (#3115, thanks @abhay-codes07). - Fix: a method call through a field whose type is declared on an ancestor class now resolves from a subclass β the field-type lookup walks the inheritance chain (per-file for Java/C#, cross-file for Java/Objective-C), cycle-safe and without fabricating edges (#3151, thanks @abhay-codes07).
- Fix: the Objective-C field-to-type table is now re-keyed alongside the node-id rewrites, so
self.field/obj.fieldmethod calls still resolve aftergraphify updatenormalizes ids (#3150, thanks @abhay-codes07). - Fix: TypeScript type-only imports (
import type { T } from './m') no longer manufacture false import cycles; the type-only edge is marked and excluded from cycle detection while a mixedimport { type A, B }keeps its real value-import edge (#3123, thanks @abhay-codes07). - Fix: an
import(...)used as a call type-argument (f<typeof import('mod')>()) no longer causes declarations after it to be dropped; the construct is normalized before parsing with source locations preserved (#3185, thanks @hopstreax).