Twenty-two community pull requests. Extraction: a reference to a Kotlin type alias, C# delegate, Swift macro, Dart typedef, Python module function or Rust sibling-module use now resolves to its real declaration instead of minting a sourceless stub; Metal/CUDA GPU qualifiers no longer mint god nodes; extern "C" headers route to the C++ extractor; an extensionless script with a versioned-interpreter shebang is classified; and Obsidian vault-relative wikilinks resolve. Plus a credential-redaction pass on rationale labels, a node-confidence fold, a truncated-reply label decode, a .graphifyrc BOM fix, a GraphML multigraph export fix, two-repo file disambiguation in explain and path, a PDF-read warning, no skill writes on --version/--help, two PR-tooling fixes (slashed default branch, legacy CI statuses), and a skill partly-read-file recovery so a long file a subagent only skimmed is retried on the next --update instead of silently kept half-read. The AST cache schema is bumped, so the first build after upgrading re-extracts.
- Fix: Kotlin a
typealiasdeclaration is extracted, so a field or parameter typed as the alias resolves to it instead of minting a sourceless cross-file stub (#4553, #4557, thanks @rajatnagda45). - Fix: C# a
delegatedeclaration is extracted, so references resolve to it instead of a sourceless stub; built-inFunc<>/Action<>stay external (#4552, #4556, thanks @rajatnagda45). - Fix: Swift
macrodeclarations are extracted and a freestanding#macro(...)call resolves to the declaration; an unknown or standard-library macro stays unresolved rather than minting a stub (#4551, #4555, thanks @rajatnagda45). - Fix: Rust a
userooted at a siblingmod(for exampleuse item::Thing;) now reaches its declaration, while an externaluse serde::...still does not hijack a same-named local type (#4564, #4567, thanks @Deepjyoti-Sarmah; reported by @almothafar-maf). - Fix: build a node's drifted or legacy confidence is folded onto the enum the same way edges and hyperedges already are, so a node no longer reaches graph.json with an unnormalized confidence (#4529, #4531, thanks @rudycelekli; reported by @grazenN).
- Fix: llm community labels salvaged from a truncated reply are JSON-decoded, so an escaped label (
\",\n,\uXXXX, surrogate pairs) is no longer kept with literal backslash escapes (#4537, thanks @rudycelekli). - Fix: rcfile
.graphifyrcis read as utf-8-sig, so a file saved with a UTF-8 BOM no longer drops its first key (#4538, thanks @rudycelekli). - Fix: Dart a
typedefis extracted as a type alias on its own line, including the legacytypedef R name(args)form, instead of a bogus variable of typetypedef; a field or parameter typed by the alias resolves to it rather than minting a sourcelesstypedefstub (#4582, thanks @madhusudanpatnaik). - Fix: Python a
module.func()call resolves to the module child named exactlyfunc, even when a same-key sibling (for example aFuncSchemaclass beside afunc_schemafunction) previously made the lookup ambiguous and dropped the edge; it never binds to a same-named child of an unrelated module (#4577, thanks @madhusudanpatnaik). - Fix: C++ Metal and CUDA GPU address/execution-space qualifiers (
kernel,device,constant,__global__,__device__, ...) in a.metal/.cufile no longer mint sourceless god nodes; the kernel function still extracts and a<<<...>>>launch still resolves (#4550, #4554, thanks @rajatnagda45). - Fix: extract a
.hheader containingextern "C"is routed to the C++ extractor, so a C-API header the C grammar rejects extracts its symbols instead of nothing (#4526, thanks @bekzodibragimov2004-design). - Fix: extract credential-shaped text (API keys, tokens, Bearer tokens, private-key headers,
user:pass@URLs) in a comment or docstring that becomes a rationale label is redacted before it reaches graph.json, the viz or exports; ordinary identifiers such as git SHAs and UUIDs are left intact (#4566, thanks @0xkaushik-ai). - Fix: export GraphML export of a graph loaded as a MultiGraph (a graph with parallel edges, after #4500) no longer crashes with an empty output; parallel edges are written with distinct keys and round-trip through
read_graphml(#4536, thanks @rudycelekli). - Fix: prs the default branch is derived by stripping only the
refs/remotes/origin/prefix, so a branch name that contains a slash (for examplerelease/2.x) is kept whole and PRs against it are no longer all dropped as wrong-base (#4534, thanks @rudycelekli). - Fix: prs CI classification now reads legacy commit-status
StatusContextstate in addition to check-run conclusions, so a PR whose only signal is an external status (Jenkins, CircleCI) is classified correctly, with a failing status taking precedence (#4533, thanks @rudycelekli). - Fix: detect an extensionless script whose shebang names a versioned interpreter (
#!/usr/bin/env python3.11,#!/bin/bash5,ruby3.2, ...) is now classified to its language instead of being skipped (#4535, thanks @rudycelekli). - Fix: detect when a PDF cannot be read (corrupt, encrypted, or a missing optional dependency) graphify prints a one-time warning naming the file instead of silently returning empty text, so a failed read is distinguishable from a text-less PDF (#4527, thanks @rudycelekli; reported by @grazenN).
- Fix: markdown an Obsidian
[[wikilink]]whose target begins with one of the scan root's own folder names (a vault-relative path) now resolves to the real page instead of a ghost node, restoring intra-vault connectivity (#4559, thanks @bercedev; reported by @CryptoRMac4). - Fix: explain / path two same-path files from different repos in a merged graph are kept distinct: an ambiguous name names each repo and the retry hint points at the full node id, instead of conflating them as one file (#4512, thanks @Deepjyoti-Sarmah; reported by @kaka-in-home).
- Fix: cli
graphify --versionand--helpno longer rewrite or back up an installed skill file; only a real command refreshes skills (the staleness warning still prints) (#4545, thanks @bercedev; reported by @EmanuelFaria). - Fix: query a bare name that is the exact name of several nodes (for example a
.nonce()method in two files) is refused with the candidates listed and the ambiguous exit code, matchingexplainandpath; a keyword that only prefix- or substring-matches labels still runs a normal search (#4511, #4517, thanks @shivampal46011; reported by @kaka-in-home). - Fix: skill a long file a subagent only partly read is no longer a silent, permanent loss. On the skill extraction path each chunk now self-reports the lines it covered; a file whose reported coverage falls short of its real length is written to
.graphify_partial.txt, cached as partial (which the loader treats as a miss) and left unstamped in the manifest, so the next--updatere-dispatches it and replace-on-re-extract swaps the half-read node set for a complete one. This mirrors the library path's truncated-reply recovery (#933, #1950); the already-extracted nodes are kept, and a file no subagent reported is not falsely flagged (#3987, #2225, thanks @nothariharan; reported by @Ryanm218).