概述
v0.9.96 於 2026-10-26 發布。本版主軸有三:
- 依賴安全清倉:Pillow 下限在 Python 3.11+ 升到
>=13.0.0、pypdf 升到>=6.19.0,lockfile 刷新到 transitive 相依的修補版本——官方原文:「This clears the bulk of the open Dependabot advisories」。 update效能:無關聯輸入變更時,graphify update直接跳過 detect/extract/build 管線、輸出保持原樣。- watch 穩定性:每次 watch 重建受
GRAPHIFY_REBUILD_TIMEOUT(預設 600 秒)約束,卡死的重建不再拖垮 watcher。
其餘是橫跨 14 個標籤(llm、python、watch、prs、export、build、zig、dart、ts、js、detect、robot、vbnet、rust、dedup、cli)的 30+ 項解析與管線修正。
依賴安全:Pillow、pypdf 與 lockfile
官方原文逐點:
- Pillow 下限:Python 3.11+ 升到
>=13.0.0;Python 3.10 維持>=12.3.0——因為 Pillow 13 不再支援 3.10。 - pypdf 下限:升到
>=6.19.0。 - lockfile 刷新:transitive 相依(pyjwt、cryptography、certifi、urllib3、anyio、fsspec、soupsieve、virtualenv)全部換到修補版本。
update 無變更即跳過管線(Perf)
過去 graphify update 即使輸入沒有任何相關變更,也會重跑 detect/extract/build。本版起(#4740、#4748,感謝 @Deepjyoti-Sarmah;回報 by @lavaxun):
- 跳過條件 keyed on:掃描檔案集(scan file-set)、config、
.graphifyrc、extractor epoch 與 output-completeness stamp(輸出完整性戳記)——五項都沒變就跳過整條管線、輸出不動。 - 安全閥:掃到的檔案若在 manifest 沒有對應 row(包括之前抽取失敗的檔案),仍強制全重建——官方原文:「so a later fix is never skipped」。之後版本修好的抽取問題不會因為「上次失敗、這次跳過」而被吃掉。
watch 穩定性:重建逾時與論文快掃
- 重建逾時(#2173、#4724,感謝 @danieldutu):每次 watch 重建以
GRAPHIFY_REBUILD_TIMEOUT為上限(預設 600 秒,0停用);在SIGALRM不可用或watch()不在主執行緒的環境改用 thread-Timer 後備(在那裡 armSIGALRM會拋ValueError、在重建開始前就把 watcher 拆掉)。卡死的重建不再讓 watcher 停擺。 - Markdown 論文納入快掃(#4750、#4751,感謝 @jaimemartinez;回報 by @yeochul-jeon):
detect()分類為論文(arXiv 標記、Abstract)的 Markdown 檔現在納入 watch quick-scan 重建,不再貢獻零節點;已有 semantic layer 的論文仍排除於 AST 快掃之外。
LLM 後端修正×3
- DeepSeek 上限生效(#4739、#4753,感謝 @Ethereal49;回報 by @snapp-kenya):DeepSeek backend 改以
max_tokens送出輸出上限(DeepSeek 認得這個參數),不再送它會忽略的max_completion_tokens——回應不再靜默未設上限。 - 失敗 chunk 不算 model omissions(#3616、#4752):在回應前就失敗的 chunk,其檔案不再被回報為模型遺漏;警告會區分「失敗的 chunk」與「真正的遺漏」,兩者都仍會重新派發。
- Ollama context window 估計(#4414、#4761):視窗大小改以「非拉丁字元算整個 token」的估計與真實 system-prompt 長度計算,非英文或過長的 prompt 不再被靜默截斷。
語言與管線修正批次
| 範圍 | 修正 | PR |
|---|---|---|
| prs | 所有未完成 CheckRun 狀態(WAITING、REQUESTED、PENDING…)都算 pending CI——被 deployment-protection job 擋住的 PR 不再被誤判為 ready |
#4730 |
| export | Obsidian 筆記列出兩節點間所有平行關係(同時 imports 與 calls),不再只列第一條邊 |
#4731 |
| build | hyperedge 成員以 members/node_ids 別名給定時,數字 id 也轉字串(比照正規 nodes),hyperedge 不再被丟掉 |
#4732 |
| llm | confidence 大小寫不同(extracted/Extracted)的 code node 仍先驗證再折疊到 EXTRACTED,未驗證節點不再以固態呈現 |
#4733 |
| python | member call 綁到實際拼寫的方法,不做大小寫/底線折疊(run() 不再解析到 _run());真碰撞時 fail closed |
#4734 |
| python | 只綁 Python caller 到 Python target——別的語言的同名類別不再被誤綁為呼叫 | #4757 |
| python | 經建構子參數注入的欄位、或由方法回傳型別標註的區域變數的呼叫,解析到目標方法(INFERRED);需單一無歧義 producer 與 class |
#4726 |
| zig | 呼叫不再橫跨方法與同名自由函式;裸呼叫綁自由函式、receiver 呼叫綁方法 | #4755 |
| dart | 未命名的 extension on T { } 宣告可被偵測抽取(名稱為選填),成員掛到被擴展型別 |
#4741 |
| extract | XAML codebehind(*.xaml 對 *.xaml.cs)解析與目錄迭代順序無關——case-sensitive 檔案系統上的圖譜穩定 |
#4747 |
| extract | AST cache 命中率以檔案總數(而非未快取集合)為分母,warm run 不再印出誤導的「100% uncached」 | #4740/#4746 |
| dedup | 兩檔案以 module/namespace 合法共用的 node id 不再印「minted by two different files」假警告 |
#4756 |
| dedup | LLM 標記的跨文件 reference stub 與真實定義碰撞時改做 namespace 隔離,兩個節點都不丟 | #4738/#4743 |
| cli | PreToolUse hook 提醒改以事實而非命令句措辭——agent 的工具結果流不再把它讀成 prompt injection 而忽略 | #2202/#4764 |
| cli | graphify extract 每次執行的 token 用量記到 graphify-out/cost.json(與 skill 寫同一本帳),獨立抽取也更新成本歷史 |
#1769/#4765 |
| ts | 鏈式 TypeScript decorators(@(Link().toMany()))復原為 decorator reference;lossy-parse 警告指出真實錯誤區域 |
#4711/#4715 |
| js | const X = require('pkg') 的外部套件綁定保留節點(套件為 source)讓 new X() 仍解析;corpus 內部檔案的 require 仍折疊 |
#4688/#4702 |
| detect | MSBuild 產出的 obj/、bin/ 只在出現 build 證據(restore/runtime 標記)時修剪——建置後掃描不再吃進生成原始碼,真正的 src/bin 保留 |
#4742 |
| robot | 同名 test case 各自取得節點(以行號加 salt),兩個同名測試保持相異 | #4697 |
| vbnet | 外部 namespace 與 type 改發出帶空 source_file 哨兵的 sourceless stub(比照其他語言),不再產生驗證失敗的節點 |
#4725/#4728 |
| rust | use 限定到指名的 crate——use serde_json::Value 不再解析到別的 crate 的同名型別;具名 pub use re-export 會被跟隨,無 manifest 綁定維持 INFERRED |
#4699/#4712 |
隨堂測驗
v0.9.96 起,`graphify update` 在下列哪個情境仍會「強制全重建」、不吃跳過優化?
💡 想先看個提示?
跳過的判準是五個 key 都沒變;但有一類檔案被明列為「永遠不能跳過」。
官方原文:「a scanned file with no manifest row (including one whose extraction previously failed) still forces a full rebuild so a later fix is never skipped」——沒有 manifest row 的檔案(含先前抽取失敗者)會強制全重建,確保之後版本的修復不會被跳過優化吃掉。
動手升級檢查清單
升級 v0.9.96:動手檢查清單
逐項勾選,確認你已完成升級必要的步驟(進度會保存在此瀏覽器)
全部完成!你已就緒 v0.9.96 的所有新功能。可清除勾選重新練習。
延伸閱讀
- 官方 v0.9.96 release notes
- 前一課:
v0995-community-batch-yaml-and-install-security——21 個社群 PR、YAML 進圖譜與安裝安全