From 5f2db35c65ac214bc0efcf97d7f2c93964c1e740 Mon Sep 17 00:00:00 2001 From: Daisy Hollman Date: Fri, 19 Dec 2025 02:54:38 +0000 Subject: [PATCH] Fix hookify plugin import error: No module named 'hookify' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hook scripts used absolute imports like `from hookify.core.config_loader` but when installed, the plugin lives in a cache directory with a hash name, not in a directory named `hookify/`. Python couldn't resolve the package. Changed to local imports (`from core.X`) which work because PLUGIN_ROOT is added to sys.path. Also simplified the sys.path setup. Fixes: https://github.com/anthropics/claude-code/issues/14267 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- plugins/hookify/core/rule_engine.py | 4 ++-- plugins/hookify/hooks/posttooluse.py | 14 +++++--------- plugins/hookify/hooks/pretooluse.py | 18 +++++------------- plugins/hookify/hooks/stop.py | 14 +++++--------- plugins/hookify/hooks/userpromptsubmit.py | 14 +++++--------- 5 files changed, 22 insertions(+), 42 deletions(-) diff --git a/plugins/hookify/core/rule_engine.py b/plugins/hookify/core/rule_engine.py index 8244c00..51561c3 100644 --- a/plugins/hookify/core/rule_engine.py +++ b/plugins/hookify/core/rule_engine.py @@ -7,7 +7,7 @@ from functools import lru_cache from typing import List, Dict, Any, Optional # Import from local module -from hookify.core.config_loader import Rule, Condition +from core.config_loader import Rule, Condition # Cache compiled regexes (max 128 patterns) @@ -275,7 +275,7 @@ class RuleEngine: # For testing if __name__ == '__main__': - from hookify.core.config_loader import Condition, Rule + from core.config_loader import Condition, Rule # Test rule evaluation rule = Rule( diff --git a/plugins/hookify/hooks/posttooluse.py b/plugins/hookify/hooks/posttooluse.py index a9e12cc..9c6ccd9 100755 --- a/plugins/hookify/hooks/posttooluse.py +++ b/plugins/hookify/hooks/posttooluse.py @@ -9,18 +9,14 @@ import os import sys import json -# CRITICAL: Add plugin root to Python path for imports +# Add plugin root to Python path for imports PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT') -if PLUGIN_ROOT: - parent_dir = os.path.dirname(PLUGIN_ROOT) - if parent_dir not in sys.path: - sys.path.insert(0, parent_dir) - if PLUGIN_ROOT not in sys.path: - sys.path.insert(0, PLUGIN_ROOT) +if PLUGIN_ROOT and PLUGIN_ROOT not in sys.path: + sys.path.insert(0, PLUGIN_ROOT) try: - from hookify.core.config_loader import load_rules - from hookify.core.rule_engine import RuleEngine + from core.config_loader import load_rules + from core.rule_engine import RuleEngine except ImportError as e: error_msg = {"systemMessage": f"Hookify import error: {e}"} print(json.dumps(error_msg), file=sys.stdout) diff --git a/plugins/hookify/hooks/pretooluse.py b/plugins/hookify/hooks/pretooluse.py index f265c27..9aff519 100755 --- a/plugins/hookify/hooks/pretooluse.py +++ b/plugins/hookify/hooks/pretooluse.py @@ -9,22 +9,14 @@ import os import sys import json -# CRITICAL: Add plugin root to Python path for imports -# We need to add the parent of the plugin directory so Python can find "hookify" package +# Add plugin root to Python path for imports PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT') -if PLUGIN_ROOT: - # Add the parent directory of the plugin - parent_dir = os.path.dirname(PLUGIN_ROOT) - if parent_dir not in sys.path: - sys.path.insert(0, parent_dir) - - # Also add PLUGIN_ROOT itself in case we have other scripts - if PLUGIN_ROOT not in sys.path: - sys.path.insert(0, PLUGIN_ROOT) +if PLUGIN_ROOT and PLUGIN_ROOT not in sys.path: + sys.path.insert(0, PLUGIN_ROOT) try: - from hookify.core.config_loader import load_rules - from hookify.core.rule_engine import RuleEngine + from core.config_loader import load_rules + from core.rule_engine import RuleEngine except ImportError as e: # If imports fail, allow operation and log error error_msg = {"systemMessage": f"Hookify import error: {e}"} diff --git a/plugins/hookify/hooks/stop.py b/plugins/hookify/hooks/stop.py index fc299bc..b922a88 100755 --- a/plugins/hookify/hooks/stop.py +++ b/plugins/hookify/hooks/stop.py @@ -9,18 +9,14 @@ import os import sys import json -# CRITICAL: Add plugin root to Python path for imports +# Add plugin root to Python path for imports PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT') -if PLUGIN_ROOT: - parent_dir = os.path.dirname(PLUGIN_ROOT) - if parent_dir not in sys.path: - sys.path.insert(0, parent_dir) - if PLUGIN_ROOT not in sys.path: - sys.path.insert(0, PLUGIN_ROOT) +if PLUGIN_ROOT and PLUGIN_ROOT not in sys.path: + sys.path.insert(0, PLUGIN_ROOT) try: - from hookify.core.config_loader import load_rules - from hookify.core.rule_engine import RuleEngine + from core.config_loader import load_rules + from core.rule_engine import RuleEngine except ImportError as e: error_msg = {"systemMessage": f"Hookify import error: {e}"} print(json.dumps(error_msg), file=sys.stdout) diff --git a/plugins/hookify/hooks/userpromptsubmit.py b/plugins/hookify/hooks/userpromptsubmit.py index 28ee51f..6f54585 100755 --- a/plugins/hookify/hooks/userpromptsubmit.py +++ b/plugins/hookify/hooks/userpromptsubmit.py @@ -9,18 +9,14 @@ import os import sys import json -# CRITICAL: Add plugin root to Python path for imports +# Add plugin root to Python path for imports PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT') -if PLUGIN_ROOT: - parent_dir = os.path.dirname(PLUGIN_ROOT) - if parent_dir not in sys.path: - sys.path.insert(0, parent_dir) - if PLUGIN_ROOT not in sys.path: - sys.path.insert(0, PLUGIN_ROOT) +if PLUGIN_ROOT and PLUGIN_ROOT not in sys.path: + sys.path.insert(0, PLUGIN_ROOT) try: - from hookify.core.config_loader import load_rules - from hookify.core.rule_engine import RuleEngine + from core.config_loader import load_rules + from core.rule_engine import RuleEngine except ImportError as e: error_msg = {"systemMessage": f"Hookify import error: {e}"} print(json.dumps(error_msg), file=sys.stdout)