chore: 共有Claude設定を全CLAUDE_CONFIG_DIRへ同期する - #977
Conversation
settings.json は CLAUDE_CONFIG_DIR ごとに独立しており、~/.claude の hooks / permissions / plugins は他の config dir では一切読まれない。 Agent Deck は config.toml の [groups.*.claude] config_dir により common/n8n/private を ~/.claude-private、elu を ~/.claude-elu に 振り分けるため、大半のセッションが ~/.claude の設定を受け取れていない。 2026-07-15 時点の実測: ~/.claude hooks=29 (permissions/plugins/attribution あり) ~/.claude-private hooks=1 (model のみ) ~/.claude-elu hooks=0 (theme/tui のみ) 結果として private/elu セッションでは - Quality Gates と --no-verify ブロックが効かない - permissions の deny が未適用 - attribution 設定(帰属表記の抑止)が未適用 - プラグインが読まれない 状態になっていた。 setup-claude.sh に sync_settings_to_extra_config_dirs を追加し、 ~/.claude/settings.json の共有キー($schema/hooks/permissions/ enabledPlugins/extraKnownMarketplaces/attribution)のみを他の config dir へマージする。model/theme/tui 等の dir 固有キーは保持。 - 対象 dir は ~/.claude-* を自動検出(CLAUDE_EXTRA_CONFIG_DIRS で上書き可) - 冪等。差分がなければ書き込まない - 不正JSONの既存ファイルは上書きせずスキップ - jq 不在時・正本不在時は警告のみで続行(DevContainer は対象dirが無く no-op)
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
📝 WalkthroughWalkthroughThe Claude setup script now discovers additional configuration directories and synchronizes allowlisted settings from the primary configuration, preserving directory-specific values and skipping invalid or unavailable targets. ChangesClaude settings synchronization
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant SetupScript
participant PrimarySettings
participant ExtraConfigDirs
participant jq
SetupScript->>PrimarySettings: read primary settings.json
SetupScript->>ExtraConfigDirs: discover configured or ~/.claude-* directories
SetupScript->>jq: validate and merge allowlisted keys
jq-->>SetupScript: merged target JSON
SetupScript->>ExtraConfigDirs: write changed settings.json files
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0533aeb26f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # 複数の CLAUDE_CONFIG_DIR に共有設定を配るためのキー。 | ||
| # ここに無いキー(model / theme / tui 等)は各 dir 固有として保持される。 | ||
| # shellcheck disable=SC2016 # jq に渡すJSONリテラル。$schema はシェル変数ではない | ||
| CLAUDE_SHARED_SETTINGS_KEYS='["$schema","hooks","permissions","enabledPlugins","extraKnownMarketplaces","attribution"]' |
There was a problem hiding this comment.
Install plugins for each synced config dir
When setup is run from the normal shell, this copies enabledPlugins/extraKnownMarketplaces into ~/.claude-*, but the later claude plugin install flow still runs only for the active Claude config and never installs plugin artifacts under those target dirs. I checked the Claude Code docs: CLAUDE_CONFIG_DIR stores plugins under that path, and enabledPlugins does not by itself install external plugins. As a result, Agent Deck sessions using CLAUDE_CONFIG_DIR=~/.claude-private can get settings that claim plugins are enabled while the plugin commands/hooks/LSPs remain absent until a separate per-dir install is run.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@script/setup-claude.sh`:
- Around line 96-98: Update the directory-processing loop around target_dir so
each non-empty path with a leading "~/” is expanded to use $HOME before
constructing target_file, while preserving absolute and other explicit paths
unchanged.
- Around line 151-154: Move the sync_settings_to_extra_config_dirs invocation
and its preceding log_info from the current position to the end of main(),
immediately before the final log_success message. Keep synchronization after all
canonical settings updates, including plugins::sync_repo_content and
plugins::apply_hookify_patch.
- Around line 123-124: Update the copy flow surrounding cp and log_success so it
checks the cp exit status before reporting success. On failure, handle the copy
error explicitly according to the script’s existing error-handling conventions,
and only call log_success after the copy completes successfully.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| while IFS= read -r target_dir; do | ||
| [[ -n "$target_dir" ]] || continue | ||
| target_file="${target_dir}/settings.json" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Expand tildes in explicit directory paths.
If a user specifies paths starting with ~/ in CLAUDE_EXTRA_CONFIG_DIRS (e.g., passing it in quotes), bash will not automatically perform tilde expansion when reading the variable. This will result in a literal directory named ~ being created in the current working directory. You can use parameter expansion to safely replace a leading tilde with the $HOME path.
💡 Proposed fix
while IFS= read -r target_dir; do
[[ -n "$target_dir" ]] || continue
+
+ # Handle tilde expansion for explicitly provided paths
+ if [[ "$target_dir" == "~" ]] || [[ "$target_dir" == "~/"* ]]; then
+ target_dir="${target_dir/#\~/$HOME}"
+ fi
+
target_file="${target_dir}/settings.json"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| while IFS= read -r target_dir; do | |
| [[ -n "$target_dir" ]] || continue | |
| target_file="${target_dir}/settings.json" | |
| while IFS= read -r target_dir; do | |
| [[ -n "$target_dir" ]] || continue | |
| # Handle tilde expansion for explicitly provided paths | |
| if [[ "$target_dir" == "~" ]] || [[ "$target_dir" == "~/"* ]]; then | |
| target_dir="${target_dir/#\~/$HOME}" | |
| fi | |
| target_file="${target_dir}/settings.json" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@script/setup-claude.sh` around lines 96 - 98, Update the directory-processing
loop around target_dir so each non-empty path with a leading "~/” is expanded to
use $HOME before constructing target_file, while preserving absolute and other
explicit paths unchanged.
| cp "$merged_file" "$target_file" | ||
| log_success " ${target_dir} に共有設定を同期しました" |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Verify the exit status of cp to ensure accurate logging.
If the cp command fails (e.g., due to file permission issues or lack of disk space), the script will incorrectly log a success message. Additionally, if the script is executed in an environment with set -e, an unhandled command failure will unexpectedly terminate the setup process.
🛡️ Proposed fix to handle copy failures
- cp "$merged_file" "$target_file"
- log_success " ${target_dir} に共有設定を同期しました"
+ if cp "$merged_file" "$target_file"; then
+ log_success " ${target_dir} に共有設定を同期しました"
+ else
+ log_warn " ${target_dir} への共有設定の同期に失敗しました"
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| cp "$merged_file" "$target_file" | |
| log_success " ${target_dir} に共有設定を同期しました" | |
| if cp "$merged_file" "$target_file"; then | |
| log_success " ${target_dir} に共有設定を同期しました" | |
| else | |
| log_warn " ${target_dir} への共有設定の同期に失敗しました" | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@script/setup-claude.sh` around lines 123 - 124, Update the copy flow
surrounding cp and log_success so it checks the cp exit status before reporting
success. On failure, handle the copy error explicitly according to the script’s
existing error-handling conventions, and only call log_success after the copy
completes successfully.
| # 追加の CLAUDE_CONFIG_DIR(~/.claude-private 等)へ共有設定を同期 | ||
| log_info "追加の CLAUDE_CONFIG_DIR に共有設定を同期します..." | ||
| sync_settings_to_extra_config_dirs | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Execute synchronization after the canonical settings.json is fully updated.
Running sync_settings_to_extra_config_dirs at this stage causes it to sync the stale version of settings.json. If subsequent setup steps—such as plugins::sync_repo_content (which copies the latest repo configuration to $CLAUDE_DIR) or plugins::apply_hookify_patch—update the canonical settings, those updates will not reach the extra directories until the user runs the setup script a second time.
Remove these lines from their current position and place them at the very end of the main() function, immediately before the final log_success message, to ensure the most up-to-date canonical settings are always distributed.
✂️ Remove from here
- # 追加の CLAUDE_CONFIG_DIR(~/.claude-private 等)へ共有設定を同期
- log_info "追加の CLAUDE_CONFIG_DIR に共有設定を同期します..."
- sync_settings_to_extra_config_dirs
-🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@script/setup-claude.sh` around lines 151 - 154, Move the
sync_settings_to_extra_config_dirs invocation and its preceding log_info from
the current position to the end of main(), immediately before the final
log_success message. Keep synchronization after all canonical settings updates,
including plugins::sync_repo_content and plugins::apply_hookify_patch.
|
🎉 This PR is included in version 1.123.4 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Agent Deck の group ごとに CLAUDE_CONFIG_DIR が切り替わるが、~/.claude 以外 の dir には commands / agents / skills が1件も無く、private セッションでは /session-close を含む全コマンドが使えなかった。 正本はリポジトリではなく ~/.claude とする。keito4/config は public のため 個人の Notion ID を含むコマンドは追跡できない。#977 の settings.json 同期と 同じ思想で、~/.claude を正本に他の dir へ配る。 コピーではなくシンボリックリンクにした。dir 固有の差分を持つ理由が現状なく、 コピーは make claude-setup を忘れた端末で静かにドリフトするため。 hooks は settings.json 側がプロジェクト相対で解決するので対象外。 実体ディレクトリがある場合は中身を失うため触らず警告する。 テストは偽 HOME で実際にスクリプトを起動し、リンクが張られたことを実体で 検証する(実装を外すと 4 件が赤になることを確認済み)。 Closes #981 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes #976
背景
settings.jsonはCLAUDE_CONFIG_DIRごとに独立しており、~/.claudeの hooks / permissions / plugins は他の config dir では一切読まれない。Agent Deck が group ごとに config dir を振り分けている(common/n8n/private →~/.claude-private、elu →~/.claude-elu)ため、大半のセッションで Quality Gates も permissions の deny も attribution も効いていなかった。実測(2026-07-15・メインMac):
変更内容
script/setup-claude.shにsync_settings_to_extra_config_dirs()を追加し、main()の設定セットアップ直後に実行する。~/.claude/settings.jsonの共有キーのみを他の config dir へマージ$schema/hooks/permissions/enabledPlugins/extraKnownMarketplaces/attributionmodel/theme/tui等の dir 固有キーはそのまま~/.claude-*を自動検出(CLAUDE_EXTRA_CONFIG_DIRSで明示指定も可)jq不在・正本不在は警告のみで続行手動コピーではなく配布スクリプトに寄せているのは、2系統に分かれた設定が必ずドリフトするため。
検証
隔離した偽 HOME で実施:
model(opus[1m])・theme(light)・tui(fullscreen)は保持されることを確認not jsonに壊した状態で実行し、上書きされずスキップされることを確認shellcheck -S warningクリーン(exit 0)メインMacへの適用も実施済みで、3 dir すべてが hooks=29 / permissions.deny あり / attribution あり になることを実機で確認。SessionStart の人生システムメモリ注入フックが維持されることも確認済み。
レビュー観点
modelを共有に含めるべきか。現状~/.claude-eluは model 未設定のまま)Summary by CodeRabbit