You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Committing graphify-out/ (or $GRAPHIFY_OUT) to git is the documented way to share incremental cache + graph artifacts across a team / CI. Today three artifacts contain absolute paths and break on clone to a different filesystem location:
graph.json is already correctly relativized via watch._relativize_source_files (since 0.5.0) — proves the intent and the pattern.
Filing as a separate bug (rather than commenting on #722) because (a) #722 is question-shaped and limited to manifest + .gitignore, (b) cache/ast/*.json is a distinct artifact with the same root cause, (c) this draft includes a concrete fix + PR offer. Linking #722 to consolidate triage.
Move /tmp/p to /tmp/q (or clone the committed graphify-out/ on another host): incremental detection misses, root resolution breaks, diffs churn on every rebuild.
Proposed fix
Three small changes mirroring the existing _relativize_source_files, each backwards compatible (relpath fallback to abspath when target escapes root):
graphify/detect.py::save_manifest — relativize keys against root before serialization. Skip entries where os.path.relpath(...).startswith("..") (paths outside the root) and write them absolute, matching _relativize_source_files.
graphify/watch.py::_rebuild_code — write the user-provided watch_path (often .) to .graphify_root instead of the resolved absolute watch_root.
graphify/cache.py::save_cached — walk result["nodes"] + result["edges"], relativize source_file fields against root using the same helper, before JSON dump.
Symmetric loaders (load_manifest, load_cached, __main__ root resolution) re-anchor relative paths against CWD / --root — matches the pattern that already works for graph.json.
Workaround (for context)
Two-way normalize-paths.py PreToolUse/PostToolUse hook flips manifest, root, and cache/ast paths abs↔rel around every graphify invocation. Plus a small runtime shim that patches watch.py to pass manifest_path explicitly. See lib/graphify/install.sh::_patch_graphify_watch and .nvm-isolated/.claude-isolated/hooks/normalize-paths.py in iclaude. Brittle — would rather drop both once upstream lands.
PR offer
Happy to submit a single PR with the three changes + tests (test_save_manifest_relativizes_keys, test_save_cached_relativizes_source_file, test_graphify_root_preserves_relative) after triage / scope confirmation.
Problem
Committing
graphify-out/(or$GRAPHIFY_OUT) to git is the documented way to share incremental cache + graph artifacts across a team / CI. Today three artifacts contain absolute paths and break on clone to a different filesystem location:manifest.json— keys are absolute (/home/alice/proj/foo.py).detect_incrementalcache miss → full rebuild on every other machine. Same observation as Question — manifest.json absolute paths + missing graphify-out/.gitignore: intended or oversight? #722 (filed there as a "question")..graphify_root— absolute project path.graphify updatewith no args fails (or scans the wrong tree) after clone.cache/ast/*.json—source_filefield on cached nodes/edges is absolute. Not directly fatal but pollutes diffs and leaks user paths into commits. Not covered by Question — manifest.json absolute paths + missing graphify-out/.gitignore: intended or oversight? #722.graph.jsonis already correctly relativized viawatch._relativize_source_files(since 0.5.0) — proves the intent and the pattern.Filing as a separate bug (rather than commenting on #722) because (a) #722 is question-shaped and limited to manifest +
.gitignore, (b)cache/ast/*.jsonis a distinct artifact with the same root cause, (c) this draft includes a concrete fix + PR offer. Linking #722 to consolidate triage.Reproduce
Move
/tmp/pto/tmp/q(or clone the committedgraphify-out/on another host): incremental detection misses, root resolution breaks, diffs churn on every rebuild.Proposed fix
Three small changes mirroring the existing
_relativize_source_files, each backwards compatible (relpath fallback to abspath when target escapes root):graphify/detect.py::save_manifest— relativize keys againstrootbefore serialization. Skip entries whereos.path.relpath(...).startswith("..")(paths outside the root) and write them absolute, matching_relativize_source_files.graphify/watch.py::_rebuild_code— write the user-providedwatch_path(often.) to.graphify_rootinstead of the resolved absolutewatch_root.graphify/cache.py::save_cached— walkresult["nodes"]+result["edges"], relativizesource_filefields againstrootusing the same helper, before JSON dump.Symmetric loaders (
load_manifest,load_cached,__main__root resolution) re-anchor relative paths against CWD /--root— matches the pattern that already works forgraph.json.Workaround (for context)
Two-way
normalize-paths.pyPreToolUse/PostToolUse hook flips manifest, root, and cache/ast paths abs↔rel around everygraphifyinvocation. Plus a small runtime shim that patcheswatch.pyto passmanifest_pathexplicitly. Seelib/graphify/install.sh::_patch_graphify_watchand.nvm-isolated/.claude-isolated/hooks/normalize-paths.pyin iclaude. Brittle — would rather drop both once upstream lands.PR offer
Happy to submit a single PR with the three changes + tests (
test_save_manifest_relativizes_keys,test_save_cached_relativizes_source_file,test_graphify_root_preserves_relative) after triage / scope confirmation.Related: #722.
Environment
0.7.7GRAPHIFY_OUT=.graphifycommitted to git)