From b101a99d2ff801fb6b09ec33f7f0ca8f583240b5 Mon Sep 17 00:00:00 2001 From: Safi Date: Thu, 9 Apr 2026 09:36:32 +0100 Subject: [PATCH] Pin tree-sitter>=0.23.0, add version guard, confidence=EXTRACTED for AST calls Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 7 +++++++ graphify/extract.py | 20 ++++++++++++++++++++ pyproject.toml | 4 ++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73b60ee2..37579c1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases) +## 0.3.20 (2026-04-09) + +- Fix: XSS in interactive HTML graph — node labels, file types, community names, source files, and edge relations now HTML-escaped before `innerHTML` injection; neighbor link `onclick` uses `JSON.stringify` instead of raw string interpolation +- Add: OpenCode `tool.execute.before` plugin — `graphify opencode install` now writes `.opencode/plugins/graphify.js` and registers it in `opencode.json`, firing the graph reminder before bash calls (equivalent to Claude Code's PreToolUse hook) (#71) +- Fix: AST-resolved call edges now carry `confidence=EXTRACTED, weight=1.0` instead of INFERRED/0.8 — tree-sitter call resolution is deterministic, not probabilistic (#127) +- Fix: `tree-sitter>=0.23.0` now pinned in dependencies and `_check_tree_sitter_version()` guard added — stale environments now get a clear `RuntimeError` with upgrade instructions instead of a cryptic `TypeError` deep in the AST pipeline (#89) + ## 0.3.19 (2026-04-09) - Fix: install step now tries plain `pip install` before falling back to `--break-system-packages` — Homebrew and PEP 668 managed environments no longer risk environment corruption (#126) diff --git a/graphify/extract.py b/graphify/extract.py index 0fdd4fd5..c767e07f 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -2546,6 +2546,25 @@ def extract_elixir(path: Path) -> dict: # ── Main extract and collect_files ──────────────────────────────────────────── + +def _check_tree_sitter_version() -> None: + """Raise a clear error if tree-sitter is too old for the new Language API.""" + try: + from tree_sitter import LANGUAGE_VERSION + except ImportError: + raise ImportError( + "tree-sitter is not installed. Run: pip install 'tree-sitter>=0.23.0'" + ) + # Language API v2 starts at LANGUAGE_VERSION 14 + if LANGUAGE_VERSION < 14: + import tree_sitter as _ts + raise RuntimeError( + f"tree-sitter {getattr(_ts, '__version__', 'unknown')} is too old. " + f"graphify requires tree-sitter >= 0.23.0 (Language API v2). " + f"Run: pip install --upgrade tree-sitter" + ) + + def extract(paths: list[Path]) -> dict: """Extract AST nodes and edges from a list of code files. @@ -2554,6 +2573,7 @@ def extract(paths: list[Path]) -> dict: 2. Cross-file import resolution: turns file-level imports into class-level INFERRED edges (DigestAuth --uses--> Response) """ + _check_tree_sitter_version() per_file: list[dict] = [] # Infer a common root for cache keys diff --git a/pyproject.toml b/pyproject.toml index 7abe4e21..eec49bb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "graphifyy" -version = "0.3.19" +version = "0.3.20" description = "AI coding assistant skill (Claude Code, Codex, OpenCode, OpenClaw) - turn any folder of code, docs, papers, or images into a queryable knowledge graph" readme = "README.md" license = { file = "LICENSE" } @@ -12,7 +12,7 @@ keywords = ["claude", "claude-code", "codex", "opencode", "knowledge-graph", "ra requires-python = ">=3.10" dependencies = [ "networkx", - "tree-sitter>=0.21", + "tree-sitter>=0.23.0", "tree-sitter-python", "tree-sitter-javascript", "tree-sitter-typescript",