Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu

## Unreleased

- Fix: `graph.html` is now part of the dated pre-overwrite snapshot (`graphify-out/YYYY-MM-DD/`). `backup_if_protected` preserved every other artifact of a protected graph before a rebuild overwrote it, but not the interactive viewer — so each run silently destroyed the only browsable copy of the previous graph, and the dated folders could not be opened in a browser at all.
- Fix: `graphify install --platform hermes` now installs to the right directory on Windows. Hermes scans `%LOCALAPPDATA%\hermes\skills`, but the installer always used the POSIX `~/.hermes/skills` (so on Windows the skill was never discovered). `_platform_skill_destination` gained a hermes branch that targets `%LOCALAPPDATA%\hermes\skills` on Windows and keeps `~/.hermes/skills` elsewhere (#1403).
- Fix: cross-file type-annotation references no longer create phantom duplicate nodes. A class defined once but referenced via type annotations in N other files (`def f(x: Thing) -> Thing`) produced 1+N nodes — the extra ones with the referencing file's path baked into the id (`pkg_a_py_thing`). `ensure_named_node` minted a *sourced* stub for these cross-file refs, which `_disambiguate_colliding_node_ids` then collided into per-file ids and `_rewire_unique_stub_nodes` refused to collapse. The fallback now emits a *sourceless* stub (like the inheritance-base path), so the references resolve to the single canonical definition. Fixed uniformly across all six language extractors that share the helper (#1402).
- Feat: CUDA (`.cu`/`.cuh`) source files are now extracted. CUDA is a C++ superset, so these files route through the existing C++ (`tree-sitter-cpp`) extractor — no new grammar dependency. `__global__`/`__device__` kernels, host functions, structs and `#include`s are captured, host call edges are inferred, and `<<<grid, block>>>` kernel-launch syntax parses without error. Detection and file-watching follow automatically since both derive their extension sets from the dispatch table / `CODE_EXTENSIONS` (#1411).
Expand Down
3 changes: 3 additions & 0 deletions graphify/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
"manifest.json",
".graphify_semantic_marker",
"cost.json",
# The rendered viewer is regenerable, but only by re-running the build it
# belongs to — without it the dated folder can't be opened in a browser.
"graph.html",
]


Expand Down
11 changes: 11 additions & 0 deletions tests/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,17 @@ def test_backup_semantic_marker(tmp_path):
assert (result / ".graphify_semantic_marker").exists()


def test_backup_includes_graph_html(tmp_path):
"""graph.html is snapshotted with the rest, so the dated folder is browsable."""
from graphify.export import backup_if_protected
(tmp_path / "graph.json").write_text('{"nodes":[],"links":[]}')
(tmp_path / "graph.html").write_text("<html>old viewer</html>")
(tmp_path / ".graphify_semantic_marker").write_text("{}")
result = backup_if_protected(tmp_path)
assert result is not None
assert (result / "graph.html").read_text() == "<html>old viewer</html>"


def test_backup_curated_labels(tmp_path):
"""graph.json + non-default label in .graphify_labels.json → backup taken."""
import json
Expand Down