From 0a4e6915c1fd1cee6f57a5fdb310fe447225ee8d Mon Sep 17 00:00:00 2001 From: Safi Date: Sun, 12 Apr 2026 18:37:54 +0100 Subject: [PATCH] fix #261, #249, #266 and bump to 0.4.4 - watch.py: preserve INFERRED/AMBIGUOUS edges (code<->doc) across rebuilds (#261) - __main__.py: fix Codex hook - use additionalContext instead of permissionDecision:allow (#249) - detect.py: skip common lockfiles (package-lock.json, yarn.lock, Cargo.lock etc.) (#266) Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 6 ++++++ graphify/__main__.py | 2 +- graphify/detect.py | 9 +++++++++ graphify/watch.py | 3 ++- pyproject.toml | 2 +- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f8758ea..5f3a4532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases) +## 0.4.4 (2026-04-12) + +- Fix: `watch` now preserves INFERRED/AMBIGUOUS edges (code↔doc rationale links) across rebuilds — previously all cross-type edges were dropped (#261) +- Fix: Codex hook no longer emits `permissionDecision:allow` which codex-cli 0.120.0 rejects (#249) +- Fix: Common lockfiles (`package-lock.json`, `yarn.lock`, `Cargo.lock`, etc.) are now skipped during detection, preventing token drain on large JS/Rust/Python projects (#266) + ## 0.4.3 (2026-04-12) - Fix: JS/TS relative imports now resolve to full-path node IDs — previously all `imports_from` edges were silently dropped on large TypeScript codebases (#256) diff --git a/graphify/__main__.py b/graphify/__main__.py index 912113bb..90ac9736 100644 --- a/graphify/__main__.py +++ b/graphify/__main__.py @@ -428,7 +428,7 @@ _CODEX_HOOK = { "type": "command", "command": ( "[ -f graphify-out/graph.json ] && " - r"""echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"},"systemMessage":"graphify: Knowledge graph exists. Read graphify-out/GRAPH_REPORT.md for god nodes and community structure before searching raw files."}' """ + r"""echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"graphify: Knowledge graph exists. Read graphify-out/GRAPH_REPORT.md for god nodes and community structure before searching raw files."}}' """ "|| true" ), } diff --git a/graphify/detect.py b/graphify/detect.py index 8f71581d..53ab095a 100644 --- a/graphify/detect.py +++ b/graphify/detect.py @@ -241,6 +241,13 @@ _SKIP_DIRS = { ".tox", ".eggs", "*.egg-info", } +# Large generated files that are never useful to extract +_SKIP_FILES = { + "package-lock.json", "yarn.lock", "pnpm-lock.yaml", + "Cargo.lock", "poetry.lock", "Gemfile.lock", + "composer.lock", "go.sum", "go.work.sum", +} + def _is_noise_dir(part: str) -> bool: """Return True if this directory name looks like a venv, cache, or dep dir.""" if part in _SKIP_DIRS: @@ -357,6 +364,8 @@ def detect(root: Path, *, follow_symlinks: bool = False) -> dict: and not _is_ignored(dp / d, root, ignore_patterns) ] for fname in filenames: + if fname in _SKIP_FILES: + continue p = dp / fname if p not in seen: seen.add(p) diff --git a/graphify/watch.py b/graphify/watch.py index b9421e1d..09f65d0d 100644 --- a/graphify/watch.py +++ b/graphify/watch.py @@ -44,7 +44,8 @@ def _rebuild_code(watch_path: Path, *, follow_symlinks: bool = False) -> bool: code_ids = {n["id"] for n in existing.get("nodes", []) if n.get("file_type") == "code"} sem_nodes = [n for n in existing.get("nodes", []) if n.get("file_type") != "code"] sem_edges = [e for e in existing.get("edges", []) - if e.get("source") not in code_ids and e.get("target") not in code_ids] + if e.get("confidence") in ("INFERRED", "AMBIGUOUS") + or (e.get("source") not in code_ids and e.get("target") not in code_ids)] result = { "nodes": result["nodes"] + sem_nodes, "edges": result["edges"] + sem_edges, diff --git a/pyproject.toml b/pyproject.toml index c370b446..3c9f34f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "graphifyy" -version = "0.4.3" +version = "0.4.4" description = "AI coding assistant skill (Claude Code, Codex, OpenCode, Cursor, OpenClaw, Factory Droid, Trae) - turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph" readme = "README.md" license = { file = "LICENSE" }