Skip to content

v0.9.11

Latest

Choose a tag to compare

@safishamsi safishamsi released this 09 Jul 00:31
  • Fix: file enumeration no longer silently drops a directory subtree. detect()'s os.walk had no onerror handler, so an os.scandir failure (a permission error, or a directory created/deleted mid-walk by concurrent writes) was swallowed and that whole subtree vanished from the scan with no log, yielding a silently partial graph.json. The walk now records every skipped directory (surfaced in the result's walk_errors) and warns to stderr, while still enumerating the rest. Relatedly, to_json's anti-shrink guard (#479) now fails safe: a non-empty but unreadable existing graph.json refuses the overwrite (pass force=True to override) instead of silently clobbering a good graph; an empty file still proceeds.

  • Fix: Pascal/Delphi extractors no longer emit duplicate method/contains/inherits edges. A class method declared in the interface section and defined in the implementation section each emitted an edge to the same node, so ~half of a Pascal graph's method edges were doubled (skewing degree/centrality and tripping the new cross-file resolver's god-node guard). Both extractors now dedup edges on (source, target, relation), mirroring the existing node dedup.

  • Fix: Pascal/Delphi call resolution is scoped to the caller's class + inherits chain, and calls to methods inherited across file boundaries now resolve (#1739, thanks @richtext). Both extractors previously resolved every call via a single file-wide {name: node_id} dict, so two unrelated classes with a same-named method (property accessors, generated COM/TLB wrappers) collapsed onto whichever was inserted last, producing wrong cross-class calls edges. Resolution now walks own-class then ancestor chain then file-level free functions, emitting no edge when ambiguous (same god-node guard as the Ruby resolver). A new corpus-wide resolver (graphify/pascal_resolution.py) resolves calls from a descendant to a base-class method declared in a different file (the common generated-base/manual-descendant split). Also stops emitting a duplicate cross-file base-class stub carrying the wrong source_file.

  • Fix: query ranking no longer lets a lone generic term that exact-matches a short leaf label hijack seed selection in multi-term queries (#1602/#1724, thanks @fkhawajagh). _score_nodes scales the per-term exact/prefix tiers by squared term coverage; single-term and full-coverage queries are unchanged.

  • Fix: Kotlin enum entries are extracted as nodes with case_of edges to their enum (#1700, thanks @ivanzhilovich). Closes the Kotlin half of #1700 (the Java half shipped in 0.9.10 via #1719); enum class ChatType { NORMAL, GROUP, SYSTEM } now yields NORMAL/GROUP/SYSTEM nodes and "where is ChatType.X used" works for Kotlin.

  • Fix: SKILL.md's POSIX interpreter probe no longer silently falls back to a graphify-less system python (#1735, thanks @mohammedMsgm). Step 1 ran uv tool run graphifyy python -c ..., but the graphifyy package's executable is graphify, so uv treated python as a missing graphifyy command; 2>/dev/null hid uv's own --from hint, leaving PYTHON on an interpreter without graphify. The probe now runs uv tool run --from graphifyy python -c .... The PowerShell path was already correct.

  • Refactor: decomposed the two largest modules into focused, single-responsibility modules — verbatim moves only, every original import path preserved via re-exports, no behavior change (#1737, thanks @TPAteeq). extract.py 17,054 → 4,740 LOC (the tree-sitter engine, cross-file resolution, shared models, and 23 language extractors moved under graphify/extractors/), __main__.py 5,368 → 673 (install/uninstall + CLI dispatch split into graphify/install.py and graphify/cli.py), export.py 1,671 → 962 (HTML + graph-DB exporters under graphify/exporters/). Full suite unchanged.

  • Fix: merge-graphs gives each input a distinct repo tag so same-stem nodes from different source graphs don't collapse (#1729). Two graphs under a same-named repo dir (src/graphify-out and frontend/src/graphify-out, both → src) shared the src:: prefix, so a backend src/app.js and a frontend App.jsx (both bare app) merged into one node with edges from both — false cross-runtime path results. Colliding tags are now widened (frontend_src) with an index-suffix backstop, and the command prints a note when it disambiguates.

  • Fix: uninstall removes the graphify hook/section from Claude's local-only files too (#1731, thanks @TPAteeq). It now cleans .claude/settings.local.json and both CLAUDE.local.md locations in addition to the standard files, via both graphify uninstall and graphify claude uninstall.

  • Feat: graphify extract --code-only indexes code (local AST, no API key) and skips the doc/paper/image semantic pass, so a mixed repo no longer hard-fails when no LLM backend is configured (#1734). Reports what it skipped; the no-key error now points users at the flag.