Setup Check
Audit Claude Code configuration and report issues, overlaps, update status, and cleanup recommendations.
Arguments
Parse from $ARGUMENTS. Default: all.
| Arg |
Scope |
all |
Full audit (all categories below, including updates) |
updates |
Claude Code CLI + plugin version/update checks |
skills |
Skills: duplicates, broken symlinks, unused, placeholders |
hooks |
Hooks: conflicts, broken paths, event collisions |
plugins |
Plugins: disabled, stale cache, version tracking |
rules |
Rules: contradictions, overlap with plugin behavior |
settings |
Settings files: duplicates, conflicting keys (health only) |
security |
Security: broad permissions, skipped prompts, orphaned MCP perms |
mcp |
MCP servers: empty configs, duplicate servers |
memory |
Memory: empty dirs, stale entries, index mismatches |
overlaps |
Cross-category overlap detection only |
bedrock |
Bedrock config: recommended Bedrock-compatible options not currently set |
Multiple args supported: /setup-check skills plugins runs both.
Goal Message
In addition to category args, the user can pass a quoted free-text string as a goal message:
/setup-check "ready for production?"
/setup-check settings "security hardening"
If an argument is not a recognized category keyword, treat it as a goal message. The goal triggers an additional Goal Assessment section in the output (see below).
Scan Paths (MANDATORY)
You MUST read ALL of these paths for the relevant category. Do not skip any. Missing a path means missing findings.
Updates:
- Claude Code CLI binary (run
claude --version to get current version)
- npm registry (run
npm view @anthropic-ai/claude-code version 2>/dev/null for latest published version; requires network)
~/.claude/plugins/installed_plugins.json (plugin versions, gitCommitSha, lastUpdated)
~/.claude/plugins/cache/ (all cached versions; detect stale ones not matching active installPath)
claude plugins update <name>@<marketplace> -s <scope> output (authoritative source for update availability; the scope flag is required and must come from each plugin's scope field in installed_plugins.json)
~/.claude/plugins/known_marketplaces.json (installed marketplaces with per-marketplace lastUpdated timestamps; used to detect which marketplaces changed after a refresh)
claude plugin marketplace list --json output (authoritative current marketplace set; read-only)
Skills:
~/.claude/skills/ (symlinks; check for broken links with ls -la)
~/.agents/skills/ (source directories; compare against symlinks for orphans)
~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/skills/ and .../agents/ (plugin-provided; the nesting is marketplace/plugin/version, so glob accordingly)
Hooks:
~/.claude/plugins/cache/*/hooks/hooks.json (glob ALL versions, not just active)
- Cross-reference against
~/.claude/plugins/installed_plugins.json to identify stale vs active
Plugins:
~/.claude/plugins/installed_plugins.json (installed list with versions)
~/.claude/settings.json > enabledPlugins (enabled/disabled state)
~/.claude/plugins/cache/ (all cached versions; detect stale ones)
Rules:
~/.claude/rules/*.md (read every rule file)
Settings:
~/.claude/settings.json (main; lower precedence)
~/.claude/settings.local.json (local overrides; higher precedence, wins on conflicts)
Security:
~/.claude/settings.json (check skipDangerousModePermissionPrompt, permissions)
~/.claude/settings.local.json (check permissions for broad Bash(<command>:*) patterns)
- MCP server sources (for orphaned-permission detection):
~/.claude.json → mcpServers (user-scope, authoritative), project-level .mcp.json, ~/.claude/.mcp.json (if present), claude mcp list stdout (fallback)
MCP:
~/.claude.json → mcpServers key (user-scope servers; authoritative location)
~/.claude/.mcp.json (legacy/optional; often absent)
- Project-level
.mcp.json files in workspace directories
Memory:
~/.claude/projects/<current-project-path>/memory/ (project memory)
MEMORY.md in that directory (index file)
Bedrock:
~/.claude/settings.json (current config: top-level keys AND the env block)
~/.claude/settings.local.json (overrides; merge for the full "currently set" key set)
gemini_search_grounded MCP call (the recommended Bedrock-compatible options reference set; live each run)
Checks Per Category
Updates
Execution order within this category: (0) marketplace refresh, (1) CLI version check, (2) plugin version freshness, (3) stale plugin cache. Never abort the audit on a failure in any step; degrade to an i or ⚠ finding and continue.
- Marketplace refresh (mutating, runs first):
- Read
~/.claude/plugins/known_marketplaces.json and record each marketplace's lastUpdated timestamp BEFORE updating (this is the baseline for change detection).
- Run
claude plugin marketplace update (no name argument updates all marketplaces). Capture stdout, stderr, and exit code.
- Re-read
known_marketplaces.json AFTER and compare each marketplace's lastUpdated:
- Timestamp advanced:
⬆ <marketplace> refreshed (pulled latest from <repo>)
- Timestamp unchanged:
✓ <marketplace> already current
- Parse output for per-marketplace failures. Each failure:
⚠ <marketplace> refresh failed (<reason>) -> Run 'claude plugin marketplace update <name>' manually
- If the whole command fails (network down, CLI error): emit a single
i Marketplace refresh skipped (<reason>) and continue to the CLI version check. Do NOT abort.
- Compare timestamps rather than trusting stdout for success: the bulk update stdout format is not guaranteed stable across CLI versions;
known_marketplaces.json lastUpdated is the durable record of what was actually pulled. Stdout is used only to surface failures.
- Claude Code CLI version: Run
claude --version to get current version. Then run npm view @anthropic-ai/claude-code version 2>/dev/null to get the latest published version. Compare the two. If npm is unavailable or network fails, report current version as i (INFO) only with message "Could not check for updates".
- Plugin version freshness: For each plugin in
installed_plugins.json:
- If
version is "unknown", flag as ⚠ (WARN) with recommendation to reinstall for version tracking
- Read the plugin's
scope field (values: user, project, local, managed) from its entry in installed_plugins.json. claude plugins update defaults to -s user, so the scope flag MUST be passed explicitly for non-user scopes or the command will fail with "Plugin X is not installed at scope user".
- Run
claude plugins update <name>@<marketplace> -s <scope> for each plugin (the plugin key in installed_plugins.json is already in name@marketplace format). Parse the output:
- If output contains "already at the latest version", mark as
✓ with current version
- If output indicates an update was applied (version changed), mark as
⬆ with old and new versions
- If the command fails with "not installed at scope ", retry once with
-s project, then -s user as fallbacks before giving up
- If the command fails for any other reason, fall back to checking
lastUpdated: flag plugins not updated in 30+ days as i (INFO, "not updated in N days, possibly stale")
- Important: Do NOT compare
gitCommitSha against the marketplace repo HEAD. Marketplace repos contain multiple plugins, so repo HEAD advances when any plugin changes, causing false positives for unrelated plugins.
- Show one finding per plugin, using the full
name@marketplace identifier so users can copy-paste directly into commands
- Stale plugin cache: Detect version directories in
~/.claude/plugins/cache/<marketplace>/<plugin>/ where more than one version directory exists. The active version is the one matching installPath in installed_plugins.json. Other directories are stale cache. Flag as ⚠ (WARN) with recommendation to clean up.
Skills
- Broken symlinks:
ls -la ~/.claude/skills/ and verify each target exists
- Orphaned sources: Directories in
~/.agents/skills/ with no symlink in ~/.claude/skills/
- Semantic duplicates: Skills with overlapping names OR overlapping descriptions (read frontmatter). Common pairs:
api-docs-generator/api-documentation-generator, android-design-guidelines/mobile-android-design, kubernetes-specialist/kubernetes-best-practices
- Plugin collisions: Standalone skill with same name as a plugin-provided skill (double-loaded). Also check partial overlaps: a standalone skill whose functionality is a subset of a plugin's sub-skills (e.g., standalone
slack-messaging vs plugin providing slack:slack-messaging)
- Placeholder skills: Skills with unfilled template content in either the description ("Replace with description") OR the body ("Insert instructions below", empty body)
- Tech stack mismatch: Skills for technologies not found in any workspace project. Check
~/workspace/ for project indicators (go.mod, build.gradle, package.json, Cargo.toml, etc.). If ~/workspace/ does not exist, skip this check and note it as i
Hooks
- Event collisions: Multiple hooks on the same event (e.g., two
UserPromptSubmit handlers)
- Broken commands: Hook commands referencing non-existent scripts
- Stale hooks: Hooks from old plugin versions still in cache (compare
installPath in installed_plugins.json)
Plugins
- Disabled plugins:
enabledPlugins: false entries (candidates for removal)
- Version unknown: Plugins with
"version": "unknown" (cannot track updates)
- Stale cache: Old version directories in cache that are not the active
installPath
- Enablement mismatch: Plugin in
installed_plugins.json but missing from enabledPlugins or vice versa
Rules
- Contradictions: Rules that give opposing instructions (read all rule files, compare)
- Plugin overlap: Rules that duplicate behavior a plugin already provides (e.g., formatting rules when a formatting plugin is installed)
- Outdated references: Rules mentioning tools, commands, or patterns that no longer exist
Settings
- Duplicate keys: Same key in both
settings.json and settings.local.json with identical values (redundant)
- Conflicting keys: Same key with different values (settings.local.json takes precedence over settings.json)
Security
- Skipped prompts:
skipDangerousModePermissionPrompt set to true in settings
- Broad permissions:
Bash(<command>:*) patterns that allow arbitrary arguments (especially python3:*, osascript:*, chmod:*, xargs:*)
- Orphaned MCP permissions: MCP tool permissions (
mcp__<server>__*) for servers not found in any configured source. Important: Claude Code stores user-scope MCP servers in ~/.claude.json under the mcpServers key, NOT in ~/.claude/.mcp.json (which often does not exist). Build the known-server set from multiple sources in this order: (a) mcpServers keys in ~/.claude.json, (b) mcpServers keys in any project-level .mcp.json in the current workspace, (c) mcpServers keys in ~/.claude/.mcp.json if it exists, (d) fallback: parse claude mcp list stdout (lines like ^ <name>: ... - [✓✗] ...). Flag a permission as orphaned only when <server> is absent from ALL sources.
- Credential exposure: Credential files with loose filesystem permissions
MCP
- Empty configs: All MCP sources empty (no
mcpServers in ~/.claude.json, no project .mcp.json, no ~/.claude/.mcp.json)
- Duplicate servers: Same server name configured at multiple scopes (e.g., in both
~/.claude.json and a project .mcp.json)
Memory
- Empty directory: Memory dir exists but has no files
- Missing index: Memory files exist but no
MEMORY.md
- Index mismatch:
MEMORY.md references files that do not exist, or files exist but are not in the index
- Stale entries: Memories referencing deleted files or very old dates
Overlaps (Cross-Category)
When running overlaps, you need data from ALL categories. Read all scan paths from every category, then run ONLY the cross-category checks below (not per-category checks like broken symlinks).
- Skill vs plugin: Standalone skill duplicates plugin-provided skill or behavior (exact name match or functional subset)
- Rule vs plugin/hook: Rule enforces what a plugin or hook already does
- Permission vs actual tools: Permissions granted for tools/servers not actually configured
- Multi-concern overlap: Multiple components (skill + plugin + rule) all addressing the same concern (e.g., Slack formatting)
Scoring note: Overlap findings are cross-category views of issues already counted in their source categories. Do NOT count overlap findings toward either score. They appear in the report for visibility but have zero weight.
Bedrock Config
Stateless audit that runs on every invocation when scope is all or bedrock. It surfaces recommended, Bedrock-compatible config options not currently set. There is NO state file and NO dismissal: an option the user skips reappears on the next run, by design.
- Collect current config: Build the set of all keys present in
~/.claude/settings.json and ~/.claude/settings.local.json, including every variable name inside their env blocks. Track each name with its namespace (top-level setting vs env variable) so matching stays namespace-aware. This is the "already set" set.
- Fetch the reference set: Call the
gemini_search_grounded MCP tool asking which settings.json keys and environment variables are recommended for Claude Code AND work when Claude Code runs on Amazon Bedrock. Request citations. For each returned option, record: name, type (setting or env), one-line purpose, recommended value (if known), a short Bedrock note, and source citation URL. Keep ONLY options whose Bedrock compatibility the sources confirm; drop any option that cannot be confirmed Bedrock-compatible.
- Diff: Drop any option already in the "already set" set, matching within the same namespace (a
setting against settings keys, an env against env variable names). The remainder is "missing recommended Bedrock config."
- Outcomes:
- None missing: emit
✓ All recommended Bedrock config present. Render no block.
- Gemini/network failure: emit
i Bedrock config check unavailable (Gemini/network) -> Re-run /setup-check bedrock when online. Never abort the audit; continue to remaining categories.
- Some missing: render the BEDROCK CONFIG block (see Output Format) and present a single
AskUserQuestion multi-select listing the missing options. Selecting none is valid.
- Apply approved options: For each selected option, invoke the
update-config skill to add the key to ~/.claude/settings.json with its recommended value (for an env-type option, add it under the env block). update-config is responsible for preserving the rest of the file and writing valid JSON. On success emit ✓ Added "<key>" to settings.json (<value>). If it reports a failure or the result would be invalid JSON, skip the write and emit ⚠ Could not add "<key>" to settings.json (<reason>) -> Add it manually.
- No persistence: Do not write any record of skipped options. Unselected options are simply re-diffed and re-shown next run. This is intended.
Goal Assessment
This section only appears when the user provides a quoted goal message in the arguments. It is NOT a standard check category; it is generated after all other checks complete.
How it works:
- All standard checks run first (whichever categories are selected)
- Review all findings through the lens of the user's stated goal
- Produce a filtered view: only findings relevant to the goal, plus any concerns that were not flagged by standard checks but matter for the stated goal
- End with a one-line "Verdict" summarizing readiness
Output structure:
┌─ GOAL ASSESSMENT ───────────────────────────────────
│
│ Goal: "<user's quoted message>"
│
│ ✓ <relevant positive finding>
│ ⚠ <relevant warning> -> <recommendation>
│ ✗ <relevant error> -> <how to fix>
│
│ Verdict: <one-line readiness assessment>
│
└─────────────────────────────────────────────────────
Examples of how to interpret goal messages:
"ready for production?" - focus on errors, security settings, broken configs, stale versions
"security hardening" - focus on broad permissions, MCP orphaned permissions, security flags, unknown versions
"clean up unused stuff" - focus on disabled plugins, stale cache, placeholder skills, duplicates, orphans
"starting a new React project" - focus on relevant skills available, missing skills for React ecosystem, MCP servers for dev tooling
Verdict tone: Be direct and honest. Examples:
- "Ready. No blockers found for your goal."
- "Almost ready. Address the 2 warnings above first."
- "Not ready. 3 errors must be fixed before proceeding."
Output Format
Use this exact structure. Do not wrap the report in markdown code blocks. Render all box-drawing characters directly as plain text output.
Header
╭─────────────────────────────────────────────────────
│ Claude Code Setup Check
│ YYYY-MM-DD | Scope: <scope>
│ Claude Code v<version>
╰─────────────────────────────────────────────────────
Replace YYYY-MM-DD with today's date, <scope> with the selected scope (e.g., "all", "skills, plugins"), and <version> with the output of claude --version.
Scores
Displayed immediately after the header, stacked on two lines:
Health: N.N / 10 ████████░░░░ <Label>
Security: N.N / 10 ████████░░░░ <Label>
Health Score Calculation:
Health measures functional correctness. Only health-classified findings contribute.
| Severity |
Tier |
Weight |
| ERROR (✗) |
Major |
-2.0 |
| ERROR (✗) |
Minor |
-1.0 |
| WARN (⚠) |
Major |
-0.7 |
| WARN (⚠) |
Minor |
-0.3 |
| INFO (i) |
-- |
-0.1 |
| OK (✓) |
-- |
0.0 |
| UPDATE (⬆) |
-- |
0.0 |
Formula: health_score = max(0.0, min(10.0, 10.0 - sum_of_health_penalties))
Health Labels:
- 9.0 to 10.0: "Excellent"
- 7.0 to 8.9: "Healthy"
- 5.0 to 6.9: "Needs Attention"
- 0.0 to 4.9: "Critical"
Security Score Calculation:
Security measures how locked-down the permission model is. These are intentional preferences, not defects, so no ✗ ERROR is used; all findings are ⚠ WARN with recalibrated weights.
| Finding |
Indicator |
Weight |
skipDangerousModePermissionPrompt enabled |
⚠ |
-1.0 |
Broad permission (each Bash(<command>:*) pattern) |
⚠ |
-0.5 |
| Orphaned MCP permissions (server not configured) |
⚠ |
-0.5 |
| Credential files with loose permissions |
⚠ |
-0.5 |
Formula: security_score = max(0.0, min(10.0, 10.0 - sum_of_security_penalties))
Security Labels:
- 9.0 to 10.0: "Locked Down"
- 7.0 to 8.9: "Guarded"
- 5.0 to 6.9: "Relaxed"
- 0.0 to 4.9: "Permissive"
Progress bar (both scores): 12 characters wide. Calculate filled blocks as round(score / 10 * 12). Use █ for filled and ░ for empty.
Category Sections
Each category renders as a left-bordered section with its name and finding count in the header:
┌─ CATEGORY NAME (N findings) ────────────────────────
│
│ ✓ Finding with no issues
│ i Informational note (details inline)
│ ⚠ Problem description (specifics) -> Recommendation
│ ✗ Broken config (specifics) -> How to fix
│
└─────────────────────────────────────────────────────
Indicators (use these exact symbols, not text tags):
✓ = OK (check passed, no issues)
⚠ = WARN (actionable recommendation)
✗ = ERROR (broken configuration, must fix)
i = INFO (informational, no action needed)
⬆ = Update available (used only in the Updates section)
Formatting rules:
- One finding per line. Each finding MUST fit on a single line:
indicator + description + (details) + -> recommendation. Do not wrap findings across multiple lines. Use concise language to keep lines compact.
- Examples of single-line findings:
✓ 88 symlinks intact, no broken links
⚠ 3 plugins "unknown" version (frontend-design, playwright, skill-creator) -> Reinstall for version tracking
✗ Broken symlink: my-skill -> missing target -> Remove or recreate symlink
⬆ prompt-improver@severity1-marketplace updated (0.5.1 -> 0.6.0) -> Was auto-updated by check
- Use parentheses for inline details rather than separate indented lines
- Use
-> to attach the recommendation directly on the same line
- If ALL sub-checks in a category pass, show a single
✓ No issues found
- Missing scan paths: show
i <path> not found, skipping and continue. Do not error out.
- Long findings may extend past the bottom rule width. This is expected behavior; there is no right border to align with. Do not truncate or wrap findings to match the rule length.
Severity rules (applies to health categories):
✗ (ERROR): Broken symlinks, missing scripts, corrupted configs, CLI not found
⚠ (WARN): Duplicates, overlaps, disabled plugins, stale cache, available updates, unknown versions
i (INFO): Version not checked (network unavailable), tech stack mismatch, empty memory, component not updated in 30+ days
✓ (OK): Category or sub-check passed with no issues
Severity rules (Security category):
⚠ (WARN): All security findings (broad permissions, skipped prompts, orphaned MCP perms, credential exposure)
✓ (OK): All security checks passed
- No
✗ ERROR in Security; these are intentional preferences, not broken configuration
Tier classification (determines weight, see Scores section above):
- Major = impacts runtime correctness. Ask: "Does this cause wrong behavior?"
- Minor = housekeeping, cosmetic, or redundant. Ask: "Is this messy but harmless?"
- When unsure, default to minor. Promote to major only if the finding can cause incorrect behavior.
- Security findings have their own fixed weights (see Security Score Calculation) and do not use tier classification.
Health Tier Assignment Table
Use this table to classify each health finding as major or minor for health score calculation. Security findings are NOT in this table; they use the Security Score weights above.
ERROR Tier Assignments
| Check |
Tier |
| Corrupted/unparseable config files |
Major |
CLI not found / claude --version fails |
Major |
| Broken hook commands (script doesn't exist) |
Major |
| Broken skill symlinks |
Minor |
| Missing scan paths for critical configs |
Minor |
WARN Tier Assignments
| Check |
Tier |
| Contradicting rules |
Major |
| Conflicting settings keys (different values) |
Major |
| Stale plugin cache (old versions in cache/) |
Minor |
| Disabled plugins still installed |
Minor |
| Unknown plugin versions |
Minor |
| Semantic duplicate skills |
Minor |
| Plugin collisions (standalone + plugin-provided) |
Minor |
| Duplicate settings keys (identical values) |
Minor |
| Orphaned skill sources (no symlink) |
Minor |
| Placeholder skills |
Minor |
| Stale hooks from old plugin versions |
Minor |
| Event collisions (multiple hooks on same event) |
Minor |
| Rule overlaps with plugin behavior |
Minor |
| Empty MCP configs |
Minor |
| Duplicate MCP servers across scopes |
Minor |
| Memory index mismatches |
Minor |
| Marketplace refresh failed (single marketplace) |
Minor |
INFO (all single-tier, -0.1)
No tier distinction. All INFO findings use the flat -0.1 weight. Updates INFO findings: marketplace refresh skipped (whole command failed).
Zero-weight Updates findings (0.0, no penalty)
These render in the Updates section but contribute nothing to the health score, matching the existing treatment of plugin updates:
| Check |
Indicator |
| Marketplace refreshed |
⬆ |
| Marketplace already current |
✓ |
Bedrock Config findings (zero-weight, exempt)
The entire Bedrock Config category is advisory and contributes to NEITHER the Health score nor the Security score. This is a deliberate exemption from the standard severity weights (which would otherwise penalize an i at -0.1 and a ⚠ as a minor): the user intentionally and repeatedly skips some recommended options, so scoring them would peg the score permanently low. Do NOT count any of these toward either score:
| Check |
Indicator |
| Missing recommended Bedrock option (each) |
i |
| All recommended Bedrock config present |
✓ |
| Bedrock config check unavailable (Gemini/network) |
i |
| Bedrock option added to settings.json |
✓ |
| Could not add Bedrock option (write failed) |
⚠ |
BEDROCK CONFIG Block
When the Bedrock Config category (scope all or bedrock) finds recommended-but-missing options, render this section box. Every listed option is, by construction, both recommended and Bedrock-compatible, so there is no per-item compatibility badge. The box itself is not a scored finding; the entire Bedrock category is zero-weight (see Scores).
┌─ BEDROCK CONFIG (N findings) ───────────────────────
│
│ i <N> recommended Bedrock-compatible options not currently set.
│
│ 1. settings.json: "<key>"
│ <one-line purpose>. Recommended: <value>.
│ Source: <citation url>
│
│ 2. env: <VAR_NAME>
│ <one-line purpose>. Recommended: <value>.
│ Source: <citation url>
│
└─────────────────────────────────────────────────────
After rendering, present the AskUserQuestion multi-select described in the Bedrock Config check, write approved options via the update-config skill, and emit the per-option ✓ Added ... confirmations as normal findings within the Bedrock Config section.
Section Ordering
When all is selected, render sections in this order:
- Updates
- Bedrock Config
- Skills
- Hooks
- Plugins
- Rules
- Settings
- Security
- MCP
- Memory
- Overlaps
- Goal Assessment (only if a goal message was provided)
When a single category is selected, show only that category section plus the summary.
Summary
╭─────────────────────────────────────────────────────
│ Summary
├─────────────────────────────────────────────────────
│
│ Health: ✓ OK: N ✗ ERROR: N major, N minor ⚠ WARN: N major, N minor i INFO: N
│ Security: ✓ OK: N ⚠ WARN: N
│
│ Top Recommendations:
│
│ 1. Most impactful recommendation
│ 2. Second most impactful
│ 3. Third
│ 4. Fourth
│ 5. Fifth
│
╰─────────────────────────────────────────────────────
Summary counts formatting:
- Health line: show tier breakdown for ERROR and WARN:
✗ ERROR: 1 major, 2 minor
- Health line: when a severity has zero findings for a tier, omit that tier:
⚠ WARN: 3 minor
- Health line: when a severity has zero findings entirely, show 0:
✗ ERROR: 0
- Security line: show total WARN count only (no tier breakdown):
⚠ WARN: 3
- Security line: when no warnings, show:
✓ OK: all clear
Rank recommendations across both dimensions by severity (health ERROR first, then health WARN, then security WARN), and within the same severity by impact. Show up to 5 recommendations.
Execution Order
- Parse arguments to determine scope. Separate category keywords from a quoted goal message (if any).
- Read ALL mandatory scan paths for selected categories (use parallel tool calls where possible).
- Run update checks first (if
all or updates is selected) in this sub-order: (0) claude plugin marketplace update to refresh all marketplaces, comparing known_marketplaces.json lastUpdated before/after; (1) claude --version and npm view for the CLI version check; (2) read installed_plugins.json and run claude plugins update <name>@<marketplace> -s <scope> for each plugin (scope read from the plugin's entry); (3) detect stale plugin cache.
- Run the Bedrock Config audit (if
all or bedrock is selected), immediately after Updates so execution order matches render order: collect current config keys from settings.json and settings.local.json, call gemini_search_grounded for recommended Bedrock-compatible options, diff out already-set keys, present the BEDROCK CONFIG block and AskUserQuestion multi-select for any missing options, and write approved options via the update-config skill. On Gemini/network failure, emit the unavailable INFO line and continue. This category is zero-weight.
- Run checks for each remaining selected category (including the Security category).
- Run overlap checks (if
all or overlaps is selected).
- Calculate dual scores:
- Health score: start at 10.0, classify each health finding by tier (see Health Tier Assignment Table), subtract the corresponding weight. Floor at 0.0, cap at 10.0.
- Security score: start at 10.0, subtract each security finding's fixed weight (see Security Score Calculation). Floor at 0.0, cap at 10.0.
- Generate goal assessment (if a goal message was provided): review all findings against the stated goal, filter to relevant findings, write verdict.
- Render the full report: header, dual score lines, category boxes (including Security), goal assessment (if any), summary.
- End with the summary box containing per-dimension counts and top 3-5 recommendations sorted by impact across both dimensions.
1---2name: setup-check3description: Audit Claude Code configuration for issues, overlaps, unused components, update status, and misconfigurations. Use when the user (1) asks to check or audit their setup, (2) wants to find duplicate or conflicting skills, hooks, plugins, or rules, (3) asks what is broken or needs cleanup, (4) wants to check Claude Code or plugin updates, (5) asks to review MCP servers or memory state, (6) asks which recommended Amazon Bedrock config options they are missing, or (7) invokes /setup-check with optional scope (all, updates, skills, hooks, plugins, rules, settings, security, mcp, memory, overlaps, bedrock).4---56# Setup Check78Audit Claude Code configuration and report issues, overlaps, update status, and cleanup recommendations.910## Arguments1112Parse from `$ARGUMENTS`. Default: `all`.1314| Arg | Scope |15|-----|-------|16| `all` | Full audit (all categories below, including updates) |17| `updates` | Claude Code CLI + plugin version/update checks |18| `skills` | Skills: duplicates, broken symlinks, unused, placeholders |19| `hooks` | Hooks: conflicts, broken paths, event collisions |20| `plugins` | Plugins: disabled, stale cache, version tracking |21| `rules` | Rules: contradictions, overlap with plugin behavior |22| `settings` | Settings files: duplicates, conflicting keys (health only) |23| `security` | Security: broad permissions, skipped prompts, orphaned MCP perms |24| `mcp` | MCP servers: empty configs, duplicate servers |25| `memory` | Memory: empty dirs, stale entries, index mismatches |26| `overlaps` | Cross-category overlap detection only |27| `bedrock` | Bedrock config: recommended Bedrock-compatible options not currently set |2829Multiple args supported: `/setup-check skills plugins` runs both.3031### Goal Message3233In addition to category args, the user can pass a quoted free-text string as a goal message:3435`/setup-check "ready for production?"`36`/setup-check settings "security hardening"`3738If an argument is not a recognized category keyword, treat it as a goal message. The goal triggers an additional Goal Assessment section in the output (see below).3940## Scan Paths (MANDATORY)4142You MUST read ALL of these paths for the relevant category. Do not skip any. Missing a path means missing findings.4344**Updates:**45- Claude Code CLI binary (run `claude --version` to get current version)46- npm registry (run `npm view @anthropic-ai/claude-code version 2>/dev/null` for latest published version; requires network)47- `~/.claude/plugins/installed_plugins.json` (plugin versions, `gitCommitSha`, `lastUpdated`)48- `~/.claude/plugins/cache/` (all cached versions; detect stale ones not matching active `installPath`)49- `claude plugins update <name>@<marketplace> -s <scope>` output (authoritative source for update availability; the scope flag is required and must come from each plugin's `scope` field in `installed_plugins.json`)50- `~/.claude/plugins/known_marketplaces.json` (installed marketplaces with per-marketplace `lastUpdated` timestamps; used to detect which marketplaces changed after a refresh)51- `claude plugin marketplace list --json` output (authoritative current marketplace set; read-only)5253**Skills:**54- `~/.claude/skills/` (symlinks; check for broken links with `ls -la`)55- `~/.agents/skills/` (source directories; compare against symlinks for orphans)56- `~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/skills/` and `.../agents/` (plugin-provided; the nesting is marketplace/plugin/version, so glob accordingly)5758**Hooks:**59- `~/.claude/plugins/cache/*/hooks/hooks.json` (glob ALL versions, not just active)60- Cross-reference against `~/.claude/plugins/installed_plugins.json` to identify stale vs active6162**Plugins:**63- `~/.claude/plugins/installed_plugins.json` (installed list with versions)64- `~/.claude/settings.json` > `enabledPlugins` (enabled/disabled state)65- `~/.claude/plugins/cache/` (all cached versions; detect stale ones)6667**Rules:**68- `~/.claude/rules/*.md` (read every rule file)6970**Settings:**71- `~/.claude/settings.json` (main; lower precedence)72- `~/.claude/settings.local.json` (local overrides; higher precedence, wins on conflicts)7374**Security:**75- `~/.claude/settings.json` (check `skipDangerousModePermissionPrompt`, permissions)76- `~/.claude/settings.local.json` (check permissions for broad `Bash(<command>:*)` patterns)77- MCP server sources (for orphaned-permission detection): `~/.claude.json` → `mcpServers` (user-scope, authoritative), project-level `.mcp.json`, `~/.claude/.mcp.json` (if present), `claude mcp list` stdout (fallback)7879**MCP:**80- `~/.claude.json` → `mcpServers` key (user-scope servers; authoritative location)81- `~/.claude/.mcp.json` (legacy/optional; often absent)82- Project-level `.mcp.json` files in workspace directories8384**Memory:**85- `~/.claude/projects/<current-project-path>/memory/` (project memory)86- `MEMORY.md` in that directory (index file)8788**Bedrock:**89- `~/.claude/settings.json` (current config: top-level keys AND the `env` block)90- `~/.claude/settings.local.json` (overrides; merge for the full "currently set" key set)91- `gemini_search_grounded` MCP call (the recommended Bedrock-compatible options reference set; live each run)9293## Checks Per Category9495### Updates9697**Execution order within this category:** (0) marketplace refresh, (1) CLI version check, (2) plugin version freshness, (3) stale plugin cache. Never abort the audit on a failure in any step; degrade to an `i` or `⚠` finding and continue.98990. **Marketplace refresh (mutating, runs first):**100 - Read `~/.claude/plugins/known_marketplaces.json` and record each marketplace's `lastUpdated` timestamp BEFORE updating (this is the baseline for change detection).101 - Run `claude plugin marketplace update` (no name argument updates all marketplaces). Capture stdout, stderr, and exit code.102 - Re-read `known_marketplaces.json` AFTER and compare each marketplace's `lastUpdated`:103 - Timestamp advanced: `⬆ <marketplace> refreshed (pulled latest from <repo>)`104 - Timestamp unchanged: `✓ <marketplace> already current`105 - Parse output for per-marketplace failures. Each failure: `⚠ <marketplace> refresh failed (<reason>) -> Run 'claude plugin marketplace update <name>' manually`106 - If the whole command fails (network down, CLI error): emit a single `i Marketplace refresh skipped (<reason>)` and continue to the CLI version check. Do NOT abort.107 - Compare timestamps rather than trusting stdout for success: the bulk update stdout format is not guaranteed stable across CLI versions; `known_marketplaces.json` `lastUpdated` is the durable record of what was actually pulled. Stdout is used only to surface failures.1081. **Claude Code CLI version:** Run `claude --version` to get current version. Then run `npm view @anthropic-ai/claude-code version 2>/dev/null` to get the latest published version. Compare the two. If npm is unavailable or network fails, report current version as `i` (INFO) only with message "Could not check for updates".1092. **Plugin version freshness:** For each plugin in `installed_plugins.json`:110 - If `version` is `"unknown"`, flag as `⚠` (WARN) with recommendation to reinstall for version tracking111 - Read the plugin's `scope` field (values: `user`, `project`, `local`, `managed`) from its entry in `installed_plugins.json`. `claude plugins update` defaults to `-s user`, so the scope flag MUST be passed explicitly for non-user scopes or the command will fail with "Plugin X is not installed at scope user".112 - Run `claude plugins update <name>@<marketplace> -s <scope>` for each plugin (the plugin key in `installed_plugins.json` is already in `name@marketplace` format). Parse the output:113 - If output contains "already at the latest version", mark as `✓` with current version114 - If output indicates an update was applied (version changed), mark as `⬆` with old and new versions115 - If the command fails with "not installed at scope <X>", retry once with `-s project`, then `-s user` as fallbacks before giving up116 - If the command fails for any other reason, fall back to checking `lastUpdated`: flag plugins not updated in 30+ days as `i` (INFO, "not updated in N days, possibly stale")117 - **Important:** Do NOT compare `gitCommitSha` against the marketplace repo HEAD. Marketplace repos contain multiple plugins, so repo HEAD advances when any plugin changes, causing false positives for unrelated plugins.118 - Show one finding per plugin, using the full `name@marketplace` identifier so users can copy-paste directly into commands1193. **Stale plugin cache:** Detect version directories in `~/.claude/plugins/cache/<marketplace>/<plugin>/` where more than one version directory exists. The active version is the one matching `installPath` in `installed_plugins.json`. Other directories are stale cache. Flag as `⚠` (WARN) with recommendation to clean up.120121### Skills1221. **Broken symlinks:** `ls -la ~/.claude/skills/` and verify each target exists1232. **Orphaned sources:** Directories in `~/.agents/skills/` with no symlink in `~/.claude/skills/`1243. **Semantic duplicates:** Skills with overlapping names OR overlapping descriptions (read frontmatter). Common pairs: `api-docs-generator`/`api-documentation-generator`, `android-design-guidelines`/`mobile-android-design`, `kubernetes-specialist`/`kubernetes-best-practices`1254. **Plugin collisions:** Standalone skill with same name as a plugin-provided skill (double-loaded). Also check partial overlaps: a standalone skill whose functionality is a subset of a plugin's sub-skills (e.g., standalone `slack-messaging` vs plugin providing `slack:slack-messaging`)1265. **Placeholder skills:** Skills with unfilled template content in either the description ("Replace with description") OR the body ("Insert instructions below", empty body)1276. **Tech stack mismatch:** Skills for technologies not found in any workspace project. Check `~/workspace/` for project indicators (go.mod, build.gradle, package.json, Cargo.toml, etc.). If `~/workspace/` does not exist, skip this check and note it as `i`128129### Hooks1301. **Event collisions:** Multiple hooks on the same event (e.g., two `UserPromptSubmit` handlers)1312. **Broken commands:** Hook commands referencing non-existent scripts1323. **Stale hooks:** Hooks from old plugin versions still in cache (compare `installPath` in `installed_plugins.json`)133134### Plugins1351. **Disabled plugins:** `enabledPlugins: false` entries (candidates for removal)1362. **Version unknown:** Plugins with `"version": "unknown"` (cannot track updates)1373. **Stale cache:** Old version directories in cache that are not the active `installPath`1384. **Enablement mismatch:** Plugin in `installed_plugins.json` but missing from `enabledPlugins` or vice versa139140### Rules1411. **Contradictions:** Rules that give opposing instructions (read all rule files, compare)1422. **Plugin overlap:** Rules that duplicate behavior a plugin already provides (e.g., formatting rules when a formatting plugin is installed)1433. **Outdated references:** Rules mentioning tools, commands, or patterns that no longer exist144145### Settings1461. **Duplicate keys:** Same key in both `settings.json` and `settings.local.json` with identical values (redundant)1472. **Conflicting keys:** Same key with different values (settings.local.json takes precedence over settings.json)148149### Security1501. **Skipped prompts:** `skipDangerousModePermissionPrompt` set to `true` in settings1512. **Broad permissions:** `Bash(<command>:*)` patterns that allow arbitrary arguments (especially `python3:*`, `osascript:*`, `chmod:*`, `xargs:*`)1523. **Orphaned MCP permissions:** MCP tool permissions (`mcp__<server>__*`) for servers not found in any configured source. **Important:** Claude Code stores user-scope MCP servers in `~/.claude.json` under the `mcpServers` key, NOT in `~/.claude/.mcp.json` (which often does not exist). Build the known-server set from multiple sources in this order: (a) `mcpServers` keys in `~/.claude.json`, (b) `mcpServers` keys in any project-level `.mcp.json` in the current workspace, (c) `mcpServers` keys in `~/.claude/.mcp.json` if it exists, (d) fallback: parse `claude mcp list` stdout (lines like `^ <name>: ... - [✓✗] ...`). Flag a permission as orphaned only when `<server>` is absent from ALL sources.1534. **Credential exposure:** Credential files with loose filesystem permissions154155### MCP1561. **Empty configs:** All MCP sources empty (no `mcpServers` in `~/.claude.json`, no project `.mcp.json`, no `~/.claude/.mcp.json`)1572. **Duplicate servers:** Same server name configured at multiple scopes (e.g., in both `~/.claude.json` and a project `.mcp.json`)158159### Memory1601. **Empty directory:** Memory dir exists but has no files1612. **Missing index:** Memory files exist but no `MEMORY.md`1623. **Index mismatch:** `MEMORY.md` references files that do not exist, or files exist but are not in the index1634. **Stale entries:** Memories referencing deleted files or very old dates164165### Overlaps (Cross-Category)166167When running `overlaps`, you need data from ALL categories. Read all scan paths from every category, then run ONLY the cross-category checks below (not per-category checks like broken symlinks).1681691. **Skill vs plugin:** Standalone skill duplicates plugin-provided skill or behavior (exact name match or functional subset)1702. **Rule vs plugin/hook:** Rule enforces what a plugin or hook already does1713. **Permission vs actual tools:** Permissions granted for tools/servers not actually configured1724. **Multi-concern overlap:** Multiple components (skill + plugin + rule) all addressing the same concern (e.g., Slack formatting)173174**Scoring note:** Overlap findings are cross-category views of issues already counted in their source categories. Do NOT count overlap findings toward either score. They appear in the report for visibility but have zero weight.175176### Bedrock Config177178Stateless audit that runs on every invocation when scope is `all` or `bedrock`. It surfaces recommended, Bedrock-compatible config options not currently set. There is NO state file and NO dismissal: an option the user skips reappears on the next run, by design.1791801. **Collect current config:** Build the set of all keys present in `~/.claude/settings.json` and `~/.claude/settings.local.json`, including every variable name inside their `env` blocks. Track each name with its namespace (top-level `setting` vs `env` variable) so matching stays namespace-aware. This is the "already set" set.1812. **Fetch the reference set:** Call the `gemini_search_grounded` MCP tool asking which `settings.json` keys and environment variables are recommended for Claude Code AND work when Claude Code runs on Amazon Bedrock. Request citations. For each returned option, record: name, type (`setting` or `env`), one-line purpose, recommended value (if known), a short Bedrock note, and source citation URL. Keep ONLY options whose Bedrock compatibility the sources confirm; drop any option that cannot be confirmed Bedrock-compatible.1823. **Diff:** Drop any option already in the "already set" set, matching within the same namespace (a `setting` against settings keys, an `env` against env variable names). The remainder is "missing recommended Bedrock config."1834. **Outcomes:**184 - **None missing:** emit `✓ All recommended Bedrock config present`. Render no block.185 - **Gemini/network failure:** emit `i Bedrock config check unavailable (Gemini/network) -> Re-run /setup-check bedrock when online`. Never abort the audit; continue to remaining categories.186 - **Some missing:** render the BEDROCK CONFIG block (see Output Format) and present a single `AskUserQuestion` multi-select listing the missing options. Selecting none is valid.1875. **Apply approved options:** For each selected option, invoke the `update-config` skill to add the key to `~/.claude/settings.json` with its recommended value (for an `env`-type option, add it under the `env` block). `update-config` is responsible for preserving the rest of the file and writing valid JSON. On success emit `✓ Added "<key>" to settings.json (<value>)`. If it reports a failure or the result would be invalid JSON, skip the write and emit `⚠ Could not add "<key>" to settings.json (<reason>) -> Add it manually`.1886. **No persistence:** Do not write any record of skipped options. Unselected options are simply re-diffed and re-shown next run. This is intended.189190### Goal Assessment191192This section only appears when the user provides a quoted goal message in the arguments. It is NOT a standard check category; it is generated after all other checks complete.193194**How it works:**1951. All standard checks run first (whichever categories are selected)1962. Review all findings through the lens of the user's stated goal1973. Produce a filtered view: only findings relevant to the goal, plus any concerns that were not flagged by standard checks but matter for the stated goal1984. End with a one-line "Verdict" summarizing readiness199200**Output structure:**201202```203┌─ GOAL ASSESSMENT ───────────────────────────────────204│205│ Goal: "<user's quoted message>"206│207│ ✓ <relevant positive finding>208│ ⚠ <relevant warning> -> <recommendation>209│ ✗ <relevant error> -> <how to fix>210│211│ Verdict: <one-line readiness assessment>212│213└─────────────────────────────────────────────────────214```215216**Examples of how to interpret goal messages:**217- `"ready for production?"` - focus on errors, security settings, broken configs, stale versions218- `"security hardening"` - focus on broad permissions, MCP orphaned permissions, security flags, unknown versions219- `"clean up unused stuff"` - focus on disabled plugins, stale cache, placeholder skills, duplicates, orphans220- `"starting a new React project"` - focus on relevant skills available, missing skills for React ecosystem, MCP servers for dev tooling221222**Verdict tone:** Be direct and honest. Examples:223- "Ready. No blockers found for your goal."224- "Almost ready. Address the 2 warnings above first."225- "Not ready. 3 errors must be fixed before proceeding."226227## Output Format228229Use this exact structure. Do not wrap the report in markdown code blocks. Render all box-drawing characters directly as plain text output.230231### Header232233```234╭─────────────────────────────────────────────────────235│ Claude Code Setup Check236│ YYYY-MM-DD | Scope: <scope>237│ Claude Code v<version>238╰─────────────────────────────────────────────────────239```240241Replace `YYYY-MM-DD` with today's date, `<scope>` with the selected scope (e.g., "all", "skills, plugins"), and `<version>` with the output of `claude --version`.242243### Scores244245Displayed immediately after the header, stacked on two lines:246247```248 Health: N.N / 10 ████████░░░░ <Label>249 Security: N.N / 10 ████████░░░░ <Label>250```251252**Health Score Calculation:**253254Health measures functional correctness. Only health-classified findings contribute.255256| Severity | Tier | Weight |257|----------|------|--------|258| ERROR (✗) | Major | -2.0 |259| ERROR (✗) | Minor | -1.0 |260| WARN (⚠) | Major | -0.7 |261| WARN (⚠) | Minor | -0.3 |262| INFO (i) | -- | -0.1 |263| OK (✓) | -- | 0.0 |264| UPDATE (⬆) | -- | 0.0 |265266Formula: `health_score = max(0.0, min(10.0, 10.0 - sum_of_health_penalties))`267268**Health Labels:**269- 9.0 to 10.0: "Excellent"270- 7.0 to 8.9: "Healthy"271- 5.0 to 6.9: "Needs Attention"272- 0.0 to 4.9: "Critical"273274**Security Score Calculation:**275276Security measures how locked-down the permission model is. These are intentional preferences, not defects, so no `✗` ERROR is used; all findings are `⚠` WARN with recalibrated weights.277278| Finding | Indicator | Weight |279|---------|-----------|--------|280| `skipDangerousModePermissionPrompt` enabled | ⚠ | -1.0 |281| Broad permission (each `Bash(<command>:*)` pattern) | ⚠ | -0.5 |282| Orphaned MCP permissions (server not configured) | ⚠ | -0.5 |283| Credential files with loose permissions | ⚠ | -0.5 |284285Formula: `security_score = max(0.0, min(10.0, 10.0 - sum_of_security_penalties))`286287**Security Labels:**288- 9.0 to 10.0: "Locked Down"289- 7.0 to 8.9: "Guarded"290- 5.0 to 6.9: "Relaxed"291- 0.0 to 4.9: "Permissive"292293**Progress bar (both scores):** 12 characters wide. Calculate filled blocks as `round(score / 10 * 12)`. Use `█` for filled and `░` for empty.294295### Category Sections296297Each category renders as a left-bordered section with its name and finding count in the header:298299```300┌─ CATEGORY NAME (N findings) ────────────────────────301│302│ ✓ Finding with no issues303│ i Informational note (details inline)304│ ⚠ Problem description (specifics) -> Recommendation305│ ✗ Broken config (specifics) -> How to fix306│307└─────────────────────────────────────────────────────308```309310**Indicators (use these exact symbols, not text tags):**311- `✓` = OK (check passed, no issues)312- `⚠` = WARN (actionable recommendation)313- `✗` = ERROR (broken configuration, must fix)314- `i` = INFO (informational, no action needed)315- `⬆` = Update available (used only in the Updates section)316317**Formatting rules:**318- **One finding per line.** Each finding MUST fit on a single line: `indicator + description + (details) + -> recommendation`. Do not wrap findings across multiple lines. Use concise language to keep lines compact.319- Examples of single-line findings:320 - `✓ 88 symlinks intact, no broken links`321 - `⚠ 3 plugins "unknown" version (frontend-design, playwright, skill-creator) -> Reinstall for version tracking`322 - `✗ Broken symlink: my-skill -> missing target -> Remove or recreate symlink`323 - `⬆ prompt-improver@severity1-marketplace updated (0.5.1 -> 0.6.0) -> Was auto-updated by check`324- Use parentheses for inline details rather than separate indented lines325- Use `->` to attach the recommendation directly on the same line326- If ALL sub-checks in a category pass, show a single `✓ No issues found`327- Missing scan paths: show `i <path> not found, skipping` and continue. Do not error out.328- **Long findings may extend past the bottom rule width.** This is expected behavior; there is no right border to align with. Do not truncate or wrap findings to match the rule length.329330**Severity rules (applies to health categories):**331- `✗` (ERROR): Broken symlinks, missing scripts, corrupted configs, CLI not found332- `⚠` (WARN): Duplicates, overlaps, disabled plugins, stale cache, available updates, unknown versions333- `i` (INFO): Version not checked (network unavailable), tech stack mismatch, empty memory, component not updated in 30+ days334- `✓` (OK): Category or sub-check passed with no issues335336**Severity rules (Security category):**337- `⚠` (WARN): All security findings (broad permissions, skipped prompts, orphaned MCP perms, credential exposure)338- `✓` (OK): All security checks passed339- No `✗` ERROR in Security; these are intentional preferences, not broken configuration340341**Tier classification (determines weight, see Scores section above):**342- **Major** = impacts runtime correctness. Ask: "Does this cause wrong behavior?"343- **Minor** = housekeeping, cosmetic, or redundant. Ask: "Is this messy but harmless?"344- When unsure, default to **minor**. Promote to major only if the finding can cause incorrect behavior.345- Security findings have their own fixed weights (see Security Score Calculation) and do not use tier classification.346347### Health Tier Assignment Table348349Use this table to classify each health finding as major or minor for health score calculation. Security findings are NOT in this table; they use the Security Score weights above.350351#### ERROR Tier Assignments352353| Check | Tier |354|-------|------|355| Corrupted/unparseable config files | Major |356| CLI not found / `claude --version` fails | Major |357| Broken hook commands (script doesn't exist) | Major |358| Broken skill symlinks | Minor |359| Missing scan paths for critical configs | Minor |360361#### WARN Tier Assignments362363| Check | Tier |364|-------|------|365| Contradicting rules | Major |366| Conflicting settings keys (different values) | Major |367| Stale plugin cache (old versions in cache/) | Minor |368| Disabled plugins still installed | Minor |369| Unknown plugin versions | Minor |370| Semantic duplicate skills | Minor |371| Plugin collisions (standalone + plugin-provided) | Minor |372| Duplicate settings keys (identical values) | Minor |373| Orphaned skill sources (no symlink) | Minor |374| Placeholder skills | Minor |375| Stale hooks from old plugin versions | Minor |376| Event collisions (multiple hooks on same event) | Minor |377| Rule overlaps with plugin behavior | Minor |378| Empty MCP configs | Minor |379| Duplicate MCP servers across scopes | Minor |380| Memory index mismatches | Minor |381| Marketplace refresh failed (single marketplace) | Minor |382383#### INFO (all single-tier, -0.1)384385No tier distinction. All INFO findings use the flat -0.1 weight. Updates INFO findings: marketplace refresh skipped (whole command failed).386387#### Zero-weight Updates findings (0.0, no penalty)388389These render in the Updates section but contribute nothing to the health score, matching the existing treatment of plugin updates:390391| Check | Indicator |392|-------|-----------|393| Marketplace refreshed | `⬆` |394| Marketplace already current | `✓` |395396#### Bedrock Config findings (zero-weight, exempt)397398The entire Bedrock Config category is advisory and contributes to NEITHER the Health score nor the Security score. This is a deliberate exemption from the standard severity weights (which would otherwise penalize an `i` at -0.1 and a `⚠` as a minor): the user intentionally and repeatedly skips some recommended options, so scoring them would peg the score permanently low. Do NOT count any of these toward either score:399400| Check | Indicator |401|-------|-----------|402| Missing recommended Bedrock option (each) | `i` |403| All recommended Bedrock config present | `✓` |404| Bedrock config check unavailable (Gemini/network) | `i` |405| Bedrock option added to settings.json | `✓` |406| Could not add Bedrock option (write failed) | `⚠` |407408### BEDROCK CONFIG Block409410When the Bedrock Config category (scope `all` or `bedrock`) finds recommended-but-missing options, render this section box. Every listed option is, by construction, both recommended and Bedrock-compatible, so there is no per-item compatibility badge. The box itself is not a scored finding; the entire Bedrock category is zero-weight (see Scores).411412```413┌─ BEDROCK CONFIG (N findings) ───────────────────────414│415│ i <N> recommended Bedrock-compatible options not currently set.416│417│ 1. settings.json: "<key>"418│ <one-line purpose>. Recommended: <value>.419│ Source: <citation url>420│421│ 2. env: <VAR_NAME>422│ <one-line purpose>. Recommended: <value>.423│ Source: <citation url>424│425└─────────────────────────────────────────────────────426```427428After rendering, present the `AskUserQuestion` multi-select described in the Bedrock Config check, write approved options via the `update-config` skill, and emit the per-option `✓ Added ...` confirmations as normal findings within the Bedrock Config section.429430### Section Ordering431432When `all` is selected, render sections in this order:4331. Updates4342. Bedrock Config4353. Skills4364. Hooks4375. Plugins4386. Rules4397. Settings4408. Security4419. MCP44210. Memory44311. Overlaps44412. Goal Assessment (only if a goal message was provided)445446When a single category is selected, show only that category section plus the summary.447448### Summary449450```451╭─────────────────────────────────────────────────────452│ Summary453├─────────────────────────────────────────────────────454│455│ Health: ✓ OK: N ✗ ERROR: N major, N minor ⚠ WARN: N major, N minor i INFO: N456│ Security: ✓ OK: N ⚠ WARN: N457│458│ Top Recommendations:459│460│ 1. Most impactful recommendation461│ 2. Second most impactful462│ 3. Third463│ 4. Fourth464│ 5. Fifth465│466╰─────────────────────────────────────────────────────467```468469**Summary counts formatting:**470- Health line: show tier breakdown for ERROR and WARN: `✗ ERROR: 1 major, 2 minor`471- Health line: when a severity has zero findings for a tier, omit that tier: `⚠ WARN: 3 minor`472- Health line: when a severity has zero findings entirely, show 0: `✗ ERROR: 0`473- Security line: show total WARN count only (no tier breakdown): `⚠ WARN: 3`474- Security line: when no warnings, show: `✓ OK: all clear`475476Rank recommendations across both dimensions by severity (health ERROR first, then health WARN, then security WARN), and within the same severity by impact. Show up to 5 recommendations.477478## Execution Order4794801. Parse arguments to determine scope. Separate category keywords from a quoted goal message (if any).4812. Read ALL mandatory scan paths for selected categories (use parallel tool calls where possible).4823. Run update checks first (if `all` or `updates` is selected) in this sub-order: (0) `claude plugin marketplace update` to refresh all marketplaces, comparing `known_marketplaces.json` `lastUpdated` before/after; (1) `claude --version` and `npm view` for the CLI version check; (2) read `installed_plugins.json` and run `claude plugins update <name>@<marketplace> -s <scope>` for each plugin (scope read from the plugin's entry); (3) detect stale plugin cache.4834. Run the Bedrock Config audit (if `all` or `bedrock` is selected), immediately after Updates so execution order matches render order: collect current config keys from `settings.json` and `settings.local.json`, call `gemini_search_grounded` for recommended Bedrock-compatible options, diff out already-set keys, present the BEDROCK CONFIG block and `AskUserQuestion` multi-select for any missing options, and write approved options via the `update-config` skill. On Gemini/network failure, emit the unavailable INFO line and continue. This category is zero-weight.4845. Run checks for each remaining selected category (including the Security category).4856. Run overlap checks (if `all` or `overlaps` is selected).4867. Calculate dual scores:487 - **Health score:** start at 10.0, classify each health finding by tier (see Health Tier Assignment Table), subtract the corresponding weight. Floor at 0.0, cap at 10.0.488 - **Security score:** start at 10.0, subtract each security finding's fixed weight (see Security Score Calculation). Floor at 0.0, cap at 10.0.4898. Generate goal assessment (if a goal message was provided): review all findings against the stated goal, filter to relevant findings, write verdict.4909. Render the full report: header, dual score lines, category boxes (including Security), goal assessment (if any), summary.49110. End with the summary box containing per-dimension counts and top 3-5 recommendations sorted by impact across both dimensions.