Skip to content
Development
Command

/doctor

Health-check the scaffolding install and report install problems plus exact fixes (diagnose-only, never mutates).

From plugin
scaffolding
1519 skills13 agents19 commands20 hooks
Install
> /plugin marketplace add komluk/scaffolding
> /plugin install scaffolding@komluk-scaffolding

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/doctor

Context preview

What this command does when you run it.

Health-check the scaffolding install and report install problems plus exact fixes (diagnose-only, never mutates).

Command definition

doctor.md
name: doctor
description: Health-check the scaffolding install and report install problems plus exact fixes (diagnose-only, never mutates).

/doctor Command

Run a health check of the scaffolding plugin install and report problems with the exact command to fix each one. Diagnoses the documented first-run gotchas (the #1 being `Agent type 'scaffolding:...' not found` after a fresh install) and groups findings by severity.

Usage

/doctor

Run from any project. No arguments. Safe to run repeatedly.

Guardrail — DIAGNOSE ONLY (never mutate)

This command **only diagnoses and prints fixes**. It MUST NEVER:

  • run `/reload-plugins`, `/plugin install/update`, or restart anything itself
  • edit `settings.json`, `CLAUDE.md`, `.gitignore`, or any user/project file
  • `chmod`, `mkdir`, `cp`, register an MCP server, or set an env var

It only reads files, runs read-only shell, and spawns **one trivial probe agent** (check #2). Print the exact command for the *user* to run — matches the propose-don't-mutate posture of `/memory`.

Steps

Follow these steps exactly, in order.

Step A — Run the inline health-check bash block

Run the block below verbatim. It performs the file/shell checks (#1, #3–#10) and prints a grouped report. It writes nothing.

# ---- scaffolding /doctor — read-only health check ----
BLOCKING=0; RECOMMENDED=0; OPTIONAL=0
pass() { printf '  [PASS] %s\n' "$1"; }
fail() { printf '  [FAIL] %s\n        fix: %s\n' "$1" "$2"; }

# Locate the installed plugin root (same multi-base discovery as /init-scaffolding)
PLUGIN_ROOT=""
find_plugin_root() {
  local base="$1"; [ -d "$base" ] || return
  local latest
  latest=$(find "$base" -name "CLAUDE.md" -path "*/scaffolding/*/CLAUDE.md" 2>/dev/null | sort -V | tail -1 | xargs dirname 2>/dev/null || true)
  if [ -n "$latest" ] && [ -f "$latest/CLAUDE.md" ]; then echo "$latest"; return; fi
  latest=$(find "$base" -name "CLAUDE.md" 2>/dev/null | sort -V | tail -1 | xargs dirname 2>/dev/null || true)
  if [ -n "$latest" ] && [ -f "$latest/CLAUDE.md" ]; then echo "$latest"; return; fi
}
# Prefer the env var Claude Code injects when the plugin is loaded
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/CLAUDE.md" ]; then
  PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
fi
if [ -z "$PLUGIN_ROOT" ]; then
  for base in \
    "$HOME/.claude/plugins/cache/komluk-scaffolding" \
    "$HOME/.claude/plugins/marketplaces/komluk-scaffolding" \
    "${USERPROFILE:-}/.claude/plugins/cache/komluk-scaffolding" \
    "${LOCALAPPDATA:-}/claude/plugins/cache/komluk-scaffolding"; do
    [ -n "$base" ] || continue
    found=$(find_plugin_root "$base")
    if [ -n "$found" ]; then PLUGIN_ROOT="$found"; break; fi
  done
fi

echo "=== BLOCKING (install will not work until these pass) ==="

# Check 1 — plugin installed / loaded
if [ -n "$PLUGIN_ROOT" ] && [ -f "$PLUGIN_ROOT/CLAUDE.md" ]; then
  if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
    pass "Plugin installed & loaded (CLAUDE_PLUGIN_ROOT set; root: $PLUGIN_ROOT)"
  else
    pass "Plugin installed (cache root: $PLUGIN_ROOT)"
    echo "        note: CLAUDE_PLUGIN_ROOT not set in this shell — fine for /doctor, but if hooks misbehave, restart Claude Code."
  fi
else
  BLOCKING=$((BLOCKING+1))
  fail "Plugin not installed / not found" "/plugin marketplace add komluk/scaffolding   then   /plugin install scaffolding@komluk-scaffolding"
fi

# Check 1b — agent files present (13) — needed for resolution
if [ -n "$PLUGIN_ROOT" ]; then
  AGENT_COUNT=$(find "$PLUGIN_ROOT/agents" -maxdepth 1 -name '*.md' 2>/dev/null | wc -l | tr -d ' ')
  if [ "$AGENT_COUNT" = "13" ]; then
    pass "All 13 agent definitions present in plugin root"
  else
    BLOCKING=$((BLOCKING+1))
    fail "Incomplete install — found ${AGENT_COUNT:-0}/13 agent files" "/plugin update scaffolding@komluk-scaffolding   then   /reload-plugins"
  fi
fi

# Check 4 — plugin.json valid + hooks registered
if [ -n "$PLUGIN_ROOT" ]; then
  PJ="$PLUGIN_ROOT/.claude-plugin/plugin.json"
  [ -f "$PJ" ] || PJ="$PLUGIN_ROOT/plugin.json"
  if [ -f "$PJ" ] && python3 -c "import json,sys; d=json.load(open(sys.argv[1])); assert d.get('hooks')" "$PJ" 2>/dev/null; then
    pass "plugin.json valid and hooks registered"
  else
    BLOCKING=$((BLOCKING+1))
    fail "plugin.json missing/invalid or no hooks registered" "/plugin update scaffolding@komluk-scaffolding   then   /reload-plugins"
  fi
fi

echo ""
echo "=== RECOMMENDED (protocol / hooks / memory tiers) ==="

# Check 3a — settings.json present in plugin root
if [ -n "$PLUGIN_ROOT" ] && [ -f "$PLUGIN_ROOT/settings.json" ] \
   && python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$PLUGIN_ROOT/settings.json" 2>/dev/null; then
  pass "settings.json present and valid in plugin root"
else
  RECOMMENDED=$((RECOMMENDED+1))
  fail "settings.json missing or unparseable in plugin root" "/plugin update scaffolding@komluk-scaffolding (reinstall)"
fi

# Check 3b — hook .sh files present + executable (9 plugin-registered hooks; refresh-mcp-token.sh is opt-in)
if [ -n "$PLUGIN_ROOT" ] && [ -d "$PLUGIN_ROOT/hooks" ]; then
  NONEXEC=$(find "$PLUGIN_ROOT/hooks" -maxdepth 1 -name '*.sh' ! -perm -u+x 2>/dev/null | wc -l | tr -d ' ')
  SH_COUNT=$(find "$PLUGIN_ROOT/hooks" -maxdepth 1 -name '*.sh' 2>/dev/null | wc -l | tr -d ' ')
  if [ "${NONEXEC:-0}" = "0" ] && [ "${SH_COUNT:-0}" -gt 0 ]; then
    pass "All $SH_COUNT hook scripts present and executable"
  else
    RECOMMENDED=$((RECOMMENDED+1))
    fail "$NONEXEC hook script(s) not executable — hooks will silently no-op" "chmod +x \"$PLUGIN_ROOT/hooks/\"*.sh   (or reinstall the plugin)"
  fi
else
  RECOMMENDED=$((RECOMMENDED+1))
  fail "hooks/ directory not found in plugin root" "/plugin update scaffolding@komluk-scaffolding (reinstall)"
fi

# Check 5 — in-repo CLAUDE.md (per-project routing)
if [ -f "./CLAUDE.md" ]; then
  pass "In-repo CLAUDE.md present — routing protocol travels to this repo"
  # Check 5b — routing section intact (HARD INVARIANT: never
Read more
Ships withscaffolding

Spec-driven multi-agent orchestration for Claude Code — pure markdown, zero backend, runs on the stock runtime. 13 agents, 36 skills, 19 commands, 15 hooks, per-phase model tiers, opt-in lifecycle hooks, optional cross-device semantic memory.

Get the whole plugin

Other commands on scaffolding.