fix Husky 9 hook path, skill.md INPUT_PATH literal, per-worker exception isolation

- hooks.py: add _user_hooks_dir() to target .husky/ instead of .husky/_ on Husky 9 repos (#987)
- skill.md: replace unsubstituted 'INPUT_PATH' literal with '.' in generate() calls (#986)
- extract.py: wrap future.result() per-future so a single worker failure prints a warning instead of falling back to full sequential re-extraction (#943)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Safi
2026-05-23 23:17:40 +01:00
parent 461e346f3a
commit 71b4e57b67
3 changed files with 27 additions and 7 deletions
+9 -2
View File
@@ -7434,8 +7434,15 @@ def _extract_parallel(
pool.submit(_extract_single_file, item): item[0] for item in work_items
}
for future in concurrent.futures.as_completed(futures):
idx, result = future.result()
per_file[idx] = result
try:
idx, result = future.result()
per_file[idx] = result
except Exception as exc:
idx = futures[future]
print(
f" warning: worker failed for {work_items[idx][1]}: {exc}",
file=sys.stderr, flush=True,
)
done_count += 1
if (
total_files >= _PROGRESS_INTERVAL
+16 -3
View File
@@ -259,13 +259,26 @@ def _uninstall_hook(hooks_dir: Path, name: str, marker: str, marker_end: str) ->
return f"graphify removed from {name} at {hook_path} (other hook content preserved)"
def _user_hooks_dir(hooks_dir: Path) -> Path:
"""Return the user-editable hooks directory.
Husky 9 sets core.hooksPath to .husky/_ (wrapper scripts auto-generated by
Husky), while user-editable hooks live in the parent .husky/. Return the
parent when the resolved dir ends in '_' so install/status/uninstall target
the correct location (#987).
"""
if hooks_dir.name == "_":
return hooks_dir.parent
return hooks_dir
def install(path: Path = Path(".")) -> str:
"""Install graphify post-commit and post-checkout hooks in the nearest git repo."""
root = _git_root(path)
if root is None:
raise RuntimeError(f"No git repository found at or above {path.resolve()}")
hooks_dir = _hooks_dir(root)
hooks_dir = _user_hooks_dir(_hooks_dir(root))
commit_msg = _install_hook(hooks_dir, "post-commit", _HOOK_SCRIPT, _HOOK_MARKER)
checkout_msg = _install_hook(hooks_dir, "post-checkout", _CHECKOUT_SCRIPT, _CHECKOUT_MARKER)
@@ -279,7 +292,7 @@ def uninstall(path: Path = Path(".")) -> str:
if root is None:
raise RuntimeError(f"No git repository found at or above {path.resolve()}")
hooks_dir = _hooks_dir(root)
hooks_dir = _user_hooks_dir(_hooks_dir(root))
commit_msg = _uninstall_hook(hooks_dir, "post-commit", _HOOK_MARKER, _HOOK_MARKER_END)
checkout_msg = _uninstall_hook(hooks_dir, "post-checkout", _CHECKOUT_MARKER, _CHECKOUT_MARKER_END)
@@ -291,7 +304,7 @@ def status(path: Path = Path(".")) -> str:
root = _git_root(path)
if root is None:
return "Not in a git repository."
hooks_dir = _hooks_dir(root)
hooks_dir = _user_hooks_dir(_hooks_dir(root))
def _check(name: str, marker: str) -> str:
p = hooks_dir / name
+2 -2
View File
@@ -537,7 +537,7 @@ labels = {cid: 'Community ' + str(cid) for cid in communities}
# Placeholder questions - regenerated with real labels in Step 5
questions = suggest_questions(G, communities, labels)
report = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, 'INPUT_PATH', suggested_questions=questions)
report = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, '.', suggested_questions=questions)
Path('graphify-out/GRAPH_REPORT.md').write_text(report, encoding=\"utf-8\")
to_json(G, communities, 'graphify-out/graph.json')
@@ -591,7 +591,7 @@ labels = LABELS_DICT
# Regenerate questions with real community labels (labels affect question phrasing)
questions = suggest_questions(G, communities, labels)
report = generate(G, communities, cohesion, labels, analysis['gods'], analysis['surprises'], detection, tokens, 'INPUT_PATH', suggested_questions=questions)
report = generate(G, communities, cohesion, labels, analysis['gods'], analysis['surprises'], detection, tokens, '.', suggested_questions=questions)
Path('graphify-out/GRAPH_REPORT.md').write_text(report, encoding=\"utf-8\")
Path('graphify-out/.graphify_labels.json').write_text(json.dumps({str(k): v for k, v in labels.items()}, ensure_ascii=False), encoding=\"utf-8\")
print('Report updated with community labels')