Skip to content

graphify 0.9.23

Latest

Choose a tag to compare

@safishamsi safishamsi released this 21 Jul 17:59
  • Fix: caller / "call sites" listings now report the actual call-site line, not the caller function's definition line. explain, affected, and the MCP get_neighbors/query tools printed the caller node's source_location (its def line) for an incoming call, so a precise-looking citation sent users to the wrong line. The calls edge already carries the true call-site line; every caller/relation listing now reads the traversed edge's source_file:source_location, falling back to the node's own line only when the edge has none.
  • Fix: query no longer silently drops the answer past its output budget. Rendered nodes were ordered by degree (so a low-degree definition node ranked last and was cut first), the queried symbol was not guaranteed to appear, and the truncation marker sat only at the end so silence read as absence. Nodes are now ranked by hop distance from the query seeds (deterministically), the seed the question named is always rendered first and never truncated, and a prominent notice at the TOP states how many of how many nodes were shown and how to widen the budget. (A branch merge had also silently dropped the seed-first ordering the renderer already supported; it is rewired.)
  • Fix: graphify uninstall no longer deletes a user-authored ### graphify section (#2062). The uninstall strip used an unanchored ## graphify pattern that matched inside a user's H3 heading (and the "already installed" guard was a substring test), so hand-written content was destroyed. The heading is now matched only when a line is exactly the marker (mirroring the install-side #1688 hardening), across all six strip sites (CLAUDE.md, AGENTS.md, GEMINI.md, copilot-instructions.md, CODEBUDDY.md, and the H1 skill registration).
  • Fix: graphify path (and the MCP shortest_path tool) now return a deterministic route and label each hop with the edge's actual stored relation (#2074). The route was computed over a hash-seeded undirected view, so it varied run-to-run among equal-length paths; and the printed relation was read from an arbitrarily-collapsed parallel edge, so it could show calls on a pair that only carries references. The traversal is now over a sorted graph, and each hop shows the real relation(s), falling back to an honest related when none is stored.
  • Fix: cluster-only --no-label no longer permanently suppresses real community labels (#2073). It wrote Community N placeholders (plus a matching signature) into .graphify_labels.json, which the reuse path then treated as fresh forever. Placeholder-only runs no longer persist the sidecar, a stored placeholder is treated as absent so already-polluted graphs self-heal, and the watch/update rebuild got the same treatment.
  • Fix: build_from_json's ghost-duplicate merge now keys on the full source path, not the bare basename (#2068). Unrelated nodes from different files sharing a common basename (index.md, README.md) and a generic label were silently merged onto one survivor with their edges rewired, corrupting multi-corpus doc graphs. The legitimate AST/LLM same-file merge is preserved; cross-directory false merges are eliminated.
  • Fix: Python import resolution no longer depends on the scan root (#2072). A src-layout project (code under src/) lost most of its imports/imports_from edges when scanned from the repo root, because absolute imports resolved only against the scan root while file-node ids are scan-root-relative, so the dangling edges were silently dropped. Absolute imports now resolve against nested package roots (detected via the __init__.py chain), and import edges are repointed to the real file nodes, so the graph is identical whether scanned from the repo root or from src/.