fix: hookifyプラグインのインポートエラーを自動修正する機能を追加 - #187
Conversation
DevContainer環境でのプラグインインストール問題を修正し、 存在しないプラグインを削除して最適化 変更内容: 1. クロスデバイスリンクエラー対策 - devcontainer.jsonにTMPDIR環境変数を追加 - setup-claude.shで専用の一時ディレクトリ作成 2. マーケットプレイス自動検出機能 - plugins.txtから必要なマーケットプレイスを抽出 - known_marketplaces.jsonから情報を読み取り 3. プラグインリストの最適化 - 存在しないプラグインを削除(vercel, supabase, nextjs-vercel-pro, supabase-toolkit) - claude-code-templatesマーケットプレイスを削除(プラグインディレクトリなし) - 実在するプラグインのみを保持 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
## 変更内容
### テンプレート化
- `known_marketplaces.json.template` を追加
- `{{HOME}}` プレースホルダーを使用して環境非依存に
- `.gitignore` に `known_marketplaces.json` を追加(環境固有ファイル)
### セットアップスクリプト改善
- `script/setup-claude.sh` を環境検出対応に修正
- テンプレートから `known_marketplaces.json` を自動生成
- `$HOME` ベースのパス設定で macOS/Linux/DevContainer すべてで動作
- bash 4.0+ 要件を追加(連想配列使用)
### ドキュメント更新
- `.claude/plugins/README.md` を更新
- 環境非依存の仕組みを説明
- セットアップ手順を明確化
## 動作確認
- macOS (Apple Silicon) でテスト完了
- 9つのプラグインすべてインストール成功
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
プラグインリストを統合: - code-review@claude-plugins-official を追加 - playwright-skill@playwright-skill を追加 コンフリクト解決: - plugins.txt: 両方の変更をマージ - setup-claude.sh: 環境非依存の新しい実装を維持
## 問題の原因 hookifyプラグインがPythonモジュールとして正しく構成されておらず、 以下のエラーが発生していました: ``` Hookify import error: No module named 'hookify' ``` ### 根本原因 1. **Pythonモジュール構造の問題** - `hookify/0.1.0/` ディレクトリが Python パッケージとして認識されない - `__init__.py` ファイルが不足 2. **絶対インポートの問題** - `from hookify.core.config_loader` のような絶対インポートが使用されている - `CLAUDE_PLUGIN_ROOT` から `hookify` モジュールが見つからない 3. **テンプレートの問題** - `known_marketplaces.json.template` に `lastUpdated` フィールドが不足 - Claude CLI のバリデーションエラーが発生 ## 実施した修正 ### 1. setup-claude.sh に自動パッチ機能を追加 プラグインインストール後、hookify プラグインが存在する場合に自動的に: - 絶対インポート(`from hookify.core`)を相対インポート(`from core`)に変更 - `__init__.py` ファイルを作成 ### 2. README にトラブルシューティングを追加 hookify プラグインのインポートエラーについて: - 症状の説明 - 原因の解説 - 手動修正方法 - 再発時の対処法 ### 3. テンプレートに lastUpdated を追加 `known_marketplaces.json.template` に `lastUpdated` フィールドを追加し、 Claude CLI のバリデーションエラーを回避 ## 動作確認 ```bash $ bash script/setup-claude.sh ... プラグイン: 11 インストール完了、0 スキップ、0 失敗 hookifyプラグインのインポートパッチを適用中... ✓ hookifyパッチを適用しました ✓ Claude Code プラグインセットアップが完了しました! ``` ## 影響範囲 - ✅ 既存のセットアップに影響なし - ✅ hookify プラグインの自動修正 - ✅ 今後のマーケットプレイス更新後も自動適用 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe changes transition from hard-coded, environment-specific marketplace configurations to an environment-agnostic template-based approach. A new template file with placeholder variables is introduced, and the setup script is refactored to generate environment-specific configurations, initialize marketplaces, and install plugins with enhanced status reporting and patch application. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- mainブランチとの差分を解決 - lastUpdatedフィールドを保持(Claude CLIバリデーションに必要) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
.claude/plugins/README.md (2)
177-181: Add language specifier to the fenced code block.The error message code block should specify a language for consistent formatting and to satisfy markdown linting.
🔎 Proposed fix
**症状:** -``` +```text Hookify import error: No module named 'hookify'</details> --- `191-198`: **Consider noting the macOS-specific sed syntax.** The `-i ''` syntax is macOS-specific. On Linux/GNU sed, use `-i` without the empty string. Consider adding a note for Linux users or providing both variants. <details> <summary>🔎 Proposed enhancement</summary> ````diff ```bash # マーケットプレイスのhookifyプラグインにパッチを適用 cd ~/.claude/plugins/marketplaces/claude-code-plugins/plugins/hookify + +# macOS: find . -name "*.py" -type f -exec sed -i '' \ -e 's/from hookify\.core/from core/g' \ -e 's/from hookify\.utils/from utils/g' \ -e 's/from hookify\.matchers/from matchers/g' \ {} \; + +# Linux: +find . -name "*.py" -type f -exec sed -i \ + -e 's/from hookify\.core/from core/g' \ + -e 's/from hookify\.utils/from utils/g' \ + -e 's/from hookify\.matchers/from matchers/g' \ + {} \;</details> </blockquote></details> <details> <summary>script/setup-claude.sh (3)</summary><blockquote> `43-45`: **Consider adding cleanup for the temporary directory.** The script creates a custom TMPDIR but doesn't clean it up after execution. This could accumulate temporary files over multiple runs. <details> <summary>🔎 Proposed enhancement</summary> Add a cleanup trap at the script start: ```diff +# クリーンアップ関数 +cleanup() { + if [[ -d "${CLAUDE_DIR}/tmp" ]]; then + rm -rf "${CLAUDE_DIR}/tmp"/* 2>/dev/null || true + fi +} +trap cleanup EXIT + # 一時ディレクトリを作成(クロスデバイスリンクエラー対策) mkdir -p "${CLAUDE_DIR}/tmp" export TMPDIR="${CLAUDE_DIR}/tmp" ``` </details> --- `64-67`: **Consider adding a warning when the template is missing.** Unlike `plugins.txt` (lines 60-62), a missing template file logs no warning. Since the template is essential for generating environment-specific marketplace configuration, a warning would help diagnose setup issues. <details> <summary>🔎 Proposed fix</summary> ```diff if [[ -f "${REPO_PLUGINS_DIR}/known_marketplaces.json.template" ]]; then cp "${REPO_PLUGINS_DIR}/known_marketplaces.json.template" "${MARKETPLACES_TEMPLATE}" log_success "known_marketplaces.json.template をコピーしました" +else + log_warn "リポジトリにknown_marketplaces.json.templateが見つかりません" fi ``` </details> --- `195-208`: **Log message logic doesn't reflect actual behavior.** The sed replacements (lines 189-193) run unconditionally every time, but the success message only fires when `__init__.py` is created. On subsequent runs, it logs "既に適用済み" even though sed just ran again. Consider moving the success message outside the conditional or restructuring to accurately reflect what was done. <details> <summary>🔎 Proposed restructure</summary> ```diff + # 絶対インポートを相対インポートに変更 (always runs, idempotent) + # ... sed commands ... + log_success "hookifyインポートパッチを適用しました" + # __init__.pyが存在しない場合は作成 if [[ ! -f "$HOOKIFY_MARKETPLACE/__init__.py" ]]; then cat > "$HOOKIFY_MARKETPLACE/__init__.py" <<'INIT_EOF' """Hookify plugin package. This package provides hook-based automation for Claude Code. """ __version__ = "0.1.0" INIT_EOF - log_success "hookifyパッチを適用しました" - else - log_info "hookifyパッチは既に適用済みです" + log_success "__init__.py を作成しました" fi ``` </details> </blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between e625cace0c555477bf3cae337cd51bbfc15a180a and d8dc7be913985519de14d594bbedd069fec660fa. </details> <details> <summary>📒 Files selected for processing (7)</summary> * `.claude/plugins/README.md` * `.claude/plugins/known_marketplaces.json` * `.claude/plugins/known_marketplaces.json.template` * `.claude/plugins/plugins.txt` * `.gitignore` * `script/install-claude-plugins.sh` * `script/setup-claude.sh` </details> <details> <summary>💤 Files with no reviewable changes (2)</summary> * .claude/plugins/known_marketplaces.json * .claude/plugins/plugins.txt </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🧠 Learnings (1)</summary> <details> <summary>📚 Learning: 2025-12-01T03:45:17.253Z</summary> ``` Learnt from: CR Repo: keito4/config PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-01T03:45:17.253Z Learning: Applies to .github/workflows/claude.yml : Trigger automatic AI assistance on claude mentions in issues, PRs, and comments using .github/workflows/claude.yml ``` **Applied to files:** - `.gitignore` </details> </details><details> <summary>🪛 markdownlint-cli2 (0.18.1)</summary> <details> <summary>.claude/plugins/README.md</summary> 179-179: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> </details> <details> <summary>🔇 Additional comments (4)</summary><blockquote> <details> <summary>.gitignore (1)</summary><blockquote> `58-58`: **LGTM!** Appropriately ignores the generated `known_marketplaces.json` file, which is environment-specific and should be regenerated from the template during setup. </blockquote></details> <details> <summary>script/install-claude-plugins.sh (1)</summary><blockquote> `47-51`: **LGTM!** The addition of `claude-plugins-official` marketplace initialization is consistent with the existing patterns and provides appropriate non-fatal error handling for cases where the marketplace already exists. </blockquote></details> <details> <summary>.claude/plugins/known_marketplaces.json.template (1)</summary><blockquote> `1-50`: **LGTM!** The template structure is well-designed with consistent use of the `{{HOME}}` placeholder. The `lastUpdated` field addresses the validation error mentioned in the PR objectives. The variation between `"source": "git"` (with full URL) and `"source": "github"` (with repo shorthand) appears intentional to accommodate different source formats. </blockquote></details> <details> <summary>script/setup-claude.sh (1)</summary><blockquote> `11-17`: **LGTM!** Good defensive check for Bash 4.0+ requirement with clear guidance for macOS users on how to upgrade. </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec sed -i '' \ | ||
| -e 's/from hookify\.core/from core/g' \ | ||
| -e 's/from hookify\.utils/from utils/g' \ | ||
| -e 's/from hookify\.matchers/from matchers/g' \ | ||
| {} \; 2>/dev/null |
There was a problem hiding this comment.
Cross-platform incompatibility: sed -i '' fails on Linux.
The sed -i '' syntax is macOS-specific. In DevContainer (Linux), GNU sed requires sed -i without the empty string argument. This will cause the patch to fail silently in Linux environments.
🔎 Proposed fix using a portable approach
- # 絶対インポートを相対インポートに変更
- find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec sed -i '' \
- -e 's/from hookify\.core/from core/g' \
- -e 's/from hookify\.utils/from utils/g' \
- -e 's/from hookify\.matchers/from matchers/g' \
- {} \; 2>/dev/null
+ # 絶対インポートを相対インポートに変更 (macOS/Linux両対応)
+ if [[ "$(uname)" == "Darwin" ]]; then
+ find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec sed -i '' \
+ -e 's/from hookify\.core/from core/g' \
+ -e 's/from hookify\.utils/from utils/g' \
+ -e 's/from hookify\.matchers/from matchers/g' \
+ {} \;
+ else
+ find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec sed -i \
+ -e 's/from hookify\.core/from core/g' \
+ -e 's/from hookify\.utils/from utils/g' \
+ -e 's/from hookify\.matchers/from matchers/g' \
+ {} \;
+ fiCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In script/setup-claude.sh around lines 189 to 193, the inplace sed call uses the
macOS-specific form `sed -i ''`, which fails on Linux; make the replacement
portable by detecting platform or using a POSIX-friendly approach: either check
uname -s and set SED_INPLACE to `-i ''` on Darwin and `-i` on others, then run
sed "$SED_INPLACE" -e 's/from hookify\.core/from core/g' ... , or use a portable
two-step (sed -i.bak ... and then rm -f *.bak) or use perl -pi -e for in-place
edits, ensuring the same regex replacements and suppressing errors to /dev/null
as before.
コードレビュー結果このPRは hookify プラグインのインポートエラーを修正する重要な改善ですが、いくつかの問題点と改善提案があります。 🔴 Critical Issues(重大な問題)1. Linux/DevContainer環境でパッチが失敗する場所: find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec sed -i '' \
-e 's/from hookify\.core/from core/g' \
...問題:
修正案: # クロスプラットフォーム対応
if [[ "$OSTYPE" == "darwin"* ]]; then
SED_INPLACE="sed -i ''"
else
SED_INPLACE="sed -i"
fi
find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec $SED_INPLACE \
-e 's/from hookify\.core/from core/g' \
-e 's/from hookify\.utils/from utils/g' \
-e 's/from hookify\.matchers/from matchers/g' \
{} \; 2>/dev/null🟡 High Priority(優先度高)2. エラーハンドリングの不足場所: 問題:
修正案: if find "$HOOKIFY_MARKETPLACE" -name "*.py" -type f -exec sed -i \
-e 's/from hookify\.core/from core/g' \
-e 's/from hookify\.utils/from utils/g' \
-e 's/from hookify\.matchers/from matchers/g' \
{} \; 2>&1 | grep -v 'No such file'; then
log_success "hookifyパッチを適用しました"
else
log_warn "hookifyパッチの適用中にエラーが発生しました"
fi3. パッチの冪等性が不完全場所: 問題:
修正案: # パッチ適用済みマーカーファイルを使用
PATCH_MARKER="$HOOKIFY_MARKETPLACE/.patched"
if [[ -f "$PATCH_MARKER" ]]; then
log_info "hookifyパッチは既に適用済みです"
else
# パッチ適用ロジック
...
touch "$PATCH_MARKER"
log_success "hookifyパッチを適用しました"
fi🟢 Suggestions(改善提案)4. ドキュメントの手動修正手順が不完全場所: 問題:
修正案: # macOS の場合
find . -name "*.py" -type f -exec sed -i '' \
-e 's/from hookify\.core/from core/g' ...
# Linux の場合
find . -name "*.py" -type f -exec sed -i \
-e 's/from hookify\.core/from core/g' ...5. テストカバレッジの欠如問題:
提案: # テストスクリプトの追加を推奨
script/test-claude-setup.sh6.
|
|
🎉 This PR is included in version 1.11.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
概要
hookifyプラグインで発生していた
No module named 'hookify'インポートエラーを自動的に修正する機能を追加しました。問題の原因
1. Pythonモジュール構造の問題
hookifyプラグインが以下のような構造になっており、Pythonパッケージとして正しく認識されませんでした:
0.1.0ディレクトリに__init__.pyが不足2. 絶対インポートの問題
hookifyプラグインのコードが絶対インポートを使用:
しかし、
CLAUDE_PLUGIN_ROOT環境変数から見てhookifyモジュールが見つからない状態でした。3. テンプレートの問題
known_marketplaces.json.templateにlastUpdatedフィールドが欠落しており、Claude CLIのバリデーションエラーが発生していました。実施した修正
1. setup-claude.sh に自動パッチ機能を追加
追加機能:
from hookify.core)を相対インポート(from core)に変更__init__.pyファイルを自動作成パッチの内容:
2. README にトラブルシューティングセクションを追加
追加内容:
3. テンプレートに lastUpdated フィールドを追加
known_marketplaces.json.templateの全マーケットプレイスにlastUpdatedフィールドを追加し、Claude CLIのバリデーションエラーを回避動作確認
テスト結果
インポートテスト
影響範囲
make claude-pluginsで再適用可能今後の対応
このパッチは暫定的な対応です。理想的には:
from core.config_loaderのような相対インポートに変更__init__.pyの配置ただし、上流での修正まで時間がかかる可能性があるため、このパッチで当面の問題を解決します。
チェックリスト
🤖 Generated with Claude Code
Summary by CodeRabbit
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.