health
Skill8 starsChanged 6 months agoMITView on GitHub
Code quality dashboard: runs the project's type checker, linter and tests, scores health 0-10, tracks trends.
53 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- KadirHarmanc/nazar-skilltheir own version, first seen Nov 8, 2026
- buildomator/buildomatortheir own version, first seen Nov 4, 2026
- trungtm78/ClaudeSkillstheir own version, first seen Oct 25, 2026
- linggen/skillstheir own version, first seen Oct 22, 2026
- ClarvAI/job-search-hqtheir own version, first seen Oct 15, 2026
- Wanghaoyihaoyi/agent-skillstheir own version, first seen Oct 15, 2026
Used with
Projects with it also use ios-clean, ios-fix and 5 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Saqlain-811Skillios-clean
Remove the DebugBridge SPM package and all #if DEBUG wiring from an iOS app. (gstack)
Also in 5 projects that use this
Saqlain-811Skillios-fix
Autonomous iOS bug fixer. (gstack)
Also in 5 projects that use this
seek888Skillopen-gstack-browser
Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in. Opens a visible browser window where you can watch every action in real time. The sidebar shows a live activity feed and chat. Anti-bot stealth built in. Use when asked to "open gstack browser", "launch browser", "connect chrome", "open chrome", "real browser", "launch chrome", "side panel", or "control my browser". Voice triggers (speech-to-text aliases): "show me the browser".
Also in 8 projects that use this
ShreyRaviSkillsetup-gbrain
Set up gbrain for this coding agent: install the CLI, initialize a local PGLite or Supabase brain, register MCP, capture per-remote trust policy. One command from zero to "gbrain is running, and this agent can call it." Use when: "setup gbrain", "connect gbrain", "start gbrain", "install gbrain", "configure gbrain for this machine". (gstack)
Also in 6 projects that use this
ShreyRaviSkillsync-gbrain
Keep gbrain current with this repo's code and refresh agent search guidance in CLAUDE.md. Wraps the gstack-gbrain-sync orchestrator with state probing, native code-surface registration, capability checks, and a verdict block. Re-runnable, idempotent. Use when: "sync gbrain", "refresh gbrain", "re-index this repo", "gbrain search isn't finding things". (gstack)
Also in 6 projects that use this
bastosSkillios-design-review
Review iOS app UI/UX design quality using Apple's design principles and the Liquid Glass-era design language from WWDC25/26. Use when asked for a design review, UX critique, visual design assessment, or evaluation of an app's interface quality, design intent, alignment with the new Apple design system, or usability. Triggers: "design review", "UX review", "visual design critique", "review the UI", "does this design work", "evaluate this interface", "design feedback", "Liquid Glass review".
Also in 5 projects that use this
- +1 more from Saqlain-811
Other versions53 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- garrytan/gstack★ 141k26% same
Wrote their own version · 52
- tw93/claude-health★ 7.5ksame name
- tw93/Waza★ 7.5ksame name
- agenticnotetaking/arscontexta★ 3.5ksame name
- kellyvv/PhoneClaw★ 1.3ksame name
- ninehills/skills★ 280same name
- kv0906/pm-kit★ 138same name
- buildomator/buildomator★ 102same name
- priyanshuchaudhary53/naval-skills★ 19same name
- JaimeGBA/Ion★ 9same name
- IvanSkainet/arena-agent★ 8same name
42 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository62 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- address-pr-reviewSkill
- agent-evalSkill
- ai-cost-guardSkill
- autoplanSkill
- aws-costSkill
- bedrock-guardrailsSkill
- benchmarkSkill
- browseSkill
- canarySkill
- carefulSkill
- claudeSkill
- codexSkill
- connect-chromeSkill
- connect-reviewSkill
- context-restoreSkill
- context-saveSkill
- csoSkill
- design-consultationSkill
- design-htmlSkill
- design-reviewSkill
- design-shotgunSkill
- devex-reviewSkill
- diagramSkill
- document-generateSkill
- document-releaseSkill
- freezeSkill
- guardSkill
- iac-reviewSkill
- improve-archSkill
- investigateSkill
- kb-reviewSkill
- land-and-deploySkill
- landing-reportSkill
- learnSkill
- make-pdfSkill
- mcp-reviewSkill
- office-hoursSkill
- open-browserSkill
- pair-agentSkill
- plan-ceo-reviewSkill
- plan-design-reviewSkill
- plan-devex-reviewSkill
- plan-eng-reviewSkill
- plan-tuneSkill
- pr-summarySkill
- qa-onlySkill
- qaSkill
- retroSkill
- reviewSkill
- scrapeSkill
- setup-browser-cookiesSkill
- setup-deploySkill
- shipSkill
- skillifySkill
- specSkill
- telegramSkill
- unfreezeSkill
- unslopSkill
- vibe-gcSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
27 rules. 0 are common, 11 are distinctive, and 16 are very specific to this project.
0
Common
Most of the 38 edited versions we read keep these.
11
Distinctive
This author's own choices. Worth a look.
16
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
If this session was compacted, the copy of this skill in context may be cut off.
- Very specific: line 20
Read ${CLAUDE_SKILL_DIR}/SKILL.md from disk and resume at the step you are on.
- Distinctive: line 24
Use when: "health check", "code quality", "how healthy is the codebase", "run all checks", "quality score".
- Very specific: line 51
When the user types /health, run this skill.
- Very specific: line 59
Read CLAUDE.md and look for a ## Health Stack section.
- Very specific: line 64
If no ## Health Stack section exists, auto-detect available tools:
- Distinctive: line 122
Use Glob to search for shell scripts:
- Distinctive: line 125
After auto-detection, present the detected tools via AskUserQuestion:
- Very specific: line 139
If the user chooses A or B (after adjustments), append or update a ## Health Stack section in CLAUDE.md:
- Distinctive: line 156
Run each detected tool. For each tool:
- Distinctive: line 159
Run the command, capturing complete stdout and stderr in a private temporary log
- Distinctive: line 198
Run tools sequentially, one block per tool (some share resources or lock files).
- Very specific: line 229
Parsing tool output for counts: use the complete captured log (COUNT above), never the displayed tail.
- Distinctive: line 310
Use these status labels:
- Very specific: line 330
Always show the coverage lines.
- Distinctive: line 337
If any category scored below 7, list the top issues from that tool's output:
- Very specific: line 356
Only when the composite is numeric, append one JSONL line to <PROJECT_DIR>/health-history.jsonl (where <PROJECT_DIR> is the path the block …
- Very specific: line 371
If a category was skipped, set its value to null.
- Very specific: line 377
Read the last 10 entries from <PROJECT_DIR>/health-history.jsonl (if the file exists and has prior entries).
- Very specific: line 445
Checks: Run Step 1 (a ## Health Stack section, or auto-detection).
- Very specific: line 473
If a log says vibe-evidence itself was not found, stop: this mode proves its result from the ledger, and without it there is nothing to …
- Distinctive: line 484
Never stub, mock or skip around it.
- Very specific: line 490
Finish from the ledger: Do not re-run anything; ask the ledger whether each check's exact command passed at the tree as it is now.
- Distinctive: line 564
Wrap, don't replace: Run the project's own tools.
- Very specific: line 565
Read-only outside
--fix: Never fix issues unless the user ran /health --fix. - Very specific: line 566
Respect CLAUDE.md: If ## Health Stack is configured, use those exact commands.
- Distinctive: line 568
Show raw output for failures: When a tool reports errors, include the actual output (tail -50) so the user can act on it without re-running.
“Common” is measured: kept by at least 6 in 10 of the 38 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
If this session was compacted, the copy of this skill in context may be cut off.
Read ${CLAUDE_SKILL_DIR}/SKILL.md from disk and resume at the step you are on.
When to invoke
Use when: "health check", "code quality", "how healthy is the codebase", "run all checks", "quality score".
Preamble
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-search" --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
User-invocable
When the user types /health, run this skill. /health skills runs
Target: skills instead of Steps 1-6. /health --fix runs
Mode: --fix instead of Steps 2-6.
Step 1: Detect Health Stack
Read CLAUDE.md and look for a ## Health Stack section. If found, parse the tools
listed there and skip auto-detection. Then print `MISSING: <category> (not listed in
Health Stack)` for each of the five categories (typecheck, lint, test, deadcode,
shell) the section omits.
If no ## Health Stack section exists, auto-detect available tools:
# A Node tool installed as a devDependency is not on PATH; run it from node_modules/.bin.
node_tool() { if [ -x "node_modules/.bin/${1}" ]; then echo "./node_modules/.bin/${1}"; else echo "${1}"; fi; }
setopt +o nomatch 2>/dev/null || true
health_found=$(
# Type checker
[ -f tsconfig.json ] && echo "TYPECHECK: $(node_tool tsc) --noEmit"
# Linter
[ -f biome.json ] || [ -f biome.jsonc ] && echo "LINT: $(node_tool biome) check ."
ls eslint.config.* .eslintrc.* .eslintrc 2>/dev/null | sed -n '1p' | xargs -I{} echo "LINT: $(node_tool eslint) ."
[ -f .pylintrc ] || [ -f pyproject.toml ] && grep -q "pylint\|ruff" pyproject.toml 2>/dev/null && echo "LINT: ruff check ."
command -v terraform >/dev/null 2>&1 && [ -n "$(find . -maxdepth 3 -name '*.tf' -not -path '*/.terraform/*' 2>/dev/null | sed -n '1p')" ] && echo "LINT: terraform fmt -check -recursive"
command -v cfn-lint >/dev/null 2>&1 && cfn_files=$(find . -maxdepth 3 \( -name node_modules -o -name .git \) -prune -o -type f \( -name '*.yaml' -o -name '*.yml' -o -name '*.json' -o -name '*.template' \) -exec grep -l 'AWSTemplateFormatVersion' {} + 2>/dev/null | sort | tr '\n' ' ') && [ -n "$cfn_files" ] && echo "LINT: cfn-lint ${cfn_files% }"
command -v actionlint >/dev/null 2>&1 && [ -d .github/workflows ] && echo "LINT: actionlint"
# Test runner: only a non-empty, single-line scripts.test is a command.
[ -f package.json ] && python3 -I -c '
import json, sys
try:
t = json.load(open(sys.argv[1])).get("scripts", {}).get("test")
except Exception:
sys.exit(0)
if isinstance(t, str) and t.strip():
t = t.strip()
print("TEST: none (multi-line test script; add it to a ## Health Stack section)" if "\n" in t else "TEST: " + t)
' package.json
[ -f pyproject.toml ] && grep -q "pytest" pyproject.toml 2>/dev/null && echo "TEST: pytest"
[ -f Cargo.toml ] && echo "TEST: cargo test"
[ -f go.mod ] && echo "TEST: go test ./..."
# Dead code
command -v knip >/dev/null 2>&1 && echo "DEADCODE: knip"
[ -f package.json ] && grep -q '"knip"' package.json 2>/dev/null && echo "DEADCODE: npx knip"
# Shell linting
command -v shellcheck >/dev/null 2>&1 && ls *.sh scripts/*.sh bin/*.sh 2>/dev/null | sed -n '1p' | xargs -I{} echo "SHELL: shellcheck"
)
[ -n "$health_found" ] && printf '%s\n' "$health_found"
# One MISSING line, with its reason, per category nothing was detected for.
health_missing() { printf 'MISSING: %s (%s)\n' "${1}" "${2}"; }
printf '%s\n' "$health_found" | grep -q '^TYPECHECK: ' || health_missing typecheck "no tsconfig.json"
printf '%s\n' "$health_found" | grep -q '^LINT: ' || health_missing lint "no biome, eslint or ruff config; no terraform, cfn-lint or actionlint target with its binary on PATH"
if ! printf '%s\n' "$health_found" | grep '^TEST: ' | grep -vq '^TEST: none ('; then
test_reason=$(printf '%s\n' "$health_found" | sed -n 's/^TEST: none (\(.*\))$/\1/p' | sed -n '1p')
health_missing test "${test_reason:-no scripts.test, pytest, Cargo.toml or go.mod}"
fi
printf '%s\n' "$health_found" | grep -q '^DEADCODE: ' || health_missing deadcode "knip neither on PATH nor in package.json"
printf '%s\n' "$health_found" | grep -q '^SHELL: ' || health_missing shell "shellcheck not on PATH, or no *.sh in ., scripts/ or bin/"A TEST: none (...) line is not a command: the test category is missing, for the
reason in parentheses. Every MISSING: category is unavailable (null in Step 3)
and its reason goes into the dashboard's Unavailable line.
Use Glob to search for shell scripts:
**/*.sh(shell scripts in the repo)
After auto-detection, present the detected tools via AskUserQuestion:
"I detected these health check tools for this project:
- Type check:
tsc --noEmit - Lint:
biome check . - Tests:
bun test - Dead code:
knip - Shell lint:
shellcheck *.sh
A) Looks right -- persist to CLAUDE.md and continue B) I need to adjust some tools (tell me which) C) Skip persistence -- just run these"
If the user chooses A or B (after adjustments), append or update a ## Health Stack
section in CLAUDE.md:
## Health Stack
- typecheck: tsc --noEmit
- lint: biome check .
- test: bun test
- deadcode: knip
- shell: shellcheck *.sh scripts/*.shStep 2: Run Tools
Run each detected tool. For each tool:
- Record the start time
- Run the command, capturing complete stdout and stderr in a private temporary log
- Record the checker's own exit code, before any parser or display command runs
- Record the end time
- Count findings from the complete log, then show its last 50 lines for the report
# Capture one tool. Per tool, set health_tool, the command line and the count pattern.
(
umask 077
health_tool=typecheck
health_pattern='error TS'
health_capture_error() {
printf 'TOOL:%s ERROR:capture-%s\n' "$health_tool" "${1}"
exit 125
}
health_log=$(mktemp "${TMPDIR:-/tmp}/vibe-health.XXXXXX") || health_capture_error log
trap 'rm -f -- "$health_log"' EXIT
health_start=$(date +%s) || health_capture_error timing
# Open the log first, so a redirection failure cannot pass for a checker result.
exec 3>"$health_log" || health_capture_error redirection
if tsc --noEmit >&3 2>&1; then
health_status=0
else
health_status=$?
fi
exec 3>&-
health_end=$(date +%s) || health_capture_error timing
# awk prints 0 for no matches, so an empty log still yields a count.
health_count=$(awk -v p="$health_pattern" 'index($(0), p) { n++ } END { print n+0 }' "$health_log") || health_capture_error parsing
tail -50 "$health_log" || health_capture_error display
printf 'TOOL:%s EXIT:%s DURATION:%ss COUNT:%s\n' "$health_tool" "$health_status" "$((health_end-health_start))" "$health_count"
)EXIT is the checker's status, never that of tail, awk or a pipe. COUNT comes
from the whole log, not the 50 lines shown. Swap in the tool's command and the fixed
string that marks one finding (error TS for tsc; Step 3 lists the others); for a
tool whose summary line carries the count, read it from the same log.
Run tools sequentially, one block per tool (some share resources or lock files). A failing checker does not stop the later ones.
SKIPPED, FAILED or ERROR — decide before and after running:
- SKIPPED — decided before running: the tool's binary is absent
(
command -v <binary>finds nothing, no localnode_modules/.binentry) and no## Health Stackentry names it. Record the reason. Only a skip redistributes weight. A binary that exists only innode_modules/.binis present: run it as./node_modules/.bin/<binary>, including when a## Health Stackentry names it bare. - FAILED — the command ran and could not execute the check: exit 126 or 127
(typo, missing binary in a configured
## Health Stackcommand, no permission). It scores 0. A configured command that does not run is a broken check, not a missing one, and must never raise the score. - ERROR — the capture itself broke (
TOOL:<name> ERROR:capture-...: log, redirection, timing, parsing or display). The category gets no score, the composite isN/A — capture failed, and no history row is written.
Step 3: Score Each Category
Score each category on a 0-10 scale using this rubric:
| Category | Weight | 10 | 7 | 4 | 0 |
| Type check | 25% | Clean (exit 0) | <10 errors | <50 errors | >=50 errors |
| Lint | 20% | Clean (exit 0) | <5 warnings | <20 warnings | >=20 warnings |
| Tests | 30% | All pass (exit 0) | >95% pass | >80% pass | <=80% pass |
| Dead code | 15% | Clean (exit 0) | <5 unused exports | <20 unused | >=20 unused |
| Shell lint | 10% | Clean (exit 0) | <5 issues | >=5 issues | N/A (skip) |
Parsing tool output for counts: use the complete captured log (COUNT above),
never the displayed tail. A non-zero exit is never CLEAN and never 10. Exit 126 or
127 is FAILED and scores 0, whatever the log says. Any other non-zero exit whose
full log yields no count scores 4 (as for a test runner that reports only its exit
code); keep its output for the details section.
- tsc: Count lines matching
error TSin output. - biome/eslint/ruff: Count lines matching error/warning patterns. Parse the summary line if available.
- Tests: Parse pass/fail counts from the test runner output. If the runner only reports exit code, use: exit 0 = 10, any other non-zero exit except 126/127 = 4 (assume some failures).
- knip: Count lines reporting unused exports, files, or dependencies.
- shellcheck: Count distinct findings (lines starting with "In ... line").
Composite score: compute it in code, never by hand. Pass every category once as
name=<score>, where the score is an integer 0-10, null for SKIPPED, or error
for a capture ERROR. Skipped weight is redistributed proportionally among the
scored categories; the weights are typecheck 25%, lint 20%, test 30%, deadcode 15%,
shell 10%.
python3 -I -c '
import sys
w = {"typecheck": 0.25, "lint": 0.20, "test": 0.30, "deadcode": 0.15, "shell": 0.10}
s = {}
for a in sys.argv[1:]:
k, sep, v = a.partition("=")
if not sep or k not in w or k in s:
sys.exit("bad argument: " + a)
if v not in ("null", "error") and not (v.isdigit() and int(v) <= 10):
sys.exit("bad score for " + k + ": " + v)
s[k] = v
if set(s) != set(w):
sys.exit("pass every category: " + " ".join(w))
scored = [k for k in w if s[k] not in ("null", "error")]
errors = [k for k in w if s[k] == "error"]
print("CHECKED: " + (" ".join(scored) or "none"))
print("UNAVAILABLE: " + (" ".join(k for k in w if s[k] == "null") or "none"))
print("COVERAGE: %d/%d" % (len(scored), len(w)))
if errors:
print("COMPOSITE: N/A - capture failed (" + " ".join(errors) + ")")
elif not scored:
print("COMPOSITE: N/A - no checks ran")
else:
c = sum(int(s[k]) * w[k] for k in scored) / sum(w[k] for k in scored)
print("COMPOSITE: %.1f" % c + ("" if len(scored) == len(w) else " (partial coverage)"))
' typecheck=10 lint=8 test=10 deadcode=7 shell=nullReplace the example values with this run's results. Report the COMPOSITE line as
printed; a numeric composite exists only when it prints a number.
Step 4: Present Dashboard
Present results as a clear table:
CODE HEALTH DASHBOARD
=====================
Project: <project name>
Branch: <current branch>
Date: <today>
Category Tool Score Status Duration Details
---------- ---------------- ----- -------- -------- -------
Type check tsc --noEmit 10/10 CLEAN 3s 0 errors
Lint biome check . 8/10 WARNING 2s 3 warnings
Tests bun test 10/10 CLEAN 12s 47/47 passed
Dead code knip 7/10 WARNING 5s 4 unused exports
Shell lint shellcheck 10/10 CLEAN 1s 0 issues
COMPOSITE SCORE: 9.2 / 10
Coverage: 5/5 categories checked
Checked: typecheck, lint, test, deadcode, shell
Unavailable: none
Duration: 23s total
VERDICT: NOT READY (lint, deadcode exited non-zero)Use these status labels:
- 10:
CLEAN - 7-9:
WARNING - 4-6:
NEEDS WORK - 0-3:
CRITICAL - Command could not run (exit 126/127):
FAILED(scores 0) - Tool not available:
SKIPPED(no score) - Capture broke:
ERROR(no score; composite is N/A)
Verdict line. End the dashboard with one of:
VERDICT: READYonly when every required check ran and exited 0 and all five categories were checked. The required checks are every## Health Stackentry, or every detected tool when the stack was auto-detected.VERDICT: NOT READYwhen every required check ran and at least one exited non-zero.VERDICT: INCOMPLETEwhen any required check was SKIPPED, FAILED or ERROR, or fewer than five categories were checked. Name each missing one. A high composite does not change this: neverREADYwith partial coverage.
Always show the coverage lines. With skipped categories, label the score
— partial coverage (e.g. COMPOSITE SCORE: 8.0 / 10 — partial coverage,
Coverage: 2/5 categories checked) and list each unavailable category with the
reason from its Step 1 MISSING: line (or its SKIPPED reason), e.g.
Unavailable: deadcode (knip neither on PATH nor in package.json). When no check ran, show COMPOSITE SCORE: N/A — no checks ran and say which
tools need installing or configuring; never show 10/10 for an empty run.
If any category scored below 7, list the top issues from that tool's output:
DETAILS: Lint (3 warnings)
biome check . output:
src/utils.ts:42 — lint/complexity/noForEach: Prefer for...of
src/api.ts:18 — lint/style/useConst: Use const instead of let
src/api.ts:55 — lint/suspicious/noExplicitAny: Unexpected anyStep 5: Persist to Health History
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" && mkdir -p "${VIBESTACK_HOME:-$HOME/.vibestack}/projects/$SLUG"
echo "PROJECT_DIR: ${VIBESTACK_HOME:-$HOME/.vibestack}/projects/$SLUG"Only when the composite is numeric, append one JSONL line to
<PROJECT_DIR>/health-history.jsonl (where <PROJECT_DIR> is the path the block above printed on its PROJECT_DIR: line). A run with no checks or a capture
ERROR writes nothing and leaves the existing history as it is:
{"ts":"2026-03-31T14:30:00Z","branch":"main","score":9.2,"typecheck":10,"lint":8,"test":10,"deadcode":7,"shell":10,"duration_s":23}Fields:
ts-- ISO 8601 timestampbranch-- current git branchscore-- composite score (one decimal)typecheck,lint,test,deadcode,shell-- individual category scores (integer 0-10)duration_s-- total time for all tools in seconds
If a category was skipped, set its value to null.
Step 6: Trend Analysis + Recommendations
Read the last 10 entries from <PROJECT_DIR>/health-history.jsonl (if the
file exists and has prior entries).
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" && mkdir -p "${VIBESTACK_HOME:-$HOME/.vibestack}/projects/$SLUG"
tail -10 "${VIBESTACK_HOME:-$HOME/.vibestack}/projects/$SLUG/health-history.jsonl" 2>/dev/null || echo "NO_HISTORY"Compare like-for-like coverage only. For each history row, the scored set is the
categories with a non-null value (a missing field counts as null). Report a delta,
IMPROVING or REGRESSIONS DETECTED only against rows whose scored set equals this
run's exactly. If the previous run's set differs, say Coverage changed — scores are
not comparable and label nothing an improvement or a regression; older rows may
still be listed with their unavailable categories marked. An N/A run has no trend.
If comparable prior entries exist, show the trend:
HEALTH TREND (last 5 runs)
==========================
Date Branch Score TC Lint Test Dead Shell
---------- ----------- ----- -- ---- ---- ---- -----
2026-03-28 main 9.4 10 9 10 8 10
2026-03-29 feat/auth 8.8 10 7 10 7 10
2026-03-30 feat/auth 8.2 10 6 9 7 10
2026-03-31 feat/auth 9.2 10 8 10 7 10
Trend: IMPROVING (+1.0 since last run)If score dropped vs the previous run with identical coverage:
- Identify WHICH categories declined
- Show the delta for each declining category
- Correlate with tool output -- what specific errors/warnings appeared?
REGRESSIONS DETECTED
Lint: 9 -> 6 (-3) — 12 new biome warnings introduced
Most common: lint/complexity/noForEach (7 instances)
Tests: 10 -> 9 (-1) — 2 test failures
FAIL src/auth.test.ts > should validate token expiry
FAIL src/auth.test.ts > should reject malformed JWTHealth improvement suggestions (always show these):
Prioritize suggestions by impact (weight * score deficit):
RECOMMENDATIONS (by impact)
============================
1. [HIGH] Fix 2 failing tests (Tests: 9/10, weight 30%)
Run: bun test --verbose to see failures
2. [MED] Address 12 lint warnings (Lint: 6/10, weight 20%)
Run: biome check . --write to auto-fix
3. [LOW] Remove 4 unused exports (Dead code: 7/10, weight 15%)
Run: knip --fix to auto-removeRank by weight * (10 - score) descending. Only show categories below 10.
Mode: --fix
/health --fix runs the checks Step 1 found, fixes the source until they pass, and
proves the result from the evidence ledger. It writes no score and no history row.
Checks. Run Step 1 (a ## Health Stack section, or auto-detection). Each
detected command is one check, labelled by its category (typecheck, lint,
test, deadcode, shell; lint-2 for a second command in one category). With
no check at all, print CHECKS: none and stop: there is nothing to make green,
and saying it passed would be a lie.
Consent. The commands come from the repo and run its code. Interactive: print
every command, and before the first run in a repo with no earlier health record
("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-evidence" read --skill health --limit 1
prints no evidence recorded) ask with AskUserQuestion: A) run them, B) stop.
SESSION_KIND: spawned or headless: run only when invoked as /health --fix --yes;
otherwise print FIX: needs --yes in a spawned or headless session and stop.
Run the checks. One block per run; one fix_check line per check, with its
label and its exact command as ONE single-quoted string:
_EV=${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-evidence
_FIX_LOG=$(mktemp -d "${TMPDIR:-/tmp}/vibe-health-fix-XXXXXXXX") || { echo "FIX: cannot create a log directory"; exit 125; }
fix_check() {
"$_EV" run --skill health --label "${1}" -- "${2}" > "$_FIX_LOG/${1}.txt" 2>&1
_rc=$?
printf 'CHECK: %s exit=%s log=%s\n' "${1}" "$_rc" "$_FIX_LOG/${1}.txt"
if [ "$_rc" -ne 0 ]; then tail -50 "$_FIX_LOG/${1}.txt"; fi
}
fix_check '<check>' '<command>'If a log says vibe-evidence itself was not found, stop: this mode proves its
result from the ledger, and without it there is nothing to prove.
Rules for every run:
- Only exit 0 is green. Any other
exit=, a missing line or "mostly passed" is red, whatever the log says. - Pre-existing means red on the first run this session, before any edit. A check that turns red after your edit is yours, including a test you never touched that your changed source now breaks.
- ENV, TIMEOUT or a missing secret is reported with the log line that shows it. Never stub, mock or skip around it.
- Never edit a test, a checker config or a script (
package.jsonscripts, lint rules, CI files,## Health Stack) to get green. Fix the source the check exercises; a wrong test is reported, not rewritten. - Stop after 5 runs, or on the same failure twice after an attempted fix. Report what is still red and hand it to
/investigate.
Finish from the ledger. Do not re-run anything; ask the ledger whether each
check's exact command passed at the tree as it is now. One fix_ready line per
check, same label and command as the last run:
_EV=${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-evidence
TREE_NOW=$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-tree-hash" 2>/dev/null || echo unknown)
_fix_bad=""
fix_ready() { "$_EV" check --skill health --label "${1}" --expect-cmd "${2}" || _fix_bad="$_fix_bad ${1}"; }
fix_ready '<check>' '<command>'
if [ -z "$_fix_bad" ]; then echo "READY at tree $TREE_NOW"; else echo "NOT READY:$_fix_bad"; fiReport the READY or NOT READY line as printed, with each check's FRESH or
STALE line, the pre-existing failures, and the files you changed. An edit after
the last run makes it NOT READY: run the checks again rather than claiming it.
Target: skills
/health skills reports on the installed skills instead of the codebase: how often
each one is used, what its description costs every session, and what to do about it.
Both tools are read-only.
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-skill-usage" --days 90
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-context-budget" --runtime claude --rendered "$HOME/.claude/skills" --config-dir "" --top 0 --warn-onlyvibe-skill-usage counts typed (the user typed /<name>) and model (the model
called the skill) from Claude Code transcripts, nested for the share found in
subagent transcripts, and tracked from the slash-command analytics file. Typed and
tracked overlap — never add them. vibe-context-budget gives each skill's
description length (--top 0 lists every skill; --config-dir "" skips the repo
config payload, which an installed copy does not have).
Present one row per installed skill:
SKILL HEALTH (last 90 days, claude measured; cursor, kiro, codex, copilot unmeasured)
Skill Typed Model Last seen Desc chars Proposal
-------------- ----- ----- ----------- ---------- ------------------------------
ship 12 30 2026-10-09 112 Keep — used weekly, both ways
diagram 0 0 - 140 Improve — never auto-invoked; description names no trigger phrase
old-helper 0 0 - 210 Retire — no use in 90 days on the one measured runtime and covered by /vibePropose exactly one of Keep, Improve, Retire or Merge into <skill>
per skill, with a reason a reader can check without this conversation (the counts,
the overlapping skill, the description problem).
Rules:
- Unmeasured is not zero. Usage on Cursor, Kiro, Codex or Copilot CLI, and in transcripts the tool could not read, is unmeasured, and unmeasured never justifies Retire. Say which runtimes the user works in before proposing Retire; a skill with zero Claude use may be in daily use elsewhere.
- Retire is a proposal. This target never deletes, moves or edits a skill. Point
to
/vibe-gcfor the removal itself. - Merge into names the surviving skill and what moves into it.
- Improve names the change: a description that never matches how users ask, a description long enough to dominate the budget, a trigger list that collides with another skill.
{{include lib/snippets/capture-learnings.md}}
The score itself belongs in health-history.jsonl, not here. What belongs here is what
you had to work out to produce it: a tool that needs a flag to be parseable, a category
whose count is misleading on this repo, a check that is slow enough to be worth skipping
on a quick pass.
Important Rules
- Wrap, don't replace. Run the project's own tools. Never substitute your own analysis for what the tool reports.
- Read-only outside
--fix. Never fix issues unless the user ran/health --fix. Present the dashboard and let the user decide. - Respect CLAUDE.md. If
## Health Stackis configured, use those exact commands. Do not second-guess. - Skipped is not failed. Skip only a tool whose absence was established before running, show coverage, and redistribute weight among scored categories only. A command that ran and failed — including exit 127 — is FAILED, never SKIPPED.
- Show raw output for failures. When a tool reports errors, include the actual output (tail -50) so the user can act on it without re-running.
- Trends require comparable history. On the first scored run, say "First health check -- no trend data yet. Run /health again after making changes to track progress." A changed coverage set or an N/A run has no score delta.
- Be honest about scores. A codebase with 100 type errors and all tests passing is not healthy. The composite score should reflect reality.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

