The single user-facing maintenance entrypoint for an existing Claude setup. Health-checks your configuration, decides whether it is fine as-is, needs an upgrade, or needs a rebuild, and takes that action — handing off to /upgrade-setup or /onboarding --rebuild as needed. Use when you want your setup checked and fixed, not just a findings report.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-onboarding-agent:checkupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
`/checkup` is the **single user-facing maintenance entrypoint** for an existing Claude setup. It runs `/audit-setup` internally, weighs findings + meta age + deprecated-model anchors, and either prints a short "fine-as-is" summary, hands off to `/upgrade-setup`, or invokes `/onboarding --rebuild`.
/checkup is the single user-facing maintenance entrypoint for an existing Claude setup. It runs /audit-setup internally, weighs findings + meta age + deprecated-model anchors, and either prints a short "fine-as-is" summary, hands off to /upgrade-setup, or invokes /onboarding --rebuild.
Call /checkup whenever you want to know whether your existing setup still matches current best practices. You never need to decide between /audit-setup and /upgrade-setup yourself — /checkup picks the right next step for you.
Power users may still invoke /audit-setup or /upgrade-setup directly when they already know which tool they want. Both skills keep their original behaviour and can be called independently. /checkup remains the canonical path for normal use.
This skill owns one decision: given an existing Claude setup, should the user rebuild it, improve it, or leave it fine-as-is? It then hands off to the appropriate skill. It does not audit (delegates to /audit-setup), does not apply changes (delegates to /upgrade-setup), does not scaffold (delegates to /onboarding).
The skill is a pure router. The only artifact it writes is an append-only line in .claude/checkup-log.md per invocation.
Detect language from the user's first message in this invocation and respond in it throughout. All file content and log lines stay in English (repo language rule).
The invocation may contain --no-delegate anywhere in the argument string (as a flag, not a value).
no_delegate: true. Stages 1–5 run normally, but Stage 6 prints the verdict and exits without invoking /onboarding, /upgrade-setup, or /audit-setup for any follow-up. (Testing aid — does not suppress the Stage 3 /audit-setup audit call, which is required for a real verdict.)no_delegate: false.Any other argument is ignored silently (forward compatibility).
Read ./.claude/onboarding-meta.json if it exists. Expected shape (see skills/_shared/write-meta.md):
{
"setup_type": "coding",
"skills_used": ["coding-setup"],
"plugin_version": "1.0.0",
"installed_at": "2026-04-01T12:00:00Z",
"upgraded_at": null
}
setup_type is a recognized slug (one of: coding, data-science, design, knowledge-base, devops, content-voice, office, research, academic-writing, web-development, graphify), set:
meta_present: truesetup_type, skills_used, installed_version: plugin_version, installed_atmeta_present: false, meta_corrupt: true. (Treated by Stage 2 as a hard gate — rebuild.)meta_present: false.repo-scanner subagent)Only run this if meta_present: false AND meta_corrupt is not true.
Dispatch a repo-scanner subagent (defined in .claude/agents/repo-scanner.md) to check whether plugin-owned delimiters exist in the user project.
Dispatch brief:
Use the Agent tool with:
subagent_type: repo-scanner
description: "Check for plugin-owned delimiters in the current project"
prompt: |
Scan the project rooted at the current working directory for
onboarding-agent-owned delimiters. Return your standard
JSON envelope (kind: "repo-scan"). The caller only needs these
fields inside `data`:
- existing_claude_md
- existing_agents_md
- signals (any string matching "onboarding-agent" or
"_onboarding_agent" indicates a marker)
Expected output: one fenced ```json block per the subagent's output contract.
Parse the reply via skills/_shared/parse-subagent-json.md with reply_kind: "repo-scan" and schema_path: ".claude/agents/schemas/repo-scan.schema.json". On success (result.ok: true), set delimiters_present: true if result.data.existing_claude_md == true OR result.data.existing_agents_md == true AND any entry in result.data.signals references onboarding-agent / _onboarding_agent, otherwise delimiters_present: false.
Trigger the fallback when the shared parser returns a failure marker (ok: false with any reason) after one retry, or when the Agent tool itself errors. On dispatch error, do not retry — fall back immediately. Print:
"⚠ repo-scanner subagent unavailable — falling back to inline delimiter scan."
Then scan these files if they exist:
./CLAUDE.md./AGENTS.md./.claude/settings.json (search for _onboarding_agent key)Look for the regex <!--\s*onboarding-agent:start (attributed or legacy form) in the markdown files, and the literal key "_onboarding_agent" in the JSON file.
delimiters_present: true.delimiters_present: false.If meta_present: false AND delimiters_present: false AND meta_corrupt is not true, print (adapt to detected language):
"No Claude onboarding-agent setup detected in this project. Run
/onboardingto create one./checkuponly makes sense on an existing setup."
Exit without logging.
Before deciding on rebuild vs. improve, check for legacy rule-file layouts:
skills/_shared/migrate-claude-instructions.md and follow its Detection section..migration-declined does not), run the full migration procedure from the helper (Preview → user decision → Execution).Do not suppress the migration prompt within a session — re-offer on every checkup invocation until the user either migrates or writes .migration-declined.
The plugin owns these subagent filenames under .claude/agents/:
| Slug | Owning Skill |
|---|---|
code-reviewer | coding-setup |
component-auditor | web-development-setup |
notebook-auditor | data-science-setup |
writing-style-auditor | academic-writing-setup |
obsidian-vault-keeper | knowledge-base-setup |
Detection: read .claude/onboarding-meta.json and list the slugs in subagents_installed[]. Cross-check against .claude/agents/ on disk. Record the present / missing / unknown slugs as subagent_state for reporting in Stage 5.
--rebuild behaviour:
skills_used) and the subagent file is either missing or present-but-plugin-owned, include it in the rebuild preview..claude/agents/ not on the catalog is user-authored and never touched.Evaluate the gates in order. The first gate that fires forces verdict = rebuild and short-circuits Stages 3–4 — jump straight to Stage 5 with the triggering reason as hard_gate_reason.
If ./.claude/settings.json exists but fails JSON parse → fire with reason: "corrupt settings.json — /upgrade-setup cannot safely edit it".
If meta_corrupt: true (from Step 1.1) AND delimiters_present: false → fire with reason: "corrupt .claude/onboarding-meta.json and no delimiters found — no anchor for selective edits".
If meta_corrupt: true BUT delimiters_present: true, do NOT fire G2 — the markers still give /upgrade-setup an anchor. The meta file will be rewritten by /upgrade-setup later.
If meta_present: true AND installed_version is a valid semver AND current_plugin_version is a valid semver AND installed_version > current_plugin_version → fire with reason: "meta records plugin v<installed_version> but v<current_plugin_version> is running — downgrade scenario, rebuild for consistency".
Resolve current_plugin_version by reading the plugin's own plugin.json in this order:
~/.claude/plugins/claude-onboarding-agent/.claude-plugin/plugin.json./.claude/plugins/claude-onboarding-agent/.claude-plugin/plugin.json./.claude-plugin/plugin.json (when running inside the plugin repo)If none resolve, set current_plugin_version: "unknown" and SKIP G3 (cannot compare).
Only run if meta_present: true. Compare setup_type from meta against a lightweight repo scan (mirrors onboarding/SKILL.md Step 2 heuristics):
coding → fewer than 5 files total across .py/.ts/.js/.go/.rs/.rb/.java/.cs AND no manifest (package.json, pyproject.toml, Cargo.toml, go.mod, requirements.txt) → fire.web-development → no web-framework config (next.config.*, vite.config.*, astro.config.*, svelte.config.*, nuxt.config.*) AND no framework dep in package.json → fire.data-science → no .ipynb files AND no notebooks/ dir AND no data/raw/ dir AND no DS deps (pandas/polars/numpy/scikit-learn/torch/jax) in pyproject.toml → fire.research → no .tex, .bib, .typ files → fire.academic-writing → no sections/, no bib/, no main.tex/main.typ, no .typ alongside .bib → fire.knowledge-base → no notes/, vault/, wiki/, obsidian/, raw/, and no sizable markdown corpus (< 5 .md files outside the repo root) → fire.office → no *.docx/*.pptx/*.pdf/*.xlsx files → fire.content-voice, devops, design, graphify → no deterministic content signal; do NOT fire G4 for these types (let Stage 4 judge).Fire reason format: "setup_type=<type> but repo content does not match (missing: <short signal list>)".
If G4 fires, do NOT offer --rebuild without the user first confirming the setup type is actually wrong — the rebuild rationale will be surfaced in Stage 5.
If any gate fires, set verdict: rebuild, hard_gate_fired: true, rationale: "<gate reason>", and jump to Stage 5. Skip Stages 3 and 4 entirely.
audit-collector subagent)audit-collectorDispatch an audit-collector subagent (defined in .claude/agents/audit-collector.md) to run the audit skill and return a compact severity-bucketed summary.
Dispatch brief:
Use the Agent tool with:
subagent_type: audit-collector
description: "Run /audit-setup and summarize findings"
prompt: |
Invoke the audit skill named below and return your standard
JSON envelope (kind: "audit-summary") with severity-bucketed counts.
audit_skill: audit-setup
max_top_titles: 3
Expected output: one fenced ```json block per the subagent's output contract.
Parse the reply via skills/_shared/parse-subagent-json.md with reply_kind: "audit-summary" and schema_path: ".claude/agents/schemas/audit-summary.schema.json". On success (result.ok: true), store audit_findings: { total: result.data.total, high: result.data.high, medium: result.data.medium, low: result.data.low, top_titles: result.data.top_titles }. Continue to Stage 4.
If the envelope arrives with ok: false (the subagent's documented in-band error signal), treat it as a subagent failure and use the Fallback below.
Trigger the fallback when the shared parser returns a failure marker (ok: false with any reason) after one retry, or when the subagent's envelope arrives with ok: false, or when the Agent tool itself errors. On dispatch error, do not retry — fall back immediately. Print:
"⚠ audit-collector unavailable — running /audit-setup inline."
Then run the inline path as before:
Try to invoke the audit-setup skill. If it is not installed / not found / not available in this environment, print (adapt to detected language):
"
/checkuprequires/audit-setup. Install the onboarding-agent plugin (or re-install it) and retry."
Exit without logging. Do NOT proceed to Stage 4 without findings.
Invoke the audit-setup skill inline. Capture the findings block it prints. Parse:
high_count, medium_count, low_count./audit-setup printed them — HIGH first).Store as audit_findings: { total, high, medium, low, top_titles: [...] }.
If /audit-setup returns its "nothing to improve" message (no findings at all), set audit_findings: { total: 0, high: 0, medium: 0, low: 0, top_titles: [] }.
This stage only runs if Stage 2 did not fire a hard gate.
Assemble the inputs:
audit_findings — from Stage 3.meta_age_days — derived from installed_at (or upgraded_at if set and later): today's date minus installed/upgraded date, rounded down to days. If meta missing, use delimiter_only: true (no age signal).repo_size_bucket — rough bucket: tiny (< 20 non-hidden files), small (20–200), medium (200–2000), large (> 2000). Use Bash find . -not -path './.*' -type f | wc -l or equivalent.anchor_deprecated_models — list of deprecated model IDs referenced anywhere in CLAUDE.md, AGENTS.md, .claude/settings.json. Fetch claude-models anchor via skills/_shared/fetch-anchor.md with anchor_name: claude-models and the same embedded fallback used by /audit-setup Pass 5. If the anchor is unreachable (anchor_markdown: null), set this to null (do not block). Capture the fetch's fetch_freshness output into anchor_freshness — values other than network or cache mean the deprecated-models check ran against a stale or embedded snapshot and the verdict rationale should say so.setup_type and skills_used from meta (if present).Apply the following judgment (in this priority order — first match wins):
audit_findings.high >= 3 AND (one of those HIGHs is a structural failure — e.g. "Overly broad tool permissions" plus something at least one of: "Potential secret…", "Deprecated Claude model ID referenced")setup_type clearly does not match repo_signals from a lightweight re-scan (soft mismatch — Stage 2 catches the hard one)meta_age_days > 540 (≈ 18 months — templates will have moved meaningfully)audit_findings.total >= 1 AND not caught by the rebuild branchanchor_deprecated_models is a non-empty list (one deprecated ID alone is enough — /upgrade-setup can flip it)audit_findings.total == 0 AND anchor_deprecated_models is empty or null.Write a 2–3 sentence rationale that cites the strongest 1–2 signals. Examples:
.claude/settings.json. /upgrade-setup can fix both without touching user-owned config." → improve/audit-setup, meta is 12 days old, no deprecated model references. Your setup matches current plugin defaults." → fine-as-isrebuildSet verdict and rationale.
Print a compact block (adapt the framing to detected language; keep verdict / command / paths in English):
Checkup — Verdict
Verdict: <rebuild | improve | fine-as-is>
Rationale: <rationale>
Delegated command (if accepted):
- rebuild → /onboarding --rebuild (backs up existing setup to .claude/backups/<timestamp>-onboarding/)
- improve → /upgrade-setup (per-change confirmation, backup, --dry-run available)
- fine-as-is → nothing — short summary, no changes
Accept verdict? (a = accept / r = rebuild / i = improve / f = fine / q = quit)
Interpret the reply:
a / accept / yes / y → chosen_verdict = verdict (accepted).r → chosen_verdict = rebuild (override if verdict was something else).i → chosen_verdict = improve.f → chosen_verdict = fine-as-is.q / quit / n / no → abort; do not delegate, but still log the run (with user_chose=quit).q.If chosen_verdict != verdict (user overrode), prompt:
"One-line reason for the override (optional — press Enter to skip):"
Accept any reply including an empty one. Normalize to a single line (replace newlines with spaces, collapse whitespace, cap at 200 chars). Store as override_reason.
If verdict was accepted as-is, set override_reason = "".
Append one line to ./.claude/checkup-log.md (create the file if missing — ensure ./.claude/ exists first via Bash mkdir -p). Format (exact, single line, UTF-8):
YYYY-MM-DD verdict=<v> user_chose=<v> reason="<override_reason>"
Where YYYY-MM-DD is today's local date. Always wrap reason in double quotes, even when empty (reason=""). Escape any internal " as \". Never truncate a line across multiple lines.
If the file already has content, ensure the new line starts on a fresh line (prepend a newline only if the file does not already end with one).
If no_delegate: true, skip this stage: just print the completion summary (Stage 7) and exit.
Otherwise dispatch according to chosen_verdict:
rebuildInvoke the onboarding skill with the --rebuild flag. Onboarding's Step 1b runs skills/_shared/backup-before-write.md (trigger: onboarding-rebuild) and is the single canonical backup for this verdict. Checkup does NOT create its own backup here — doing so would produce two redundant .claude/backups/ directories in the same invocation.
If onboarding --rebuild is not supported in the installed plugin version (detect by reading skills/onboarding/SKILL.md for the --rebuild keyword; if the skill file is not resolvable, attempt invocation and fall back on failure), fall back to:
--rebuild flag not supported by the installed /onboarding. Back up your existing setup manually (copy CLAUDE.md, AGENTS.md, .claude/settings.json, .claude/onboarding-meta.json, claude_instructions/ somewhere safe) then run /onboarding."/onboarding — let the user do it after backing up.improveInvoke the upgrade-setup skill. Pass no additional arguments (the user can re-run /upgrade-setup --dry-run themselves if they want).
If /upgrade-setup is not installed (not in the plugin's skills list), fall back:
/audit-setup findings inline (re-use the block captured in Stage 3 — do not re-run the audit)./upgrade-setup (issue #5) would automate these changes. Until it is installed, apply the fixes manually using the How to apply lines above."fine-as-isNo delegation. Print a short summary:
Your Claude setup looks current.
Setup type: <setup_type | unknown>
Last upgraded: <upgraded_at | installed_at — never upgraded | unknown>
Meta path: .claude/onboarding-meta.json
Re-run `/checkup` any time to re-evaluate your setup — it runs the audit again and picks the right next step. Power users can still call `/audit-setup` directly for raw findings.
Always print this block at the end, regardless of path (skipped only if Stage 1 / Stage 3 aborted):
Checkup complete.
Verdict: <verdict>
Chosen: <chosen_verdict>
Override reason: <override_reason or "(none)">
Delegated to: <"/onboarding --rebuild" | "/upgrade-setup" | "(none — fine-as-is)" | "(none — --no-delegate)">
Log: .claude/checkup-log.md
Backup: <".claude/backups/<timestamp>-onboarding/" when onboarding --rebuild ran | "(n/a)">
Anchor freshness: <"network" or "cache" → omit this line;
"fallback" → "claude-models served from fallback snapshot — re-run /anchors once upstream is reachable";
"embedded" → "claude-models unreachable and no fallback — deprecated-model check skipped">
The Backup: path is only meaningful when onboarding with --rebuild actually ran and completed — if onboarding is still running when this skill returns, leave it as "(see /onboarding output)".
fine-as-is, Stage 6c.rebuild.rebuild.rebuild.improve, delegates to /upgrade-setup./audit-setup not installed → Stage 3.1 aborts with clear message./upgrade-setup missing, verdict improve → Stage 6b prints findings inline and points at issue #5.fine-as-is with rebuild → override reason prompted; log line records verdict=fine-as-is user_chose=rebuild reason="..."./checkup --no-delegate → verdict printed, log written, no follow-up invocation..claude/checkup-log.md is append-only and never rotated by this skill; users can prune it manually./checkup re-runs /audit-setup and re-judges.Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub a2ngerer/claude_onboarding_agent --plugin claude-onboarding-agent