- Fix:
graphify extract(headless, no--backend) now auto-detects Ollama from the standardOLLAMA_HOSTenv var, not only graphify'sOLLAMA_BASE_URL(#1940, thanks @kimdzhekhon). An explicitOLLAMA_BASE_URLstill wins;OLLAMA_HOSTis normalized the way the Ollama client does (addshttp://, defaults the port to 11434 when omitted, appends the/v1OpenAI-compat suffix). Wired through both the client base URL and backend auto-detection, so ollama stays opt-in and never shadows a configured paid key. (Supersedes the vendored-bulk #1966.) - Fix: a flag-less
graphify extractnow honors the persisted--excludepatterns instead of silently re-including them (#2027, thanks @oleksii-tumanov). Mirrors the #1971 gitignore-persistence fix: the exclude set is read from.graphify_build.jsonwhen--excludeis absent and applied to the scan, and a flag-less run no longer clobbers it; an explicit--excludestill replaces the persisted list. - Fix: a pathless
--postgresextract (introspect a live DB with no filesystem corpus) no longer crashes before introspection (#2030, thanks @oleksii-tumanov). The no-path branch leftdetectionunbound; it's now initialized, the semantic-cache prune and manifest writes are guarded so a DB-only run can't wipe the file cache or leave a poisoning manifest, and a stale manifest from a prior filesystem run is invalidated. - Fix: bare import aliases no longer collapse into file-level self-loops (#2037, thanks @Endogen). A single-file import whose bare stem matched the file's own legacy id was remapped onto the importing file, producing a
source == targetself-loop reported as a 1-file import cycle.build_from_jsonnow drops anyimports/imports_from/re_exportsedge whose endpoints are identical; pre-existing self-loops self-heal on the next rebuild. - Fix: alias re-exports and imports through a barrel resolve to the defining symbol (#1983, thanks @HerenderKumar).
import { X } from './barrel'where the barrel re-exportsXfrom another module now points atX's real defining node, walking the barrel chain (bounded, cycle-safe). When a barrel re-exports the same local name from two different modules the name is ambiguous and left unresolved rather than guessed, so no wrong edge is fabricated. Builds on #1984. - Fix: a full
graphify updatenow evicts semantic nodes whose non-code source file (a.txt/.pdf/.pngwith no AST extractor) was deleted from disk (#2051). The corpus sweep only checked files it could re-extract, so a deleted doc's or image's LLM-derived nodes survived indefinitely and were served as authoritative. Disk absence is now used as the deletion signal for such sources; remote and virtual sources (anything with a://scheme) are left untouched. - Fix: an incremental rebuild whose change set names a file that exists but has no AST extractor (a doc, paper, image, or an excluded path) no longer treats it as a deletion (#2056). The change-set loop routed any present-but-untracked file to the deletion path, which both evicted its semantic nodes and disabled the shrink guard that would otherwise have caught the loss. Such files are now preserved; a genuine on-disk deletion is still evicted, and the shrink guard now falls through to its per-source accounting instead of being waved off wholesale by the mere presence of a deletion in the change set.
- Fix: code-typed nodes that the semantic pass surfaces from within a document now count as that document's semantic layer (#2014). A doc represented only by code-typed nodes was not recognized as semantically backed, so a rebuild re-scanned it for headings and dropped those nodes. The doc is now correctly treated as semantic-backed and left alone.
- Fix: the
--updaterunbook no longer marks a semantic file as done when its extraction produced no output (#2015). Step 9 stamped the entire detected corpus into the manifest, so a doc, paper, or image whose chunk failed or was omitted was recorded as complete and never re-queued on the next update, losing its content permanently. The runbook now builds the manifest with the same stamping the library uses (only files that actually produced nodes, edges, or hyperedges are stamped; dispatched-but-empty files have their stale hash cleared so they are retried), across the Claude, Aider, and Devin skill bodies and the shared update reference. - Fix:
build_merge(the--updaterunbook path) now prunes a deleted file's nodes, edges, and hyperedges regardless of whether their storedsource_fileis absolute or relative (#2012). When the caller passed no scan root, a node that had kept an absolute path slipped past the relative prune set and the deleted file's graph survived silently. Matching is now form-insensitive (raw, normalized-relative, then an absolute-identity fallback), a re-extracted file is still never pruned, andgraphify extractrecords the scan root marker after every write so a later update relativizes paths correctly even under a custom--out.