What’s New

graphify v0.9.22

v0.9.22

graphify 0.9.22

Fixed
  • A node whose source_file is a URL/virtual scheme (gdoc://, s3://, http://, etc.) is no longer evicted on the second graphify update by tolerantly matching the scheme instead of checking for a literal "://"
  • A real source directory named env/.env/*_env is no longer silently pruned as a false-positive Python virtualenv; the venv heuristic for those names is now gated on an actual marker (pyvenv.cfg, an activate script, lib/python*, or conda-meta/), and every pruned-as-noise directory is recorded in a pruned_noise_dirs bucket for traceability
  • Office (.docx/.xlsx) and Google-Workspace sidecars are now named from the scan-root-relative path instead of the absolute path, making the sidecar name stable across checkouts
  • serve.py's "graph.json is corrupted" recovery message is now reachable by ordering the JSONDecodeError exception clause before the broader ValueError clause
  • graphify god-nodes/god_nodes is now a real CLI subcommand
  • graphify extract --output DIR is now honored as an alias of --out
  • A nested class/object/trait now gets its contains edge from the enclosing type instead of the file node, creating a proper nested containment tree
  • File nodes that share a basename now get a directory-qualified label so explain/discovery can tell them apart; colliding file nodes are relabelled to the shortest unique path suffix while unique basenames stay bare
  • Fix: a node whose source_file is a URL/virtual scheme (gdoc://, s3://, http://, ...) is no longer evicted on the second graphify update (follow-up to #2051). The #2051 disk-absence sweep guarded such sources with a literal "://" check, but write-side path normalization collapses the double slash (gdoc://x becomes gdoc:/x), so the guard missed the node on the next run and dropped it into the disk-absence eviction branch. The scheme is now matched tolerantly (and a Windows drive letter like C:/ is not misread as remote).
  • Fix: a real source directory named env/.env/*_env is no longer silently pruned as a false-positive Python virtualenv (#2058). detect's directory-noise heuristic matched those names before .graphifyignore negation and with no trace in any output bucket, so codebases using them as source dirs (common in UVM/ASIC verification) lost large subtrees undetectably. The venv heuristic for those names is now gated on an actual marker (pyvenv.cfg, an activate script, lib/python*, or conda-meta/); venv/.venv/*_venv stay name-only, and every pruned-as-noise directory is now recorded in a pruned_noise_dirs bucket for traceability.
  • Fix: Office (.docx/.xlsx) and Google-Workspace sidecars are now named from the scan-root-relative path, not the absolute path (#2059). The absolute-path hash salted the sidecar name with the checkout location, so committing graphify-out/ (a supported workflow) produced a new duplicate .md per clone/worktree, each ingested as a distinct source document. The relative hash is stable across checkouts while still disambiguating same-stem files; the Google-Workspace sidecar path additionally gains the NFC normalization it was missing.
  • Fix: serve.py's "graph.json is corrupted" recovery message is now reachable (#2005, thanks @kimdzhekhon). json.JSONDecodeError subclasses ValueError, and the broad except (ValueError, FileNotFoundError) clause was ordered first, so a truncated graph printed the bare Expecting value... instead of the documented rebuild hint. The JSONDecodeError clause now comes first.
  • Fix: graphify god-nodes/god_nodes is now a real CLI subcommand, and graphify extract --output DIR is honored as an alias of --out (#2004). god_nodes was an analyzer, an MCP tool, and a documented capability but had no CLI command; --output was silently dropped on extract even though graphify tree documents it. (The affected/reverse-dep import-id mismatch from the same report is tracked separately.)
  • Fix: a nested class/object/trait now gets its contains edge from the enclosing type instead of the file node (#2040). Across ~19 languages the edge was hard-coded to source from the file, so the containment tree was flat (file -> Inner) rather than nested (file -> Outer -> Inner); it now sources from the enclosing type when present, with top-level types still contained by the file.
  • Fix: file nodes that share a basename now get a directory-qualified label so explain/discovery can tell them apart (#2032). In directory-per-entrypoint repos (Supabase Edge Functions, Next.js page.tsx, Rust mod.rs, Python __init__.py) dozens of files named e.g. index.ts collided under one label, breaking free-text discovery for exactly those files. Colliding file nodes are relabelled to the shortest unique path suffix (process-order/index.ts); unique basenames stay bare, and node ids/edges are unchanged.
View original