diff --git a/CHANGELOG.md b/CHANGELOG.md index 37579c1e..55d8fb06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases) +## 0.3.21 (2026-04-09) + +- Fix: Codex PreToolUse hook now places `systemMessage` at the top level of the output JSON instead of inside `hookSpecificOutput` — matches the strict schema enforced by codex-cli 0.118.0+ which uses `additionalProperties: false` (#138) +- Fix: git hooks now use `#!/bin/sh` instead of `#!/bin/bash` — Git for Windows ships `sh.exe` not `bash`, so hooks were silently skipped on Windows (#140) + ## 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 diff --git a/graphify/__main__.py b/graphify/__main__.py index 6d8fcc5d..3f31b7cc 100644 --- a/graphify/__main__.py +++ b/graphify/__main__.py @@ -251,7 +251,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","permissionDecision":"allow"},"systemMessage":"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/hooks.py b/graphify/hooks.py index f2c74e3c..92320272 100644 --- a/graphify/hooks.py +++ b/graphify/hooks.py @@ -124,7 +124,7 @@ def _install_hook(hooks_dir: Path, name: str, script: str, marker: str) -> str: return f"already installed at {hook_path}" hook_path.write_text(content.rstrip() + "\n\n" + script) return f"appended to existing {name} hook at {hook_path}" - hook_path.write_text("#!/bin/bash\n" + script) + hook_path.write_text("#!/bin/sh\n" + script) hook_path.chmod(0o755) return f"installed at {hook_path}" @@ -143,7 +143,7 @@ def _uninstall_hook(hooks_dir: Path, name: str, marker: str, marker_end: str) -> content, flags=re.DOTALL, ).strip() - if not new_content or new_content == "#!/bin/bash": + if not new_content or new_content in ("#!/bin/bash", "#!/bin/sh"): hook_path.unlink() return f"removed {name} hook at {hook_path}" hook_path.write_text(new_content + "\n") diff --git a/pyproject.toml b/pyproject.toml index eec49bb5..627abc43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "graphifyy" -version = "0.3.20" +version = "0.3.21" 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" }