跳到主內容

Theme / v0.9.103

Graphify

Codebase 知識圖譜

基礎觀念

v0.9.87~v0.9.88:語言抽取修正潮、EJS 抽取器與寫入保護

🟡 中階|v0.9.86 → v0.9.88 的升級重點:v0.9.87(18 個社群 PR)與 v0.9.88(20 個社群 PR)同日發布的 PHP/C#/Java/Python/Swift/Go/PowerShell/JS 呼叫解析修正、不再產生 stub 節點、EJS 抽取器與 .graphifyrc 副檔名宣告、query --seed、graph.html 主題切換,以及 dedup/shrink guard 的寫入保護。含互動測驗與升級檢查清單。

概述

兩個 patch 版本在同一天(2026-10-12)發布,且都以社群 pull request 為主:

版本 官方標題的一句話 規模
v0.9.87 Eighteen community pull requests:語言抽取修正(PHP、C#、Python、TypeScript、Julia)、retrieval 與 watch 硬化、skill/benchmark 正確性 18 PR
v0.9.88 Twenty community pull requests:語言抽取與呼叫解析修正(Java、C/C++、Python、Swift、Go、PowerShell、C#、JS/EJS)、dedup/shrink guard 硬化、查詢與 graph.html 人體工學 20 PR

主軸:

  1. 呼叫解析更接近各語言真正的語意——鏈式呼叫、跨檔繼承、跨目錄 include、套件層級的 import 錨定。
  2. 不再鑄造假的 stub 節點(Python 的 @property 家族與 Self、Swift 的 Self、Go 的泛型型別參數、前方引用)。
  3. 新抽取器與可宣告的副檔名語意:EJS 抽取器、.graphifyrc 的 language.<ext>。
  4. 寫入保護:dedup 之後仍不會誤刪語意節點,update/export 的 node id 語意更嚴謹。

呼叫解析:同名不再誤綁

  • PHP(v0.9.87):Class::method() 的靜態呼叫改解析到被呼叫的方法,不再綁到 class 節點;同 namespace、不需 use import 的呼叫也不再停在 INFERRED 信心。self/static/parent 與小寫開頭的 class receiver 都走 PHP resolver,任何歧義或語料庫外的 receiver 一律 fail-closed(#3872、#3874)。
  • C#(v0.9.87):巢狀與泛型 partial 型別改用完整型別路徑合併(C# 泛型 arity 標記如 Outer`1.Inner),因此跨兩個檔案的巢狀 partial 會被合成一個,而 Foo 與 Foo<T> 保持不同;跨檔的非限定呼叫在「自己是唯一候選」時綁到呼叫者合併後的型別;有真實同名基底時,partial 上無來源的 placeholder 基底會被丟棄(#4363、#4364)。另外 var 改依被呼叫方法的回傳型別定型,讓後續的成員呼叫能解析(#4266、#4268)。
  • Java(v0.9.88):鏈式、new 與 cast receiver 的呼叫(factory.builder().size(3).build()、new Builder().size(1)、((Builder) o).build())改沿方法鏈上宣告的回傳型別解析,且只在單一明確目標時才綁定(#4306、#4307);從跨檔父型別繼承而來的裸呼叫與欄位 receiver 解析到最近的宣告父型別(class 勝過 interface default,平手則不綁)(#4304、#4305)。
  • TypeScript(v0.9.87):公開呼叫 c.name() 只在 class 真的宣告了公開 name 時才連到 #name 節點,且 foo 與 #foo 共用一個節點時公開呼叫仍保留自己的邊(#4298)。
  • JS/TS 匯入錨定(v0.9.88):裸或 scoped 的外部 import 改錨在套件名而非路徑末端——@scope-a/utils 與 @scope-b/utils 不再混同,lodash/fp/map 收斂到單一 lodash 節點(#3084、#3092)。
  • C/C++ include(v0.9.88):引號形式的跨目錄 include(#include "../lib/foo.h"、STM32 的 Core/Src 到 Core/Inc)改以唯一的最長共同目錄前綴匹配解析,同分 fail-closed,且對 ./、../、絕對路徑與角括號 include 永不猜測(#4354、#4392)。
  • PowerShell(v0.9.88):帶引號或 $PSScriptRoot 路徑的 dot-source include 開始產生 import 邊,function 之外的 script-scope 指令也被收為呼叫(#4356、#4369)。
  • Julia(v0.9.87):parametric 與 module-qualified 的 functor(可呼叫 struct)型別以其型別命名,不再退回變數綁定(#4351)。
隨堂測驗

Java 的 `factory.builder().size(3).build()` 這種鏈式呼叫,v0.9.88 之後是如何解析的?

💡 想先看個提示?

鏈式呼叫的型別資訊藏在「每個方法回傳什麼」裡。

不再鑄造假的 stub 節點

一批修正的共同句型是「不再 mint 一個無來源(sourceless)stub」——這些節點過去會污染圖譜、甚至吞掉真正的節點:

  • Python(v0.9.88):@name.setter/.getter/.deleter 裝飾器不再鑄造無來源 stub(#4380、#4385);Self(PEP 673)型別註解(-> Self、: Self、typing.Self)不再鑄造無來源的 self stub(#4381、#4386)。
  • Swift(v0.9.88):Self 型別註解不再鑄造無來源 self stub(#4382、#4387)。
  • Go(v0.9.88):簽名、struct 欄位與 interface 方法中的泛型型別參數([T any])不再鑄造無來源的 t/r stub(#4383、#4388)。
  • Python 前方引用(v0.9.88):在定義之前就被型別註記的 class(forward reference)不再鑄造與檔案節點碰撞、並把檔案節點吞掉的裸 stub(#4334、#4343)。
  • C# verbatim 字串(v0.9.88):抽取器現在能從「以轉義引號結尾的 verbatim interpolated string」之後恢復成員宣告,不再靜默丟掉檔案其餘部分;修正只遮罩出問題的位元組,且若重寫後無法乾淨重解析就整批丟棄(#3376、#3612)。
  • Python @property 讀取(v0.9.87,新功能):讀取 @property(obj.prop,含 x.prop += v)改為連結到 property 的 getter,不再被當成裸屬性存取而丟棄(#4337)。

新抽取器與可宣告的副檔名語意

  • EJS 抽取器(v0.9.88):.ejs 樣板現在有專屬抽取器——scriptlet 函式/類別、require/import 邊、dynamic import,以及 <%- include('partial') %> 的組合邊;此前整個檔案只產生一個 top-level 解析錯誤(#3811、#4338)。
  • .graphifyrc 的語言宣告(v0.9.87):專案可用 language.<ext>=<language|.ext> 這類行宣告模糊副檔名(.inc、.h、TS 家族)代表什麼語言。宣告會貫穿分類、抽取器選擇、imports、watch 與 AST cache;未宣告時偵測行為逐位元不變(#2961、#3789)。
隨堂測驗

專案裡有一個 `.inc` 檔案,Graphify 偶爾猜錯語言。v0.9.87 之後的正規解法是什麼?

💡 想先看個提示?

設定檔在 repo 根目錄,檔名以點開頭。

查詢與圖形介面

  • graphify query --seed(v0.9.88):可指定遍歷的起始節點(ids、labels、callable 名稱或路徑),讓外部 ranker 自己決定起始集合;無法解析的 seed 會被回報並跳過,整組都無法解析時 fail-closed,不會退回關鍵字 seed(#4293、#4289)。
  • graphify serve 的點號查詢(v0.9.88):pkg.mod.func、pkg.mod:func 這類 Python 查詢改以 module 路徑解析到符號,同檔歧義時 fail-closed,裸名查詢不受影響(#4366、#4367)。
  • graph.html:新增明/暗/跟隨系統主題切換,且暗色預設的前後輸出逐位元相同(#3894、#4300);側邊欄新增 hover tooltip,顯示被截斷的 legend/search/neighbor 全名與 legend 節點數,使用者文字以 textContent 寫入以保留內嵌 JSON 的轉義(#4286、#4291)。
  • MCP query_graph 的 seed 順序(v0.9.87):改以匹配強度排序,字母序較前的詞的弱匹配不再領先特定詞的精確匹配;每詞保證的 seed 仍在(#4357、#4358)。

寫入保護:dedup、shrink guard 與 node id

  • graphify affected <PR>(v0.9.87):影響範圍改以指定 PR 界定,不再用 repository 的預設分支;PR 預設分支的偵測獨立受測試(#3829)。
  • update 與 export 的 node id(v0.9.87):update 在節點總數成長時拒絕丟掉已儲存的語意節點 id(視為不完整的重新抽取),但仍允許移除已消失的 import stub;export 保留仍在圖中的整數節點 id(#4115)。
  • _origin 標記(v0.9.87):update skill 在語意層蓋上 _origin,讓只跑 AST 的 update 不能刪除它沒有重新抽取的語意節點(#2843、#3110)。
  • dedup 的路徑限定(v0.9.88):語意 id 若丟掉了目錄,dedup 現在會做路徑限定——a/x.md 與 b/x.md 不再塌成一個而遺失其中一個節點;第三方檔案對裸 id 的引用則留為未解析並附警告,而不是猜測(#4281、#4362)。
  • shrink guard 的豁免(v0.9.88):被 dedup 合法併入 AST 雙胞胎的語意節點不再被 shrink guard 誤擋;豁免範圍嚴格限定在「同路徑、同標籤、_origin=="ast" 的雙胞胎」,真正的部分建置遺失仍會被拒。LLM 節點/邊的欄位別名(file/filepath、relationship)會被折疊,且以標準欄位為準(#4389、#4391)。

watch、hook 與 install

  • watch 的整批重建(v0.9.87):rebuild lock 忙碌時不再靜默丟棄整批重建,而是排入佇列(取代已排入的 incremental 路徑)並在進行中的 rebuild 之後清空;且只在真的排入時才印出 changes queued(#4274、#4276)。
  • hook 的軟性提示(v0.9.87):read/search 的軟性提示改為每 session 有界,不再對每個符合的檔案都觸發(#3435、#3443)。
  • update skill 的輸出(v0.9.87):只印出增量步驟的短摘要,完整結果留在 .graphify_incremental.json,不再把每個檔案路徑倒進 agent context(#3952)。
  • install/uninstall 的邊界(v0.9.88):只移除自己的 hook 條目——以 hook-guard/hook-check 指令鍵判斷,而不是寬鬆的 graphify 子字串,因此同群組的其他使用者 hook 與指令會被保留,且 uninstall 走備份(#4359、#4373);CLAUDE.md、AGENTS.md 與同類檔案在 install/uninstall 前後保留原本的行尾(CRLF 或 LF),不再被正規化為平台預設(#4360、#4372)。
  • wiki 索引(v0.9.88):兩個 community 或 god-node 同名時,索引列改為各自連到自己的文章,而不是都指向第一個註冊的 slug 而讓另一篇孤立(#3032、#3033、#3095)。
  • benchmark 與 labeling:benchmark 改為計算 query_graph 實際回傳答案的 token(呼叫真正有預算的查詢路徑),而不是另一份無預算的重新實作(#4347、#4348);labeling 遵守 GRAPHIFY_CLAUDE_CLI_MODEL 環境變數,不再靜默退回 session 的預設模型(#3846、#3876)。

動手升級檢查清單

升級 v0.9.88:動手檢查清單

逐項勾選,確認你已完成升級必要的步驟(進度會保存在此瀏覽器)

0 / 5

延伸閱讀