fix(doctor): detect plugin and hooks in project-level settings (#1091)
* fix(doctor): detect beads plugin in project-level settings isBeadsPluginInstalled() now checks project-level settings files (.claude/settings.json and .claude/settings.local.json) in addition to user-level settings (~/.claude/settings.json). This fixes the contradictory bd doctor output where the plugin check passes but the integration check warns "Not configured" when the plugin is enabled at project scope. Fixes #1090 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(doctor): detect Claude hooks in project-level settings.json hasClaudeHooks() was missing .claude/settings.json - it only checked .claude/settings.local.json for project-level hooks. Now checks all three locations: - ~/.claude/settings.json (user-level) - .claude/settings.json (project-level) - .claude/settings.local.json (project-level, gitignored) Also uses filepath.Join consistently for cross-platform compatibility. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+31
-6
@@ -81,15 +81,39 @@ func CheckClaude() DoctorCheck {
|
||||
}
|
||||
}
|
||||
|
||||
// isBeadsPluginInstalled checks if beads plugin is enabled in Claude Code
|
||||
// isBeadsPluginInstalled checks if beads plugin is enabled in Claude Code.
|
||||
// It checks user-level (~/.claude/settings.json) and project-level settings
|
||||
// (.claude/settings.json and .claude/settings.local.json).
|
||||
func isBeadsPluginInstalled() bool {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
settingsPath := filepath.Join(home, ".claude/settings.json")
|
||||
data, err := os.ReadFile(settingsPath) // #nosec G304 -- settingsPath is constructed from user home dir, not user input
|
||||
// Check user-level settings
|
||||
userSettings := filepath.Join(home, ".claude", "settings.json")
|
||||
if checkPluginInSettings(userSettings) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check project-level settings
|
||||
projectSettings := filepath.Join(".claude", "settings.json")
|
||||
if checkPluginInSettings(projectSettings) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check project-level local settings (gitignored)
|
||||
projectLocalSettings := filepath.Join(".claude", "settings.local.json")
|
||||
if checkPluginInSettings(projectLocalSettings) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// checkPluginInSettings checks if beads plugin is enabled in a settings file
|
||||
func checkPluginInSettings(settingsPath string) bool {
|
||||
data, err := os.ReadFile(settingsPath) // #nosec G304 -- settingsPath is constructed from known safe locations, not user input
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -159,10 +183,11 @@ func hasClaudeHooks() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
globalSettings := filepath.Join(home, ".claude/settings.json")
|
||||
projectSettings := ".claude/settings.local.json"
|
||||
globalSettings := filepath.Join(home, ".claude", "settings.json")
|
||||
projectSettings := filepath.Join(".claude", "settings.json")
|
||||
projectLocalSettings := filepath.Join(".claude", "settings.local.json")
|
||||
|
||||
return hasBeadsHooks(globalSettings) || hasBeadsHooks(projectSettings)
|
||||
return hasBeadsHooks(globalSettings) || hasBeadsHooks(projectSettings) || hasBeadsHooks(projectLocalSettings)
|
||||
}
|
||||
|
||||
// hasBeadsHooks checks if a settings file has bd prime hooks
|
||||
|
||||
Reference in New Issue
Block a user