
Brewcode:Skills
- 20 installs
- 29 repo stars
- Updated August 2, 2026
- kochetkov-ma/claude-brewcode
Helps with ai & agent building tasks.
About
brewcode:skills is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- brewcode:skills
- AI & Agent Building
- AI-coding skill
Brewcode:Skills by the numbers
- 20 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #10,459 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kochetkov-ma/claude-brewcode --skill brewcodeskillsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 20 |
|---|---|
| repo stars | ★ 29 |
| Last updated | August 2, 2026 |
| Repository | kochetkov-ma/claude-brewcode ↗ |
What it does
Helps with ai & agent building tasks.
Files
skills Skill
Skill Management: List, improve, create skills with activation optimization.
<instructions>
Parse Arguments
Extract mode and target from $ARGUMENTS:
| Pattern | Mode | Target |
|---|---|---|
empty / list | list | none |
| `up <name\ | path\ | folder>` |
| `create <prompt\ | spec-path>` | create |
| `<path\ | name>` (not a mode) | up (default) |
Smart Detection: If first argument is NOT a mode keyword (list, up, create), treat entire input as target for up mode.
Examples:
/brewcode:skillsorlist→list/brewcode:skills up commit→up, target=commit/brewcode:skills create "semantic code search"→create, target=prompt/brewcode:skills commit→up, target=commit(shorthand)/brewcode:skills ~/.claude/skills/→up, target=folder (shorthand)
---
Mode: list
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/list-skills.sh" && echo "✅ list" || echo "❌ list FAILED"STOP if ❌ — verify skill base directory is resolved and scripts exist.
---
Mode: create / up (Unified Flow)
Both create and up follow Phases 0-6. Differences noted per phase.
Description Budget (DEFAULT)
Frontmatter description: <= 120 chars (optimal ~100), single line. What + when + 3-5 distinct triggers (comma-list). No filler, no <example> blocks. Some registries truncate long descriptions and dilute trigger matching. EN only unless user explicitly asks.
Prerequisite (up only): Resolve Target
EXECUTE using Bash tool:
TARGET="$ARGUMENTS"
if [[ "$TARGET" == up\ * ]] || [[ "$TARGET" == "up" ]]; then
TARGET="${TARGET#up }"; TARGET="${TARGET#up}"
fi
TARGET="$(echo "$TARGET" | xargs)"
if [[ -z "$TARGET" ]]; then
echo "❌ No target. Usage: /brewcode:skills up <name|path|folder>"; exit 1
fi
if [[ -d "$TARGET" ]]; then
echo "TYPE: folder"; echo "PATH: $TARGET"
find "$TARGET" -name "SKILL.md" -type f 2>/dev/null | head -20
elif [[ -f "$TARGET" ]]; then
echo "TYPE: file"; echo "PATH: $TARGET"
elif [[ -f "$TARGET/SKILL.md" ]]; then
echo "TYPE: skill-dir"; echo "PATH: $TARGET/SKILL.md"
else
echo "TYPE: name"; echo "NAME: $TARGET"
for loc in ~/.claude/skills .claude/skills; do
[[ -f "$loc/$TARGET/SKILL.md" ]] && echo "FOUND: $loc/$TARGET/SKILL.md"
done
fiSTOP if ❌ — target must resolve to at least one SKILL.md.
Phase 0: Discovery
Spawn 2-3 Explore agents in parallel (single message).
create mode — spawn in ONE message: 1. Explore: Research skill patterns in $BC_PLUGIN_ROOT/skills/ and ~/.claude/skills/ — structure, naming, frontmatter, references, scripts. 2. Explore: Analyze target project structure for {TOPIC} — code, APIs, configs, tooling. 3. (Optional) general-purpose: Web research for {TOPIC} — best practices, similar tools. Use WebSearch/WebFetch.
up mode — spawn in ONE message: 1. Explore: Analyze skill at {SKILL_PATH} — SKILL.md, references/, scripts/, tests/, README.md. Report quality and gaps. 2. Explore: Compare {SKILL_PATH} against patterns in $BC_PLUGIN_ROOT/skills/. Output improvement recommendations.
Phase 1: User Interaction
Step 1: Check Conversation History (create only) Check if current conversation already contains workflow to capture. If yes: extract tools, steps, corrections, I/O formats for Phase 2.
Step 2: Determine Input Type (create only)
| Input | Action |
|---|---|
Path to .md file | Read as spec |
| Text prompt | Use as research query |
Step 3: Invocation Type (AskUserQuestion)
header: "Invocation"
question: "Who will invoke this skill?"
options:
- label: "User only (slash command)"
description: "disable-model-invocation: true, simple description"
- label: "LLM auto-detect"
description: "Full trigger keyword optimization"
- label: "Both (default)"
description: "User slash command + LLM auto-detection"Save as INVOCATION_TYPE.
Step 4: Mode Switcher Detection (create only)
Keywords: "mode", "toggle", "switch", "persistent", "from now on", "always do", "session behavior"
If detected — AskUserQuestion: "Create as Mode Switcher skill?" (Yes/No). If Yes: set IS_MODE_SWITCHER=true, then ask scope (Project/Global/Session) via AskUserQuestion, save as MODE_SCOPE.
Validate BC_PLUGIN_DATA: EXECUTE using Bash tool:
if [ -n "$BC_PLUGIN_DATA" ]; then echo "✅ BC_PLUGIN_DATA=$BC_PLUGIN_DATA"; else echo "❌ BC_PLUGIN_DATA not set"; fiSTOP if ❌ — BC_PLUGIN_DATA required for Mode Switcher.
Step 5: Testing Depth (AskUserQuestion)
header: "Testing Depth"
question: "How thoroughly should the skill be tested?"
options:
- label: "Quick (default)" — validate-skill.sh + 3-5 test prompts
- label: "Standard" — + unit tests + simple review (1 reviewer + verification)
- label: "Deep" — + quorum review (3 reviewers, threshold 2) + E2E testsSave as TESTING_DEPTH.
Step 6: Review Type (AskUserQuestion, only if Standard or Deep)
header: "Review Type"
question: "What review approach?"
options:
- label: "Simple (default for Standard)" — 1 reviewer + 1 verification agent
- label: "Quorum (default for Deep)" — 3 reviewers parallel, threshold 2/3, DoubleCheckSave as REVIEW_TYPE.
Step 7: Plan Confirmation (AskUserQuestion)
Output plan summary: Action (Create/Improve), skill path/name, files to create/modify, references used, testing approach, review type.
header: "Plan Confirmation"
question: "Proceed with this plan?"
options: [Proceed, Adjust ("Let me change something"), Cancel]If Adjust — ask what to change, update, re-confirm. If Cancel — stop.
Phase 2: Create/Improve (skill-creator agent)
Task(subagent_type="brewcode:skill-creator", model="opus", prompt=" {ACTION} skill based on research and user preferences. Action: {create|improve} Topic/Skill: {TOPIC or SKILL_PATH} Invocation type: {INVOCATION_TYPE}
Discovery Results
{EXPLORE_RESULTS}
Requirements
- Follow skill-creator best practices
- Generate unit tests for scripts/ (Step 5.7)
- Generate README.md (Step 5.8)
- Invocation type pre-filled: {INVOCATION_TYPE} — skip asking
")
Mode Switcher additions (if IS_MODE_SWITCHER=true) — append:
- Single skill with argument parsing: on [mode-name], off, status
- State in
$BC_PLUGIN_DATA/modes.json— structure:.global,.projects["$PWD"],.sessions["$SESSION_ID"] - Scope:
{MODE_SCOPE}, resolution priority: session > project > global disable-model-invocation: true, mode instructions inreferences/- Bash MUST validate:
if [ -z "$BC_PLUGIN_DATA" ]; then echo "❌"; exit 1; fi
After creation (if Mode Switcher): AskUserQuestion — create mode file in brewcode/modes/? If yes: spawn brewcode:hook-creator.
Folder target (multiple skills): spawn parallel agents in ONE message, one per SKILL.md found.
Phase 3: Validate (automatic)
Skill-creator Steps 5-5.8 run automatically (validate, unit tests, README). No orchestrator action needed.
Phase 4: Review
Skip if `TESTING_DEPTH` is Quick.
Read review prompt: ${CLAUDE_SKILL_DIR}/references/review-prompt.md
Simple Review (`REVIEW_TYPE` = Simple):
1. Task(subagent_type="brewcode:reviewer", model="opus", prompt="Review skill quality at: {SKILL_PATH}\n\n{REVIEW_PROMPT_CONTENT}") 2. If findings: Task(subagent_type="brewcode:reviewer", model="sonnet", prompt="Verify these review findings against actual code...\n\n{REVIEWER_FINDINGS}") 3. Confirmed findings: Task(subagent_type="brewcode:skill-creator", model="opus", prompt="Fix verified issues in skill at: {SKILL_PATH}\n\n{CONFIRMED_FINDINGS}")
Quorum Review (`REVIEW_TYPE` = Quorum):
1. Three in parallel (ONE message): Task(subagent_type="brewcode:reviewer", model="opus", prompt="Review skill quality at: {SKILL_PATH}\n\n{REVIEW_PROMPT_CONTENT}") Task(subagent_type="brewcode:reviewer", model="opus", prompt="Review skill quality at: {SKILL_PATH}\n\n{REVIEW_PROMPT_CONTENT}") Task(subagent_type="brewcode:reviewer", model="opus", prompt="Review skill quality at: {SKILL_PATH}\n\n{REVIEW_PROMPT_CONTENT}") 2. Quorum: same file + +-5 lines + same category = threshold 2/3 agree. 3. Task(subagent_type="brewcode:reviewer", model="opus", prompt="DoubleCheck: verify quorum findings against code.\n\n{QUORUM_FINDINGS}") 4. Confirmed: Task(subagent_type="brewcode:skill-creator", model="opus", prompt="Fix verified issues...\n\n{CONFIRMED_FINDINGS}")
Collect findings: After Phase 4 completes, compile all confirmed findings (source, severity, issue, fix applied, verified status) into a structured list. Pass to Phase 6 for summary.
Phase 5: E2E Testing (Optional)
Only if `TESTING_DEPTH` is Deep. Otherwise skip.
1. Read: ${CLAUDE_SKILL_DIR}/references/e2e-template.md 2. Create test scenarios in {SKILL_DIR}/tests/ — 1 per mode (happy path) + 1 edge case per mode. 3. Execute each scenario:
EXECUTE using Bash tool:
TMPDIR=$(mktemp -d)
mkdir -p "$TMPDIR/.claude/skills"
cp -r "{SKILL_DIR}" "$TMPDIR/.claude/skills/"
cd "$TMPDIR" && timeout 120 claude -p "{PROMPT}" 2>&1 | tee "$TMPDIR/output.log"
{ASSERTION_COMMANDS}
rm -rf "$TMPDIR"4. Iteration: scenario failure = fix (max 2 retries). Small skill issues = fix + re-run. Major issues = back to Phase 2.
Phase 6: Summary
Read: ${CLAUDE_SKILL_DIR}/references/summary-template.md
Fill: action, path, invocation type, testing depth, review type, completed phases checklist, problems found/fixed (Phase 4), test results (Phase 3 + 5), suggestions, skipped phases with reasons.
Output filled summary to user.
</instructions>
---
Output Format
Forlistmode only. Forcreate/upmodes, Phase 6 summary replaces this section.
# skills [list]
## Detection
| Field | Value |
|-------|-------|
| Arguments | `$ARGUMENTS` |
| Mode | `list` |
| Target | `none` |
## Skills Summary
| Location | Count | Skills |
|----------|-------|--------|
| Global (~/.claude/skills/) | N | skill1, skill2 |
| Project (.claude/skills/) | N | skill3 |
| Plugins | N | plugin:skill1 |
## Next Steps
- [recommendations based on results]MIT License
Copyright (c) 2025-2026 Maxim Kochetkov (kochetkov-ma)
https://github.com/kochetkov-ma/claude-brewcode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Skills
Manage Claude Code skills -- list installed skills, improve existing ones via the skill-creator agent, or create new skills from a prompt or spec file with research-driven generation.
Quick Start
/brewcode:skillsLists all available skills across global, project, and plugin locations.
Modes
| Mode | How to trigger | What it does |
|---|---|---|
list | /brewcode:skills or /brewcode:skills list | Lists all skills grouped by location (global, project, plugin) |
up | `/brewcode:skills up <name\ | path\ |
up (shorthand) | `/brewcode:skills <name\ | path\ |
create | /brewcode:skills create <prompt> | Researches the topic (codebase + web), then creates a new skill |
create (from spec) | /brewcode:skills create ./spec.md | Reads the spec file and creates a skill based on its contents |
Examples
Good Usage
# List everything installed
/brewcode:skills list
# Improve a skill by name (searches global and project locations)
/brewcode:skills up commit
# Shorthand -- same as above, "up" is implied
/brewcode:skills commit
# Improve a skill by explicit path
/brewcode:skills up ~/.claude/skills/commit/SKILL.md
# Shorthand with path
/brewcode:skills brewcode/skills/setup
# Improve all skills in a folder (parallel agents)
/brewcode:skills ~/.claude/skills/
# Create a brand new skill from a prompt
/brewcode:skills create "semantic code search"
# Create a skill from a spec file
/brewcode:skills create ./my-skill-spec.mdCommon Mistakes
| Mistake | Why it fails | Correct |
|---|---|---|
/brewcode:skills up (no target) | up mode requires a skill name, path, or folder | /brewcode:skills up commit |
/brewcode:skills create (no prompt) | create mode requires a prompt or spec file path | /brewcode:skills create "my new skill" |
/brewcode:skills up list | Interprets list as a skill name to improve, not the list mode | /brewcode:skills list |
Output
Depends on mode:
- list -- a summary table of all skills grouped by location (global
~/.claude/skills/, project.claude/skills/, plugins). - up -- the skill-creator agent rewrites the target SKILL.md with optimized description, trigger keywords, imperative voice, and best practices. For folders, multiple agents run in parallel.
- create -- a new skill directory containing
SKILL.mdandREADME.md, placed in.claude/skills/(project) or~/.claude/skills/(global). Before creation you are asked whether the skill should be user-invocable, LLM auto-detected, or both.
Mode Switcher
The create mode can generate Mode Switcher skills — special skills that toggle persistent behavioral modes for the entire Claude Code session.
What is a Mode Switcher?
A mode switcher is a skill that changes how Claude behaves for the rest of the session. For example, "manager mode" makes Claude delegate all tasks via agents, "researcher mode" makes Claude prioritize depth and source verification.
How it works
/brewcode:skills create "toggle research mode"
↓
Step 2.5 detects "mode/toggle" keywords
↓
Asks: "Create as a Mode Switcher skill?"
↓ Yes
skill-creator uses Mode Switcher pattern
↓
Creates skill with on/off/status arguments
↓
Skill writes state → hooks inject instructionsFlow
Skill writes {"mode":"research"} → $CLAUDE_PLUGIN_DATA/modes.json
↓
forced-eval.mjs → injects [MODE: research] into every user prompt
session-start.mjs → injects mode into session context (survives compact)
pre-task.mjs → injects mode into every sub-agent promptExample
# Create a mode switcher skill
/brewcode:skills create "toggle deep research mode that prioritizes source verification"
# The created skill will support:
/my-mode on research # activate mode
/my-mode off # deactivate
/my-mode status # show current modeCreating a mode manually
1. Create mode instructions file: brewcode/modes/{name}.md (plain text) 2. Activate:
MODES="$BC_PLUGIN_DATA/modes.json"
[ ! -f "$MODES" ] && echo '{}' > "$MODES"
jq --arg m "research" --arg p "$PWD" --arg t "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
'.projects[$p] = {mode: $m, activatedAt: $t}' "$MODES" > "$MODES.tmp" && mv "$MODES.tmp" "$MODES"3. Deactivate:
MODES="$BC_PLUGIN_DATA/modes.json"
jq --arg p "$PWD" 'del(.projects[$p])' "$MODES" > "$MODES.tmp" && mv "$MODES.tmp" "$MODES"Legacy fallback:.claude/tasks/cfg/brewcode.state.json(flatmodefield) is still supported but deprecated.
Hooks pick up the change automatically — no code modifications needed.
Tips
- Use the shorthand form (
/brewcode:skills commit) for quick improvements -- no need to typeupexplicitly. - Point at a folder (
/brewcode:skills ~/.claude/skills/) to batch-improve every skill inside it. Each skill gets its own parallel agent. - The
createmode checks conversation history first. If the current conversation already contains a workflow worth capturing, it extracts context directly and skips web research. - After creating a skill, you are offered an optional eval step that runs three test prompts to verify the skill activates correctly.
Documentation
Full docs: skills
E2E Test Scenario Template
Template for skill E2E tests executed via claude -p from bash.
---
Scenario Structure
# E2E: {SKILL_NAME} -- {MODE} -- {VARIANT}
## Setup
- Skill path: {SKILL_PATH}
- Mode: {MODE} (e.g., create, up, list)
- Variant: happy-path | edge-case | error-handling
## Prompt
> The exact prompt to send to claude -p
## Expected Behavior
- [ ] Skill triggers (slash command recognized)
- [ ] Expected files created/modified
- [ ] Expected output contains key phrases
- [ ] No errors in stderr
## Assertions
| # | Check | Command | Expected |
|---|-------|---------|----------|
| 1 | File exists | `test -f path` | exit 0 |
| 2 | Content match | `grep -q "pattern" file` | exit 0 |
| 3 | Line count | `wc -l < file` | 10..500 |
| 4 | No errors | `! grep -qi "error" output.log` | exit 0 |---
Execution Methods
Method A -- Isolated (preferred for CI):
TMP=$(mktemp -d)
mkdir -p "$TMP/.claude/skills"
cp -r "$SKILL_PATH" "$TMP/.claude/skills/"
cd "$TMP" && timeout 120 claude -p "{prompt}" 2>&1 | tee "$TMP/output.log"
EXIT_CODE=$?
# run assertions against $TMP/output.log and generated files
rm -rf "$TMP"Method B -- In-session (installed plugin):
timeout 120 claude -p '/brewcode:skills create name="my-skill"' 2>&1 | tee output.logCapture and timeout:
timeout 120 claude -p "..." 2>&1 | tee output.log
echo "EXIT: $?"---
Assertion Patterns
File exists:
test -f "$FILE" && echo "PASS" || echo "FAIL: $FILE not found"Content contains pattern:
grep -q "$PATTERN" "$FILE" && echo "PASS" || echo "FAIL: pattern '$PATTERN' not in $FILE"Line count in range:
lines=$(wc -l < "$FILE")
[ "$lines" -ge 10 ] && [ "$lines" -le 500 ] && echo "PASS" || echo "FAIL: $lines lines (expected 10..500)"YAML frontmatter present:
head -1 "$FILE" | grep -q "^---" && echo "PASS" || echo "FAIL: no YAML frontmatter"No errors in output:
! grep -qi "error\|fail\|exception" output.log && echo "PASS" || echo "FAIL: errors found in output"Exit code check:
[ "$EXIT_CODE" -eq 0 ] && echo "PASS" || echo "FAIL: exit code $EXIT_CODE"Aggregate result:
RESULTS="$TMP/results.txt"
# ... each assertion appends PASS/FAIL to $RESULTS ...
FAILS=$(grep -c "FAIL" "$RESULTS")
echo "Total: $(wc -l < "$RESULTS") | Failed: $FAILS"
[ "$FAILS" -eq 0 ] && echo "E2E PASSED" || echo "E2E FAILED"---
Iteration Rules
| Rule | Action |
|---|---|
| Scenario fails | Fix scenario first (not skill) unless skill is clearly broken |
| Max retries | 2 retry cycles per scenario |
| Small skill fix | Fix skill -> re-run E2E immediately |
| Major skill issue | Return to Phase 2 (full improvement cycle) |
| Flaky result | Add sleep 2 or increase timeout, retry once before marking FAIL |
README Template for Claude Code Skills
Instructions for skill-creator agent:
- Replace all {PLACEHOLDERS} with actual values from the skill being documented- Remove sections that don't apply (e.g., Modes for single-mode skills, Arguments if none)
- Keep README under 100 lines
- Use actual examples from the skill, not generic ones
- Files section: only list directories/files that actually exist in the skill
- After generation, remove this instructions block entirely
---
Template
---
auto-sync: enabled
auto-sync-date: {TODAY}
auto-sync-type: skill
---
# {SKILL_NAME}
> {ONE_LINE_DESCRIPTION}
## Quick Start
`/{SKILL_NAME} {ARGUMENT_HINT}`
## Modes
| Mode | Usage | Description |
|------|-------|-------------|
| {MODE} | `/{SKILL_NAME} {MODE} {ARGS}` | {DESCRIPTION} |
> Omit this section if single-mode skill.
## Arguments
| Argument | Required | Description |
|----------|----------|-------------|
| {ARG} | {YES/NO} | {ARG_DESCRIPTION} |
## Examples
### {EXAMPLE_TITLE}
/{SKILL_NAME} {EXAMPLE_ARGS}
### {EXAMPLE_TITLE_2}
/{SKILL_NAME} {EXAMPLE_ARGS_2}
## Workflow
1. {STEP_1}
2. {STEP_2}
3. {STEP_3}
## Output
{DESCRIBE_WHAT_THE_SKILL_PRODUCES — files, reports, artifacts, console output}
## Files
| File | Purpose |
|------|---------|
| SKILL.md | Main skill definition |
| references/ | {REFERENCE_DESC} |
| scripts/ | {SCRIPTS_DESC} |
| tests/ | {TESTS_DESC} |Skill Quality Review
You are reviewing a skill for structural correctness, activation quality, and security.
Skill path: {SKILL_PATH}
Read the entire skill directory: SKILL.md, references/, scripts/, tests/, README.md.
---
Review Checklist
| # | Category | What to Check |
|---|---|---|
| 1 | Description | Single line, quoted, 150-250 chars, starts with action verb, no multiline `\ |
| 2 | Description (LLM) | If disable-model-invocation is NOT true: has Triggers - line with 3-5 keyword phrases |
| 3 | Frontmatter | Valid YAML, name is lowercase-hyphens and <=64 chars |
| 4 | Frontmatter flags | user-invocable, disable-model-invocation, allowed-tools, model all present and correct |
| 5 | Body size | <500 lines total in SKILL.md |
| 6 | Body tone | Imperative form ("Read the file", not "You should read the file") |
| 7 | Body instructions | WHY-based: each rule explains rationale or has a consequence ("STOP if...") |
| 8 | References exist | Every file referenced in SKILL.md exists on disk. Verify with ls or Glob |
| 9 | References loading | References loaded conditionally (per phase/mode), NOT all at once at top |
| 10 | References guard | Each reference load has: "If not found, STOP" or equivalent error handling |
| 11 | Scripts executable | All .sh files in scripts/ have chmod +x and execute without error |
| 12 | Scripts paths | Scripts use ${CLAUDE_SKILL_DIR} for own files, never hardcoded absolute paths |
| 13 | Scripts pattern | Every bash block ends with `&& echo "OK" \ |
| 14 | Tests exist | tests/ directory exists with test files for each script |
| 15 | Tests pass | All tests execute successfully, cover happy path + at least one error path |
| 16 | README exists | README.md present in skill directory |
| 17 | README quality | Has auto-sync frontmatter, Quick Start section, content matches actual skill behavior |
| 18 | Progressive L1 | Description acts as L1 (~100 words equivalent): enough to decide whether to invoke |
| 19 | Progressive L2 | Body acts as L2 (<500 lines): full instructions without needing references |
| 20 | Progressive L3 | References act as L3: loaded on demand per phase, not eagerly |
| 21 | Security: secrets | No hardcoded tokens, passwords, API keys, or credentials anywhere |
| 22 | Security: injection | No unescaped user input in bash blocks, no eval on external data |
---
Severity Definitions
| Severity | Meaning | Action |
|---|---|---|
| critical | Skill broken, security risk, or will not activate | Must fix before use |
| major | Significant quality issue, poor activation, missing required component | Should fix |
| minor | Suboptimal but functional | Fix when convenient |
| nit | Style preference, cosmetic | Optional |
---
Output Format
Report ALL findings in this exact format:
## Review: {SKILL_NAME}
### Summary
| Metric | Value |
|--------|-------|
| Total findings | N |
| Critical | N |
| Major | N |
| Minor | N |
| Nit | N |
| Verdict | PASS / PASS WITH ISSUES / FAIL |
Verdict rules: FAIL if any critical. PASS WITH ISSUES if any major. PASS otherwise.
### Findings
| # | Category | Severity | File | Line | Issue | Suggestion |
|---|----------|----------|------|------|-------|------------|
| 1 | Description | major | SKILL.md | 3 | Missing Triggers line | Add `Triggers - keyword1, keyword2, keyword3` |
| 2 | Scripts | critical | scripts/run.sh | 12 | Hardcoded /home/user path | Use `${CLAUDE_SKILL_DIR}` instead |---
Verification Requirement
Findings are NOT actionable until verified by a separate agent.
Each finding MUST include:
- Exact file path relative to skill directory
- Exact line number where the issue occurs
- Specific text or pattern that demonstrates the issue
The verification agent will cross-check every finding against the actual file content. Do NOT suggest fixes that you have not confirmed are applicable to the current file state.
---
Review Modes
This prompt is used in two modes by the orchestrator:
| Mode | Reviewers | Verification |
|---|---|---|
| Simple | 1 reviewer agent | 1 verification agent confirms findings |
| Quorum | 3 reviewer agents (parallel) | Quorum threshold 2/3, then 1 DoubleCheck agent verifies |
In quorum mode, each reviewer works independently. The orchestrator merges results and applies majority-rule filtering.
Summary Report Template for Skills Orchestrator (Phase 6)
Instructions for orchestrator:
- Fill all {PLACEHOLDERS} from collected data across phases- Remove empty sections (e.g., E2E Tests if Quick mode, Review if None)
- Checkboxes reflect actual phase completion:[x]done,[ ]skipped
- Problems table only includes confirmed and verified findings
- After generation, remove this instructions block entirely
---
Template
# Skill {ACTION}: {SKILL_NAME}
| Field | Value |
|-------|-------|
| Location | {SKILL_PATH} |
| Action | {ACTION} |
| Invocation | {INVOCATION_TYPE} |
| Testing Depth | {TESTING_DEPTH} |
| Review Type | {REVIEW_TYPE} |
| Model | {MODEL} |
## What Was Done
- [{DISCOVERY}] Discovery (Explore agents)
- [{INTERACTION}] User interaction (invocation, testing depth)
- [{CREATE}] {ACTION_VERB} (skill-creator)
- [{VALIDATE}] Validation (validate-skill.sh + checklists)
- [{UNIT}] Unit Tests (scripts/)
- [{README}] README generation
- [{REVIEW}] Review ({REVIEW_TYPE})
- [{E2E}] E2E Testing
## Problems Found and Fixed
| # | Source | Severity | Issue | Fix | Verified |
|---|--------|----------|-------|-----|----------|
| {N} | {PHASE_OR_AGENT} | {HIGH/MEDIUM/LOW} | {DESCRIPTION} | {WHAT_WAS_DONE} | {YES/NO} |
## Test Results
### Unit Tests
| Script | Tests | Passed | Failed |
|--------|-------|--------|--------|
| {SCRIPT_NAME} | {TOTAL} | {PASSED} | {FAILED} |
### E2E Tests
| Scenario | Mode | Variant | Status | Assertions | Details |
|----------|------|---------|--------|------------|---------|
| {SCENARIO} | {MODE} | {VARIANT} | {PASS/FAIL} | {COUNT} | {NOTES} |
## What Could Be Improved
- {SUGGESTION_1}
- {SUGGESTION_2}
## What Was NOT Done
- {SKIPPED_ITEM} -- Reason: {WHY}#!/bin/bash
# list-skills.sh — Scan and list all available Claude Code skills
# Usage: list-skills.sh
# Output: Markdown table of skills with scope, name, description, invocation
set -euo pipefail
# --- Configuration ---
GLOBAL_SKILLS="$HOME/.claude/skills"
PROJECT_SKILLS=".claude/skills"
PLUGIN_ROOT="${BC_PLUGIN_ROOT:-}"
# --- Functions ---
# Extract value from YAML frontmatter
# Usage: extract_frontmatter "field" "file"
extract_frontmatter() {
local field="$1"
local file="$2"
# Match field in frontmatter (between --- markers)
# Use grep with || true to avoid exit on no match
sed -n '/^---$/,/^---$/p' "$file" 2>/dev/null | grep -E "^${field}:" | head -1 | sed "s/^${field}:[[:space:]]*//" | tr -d '"' | tr -d "'" || true
}
# Get first non-empty line after frontmatter for description fallback
get_first_content_line() {
local file="$1"
# Skip frontmatter, get first non-empty line
# Use || true to avoid exit on no match
sed -n '/^---$/,/^---$/!p' "$file" 2>/dev/null | grep -v '^#' | grep -v '^$' | head -1 | sed 's/^[[:space:]]*//' || true
}
# Truncate string to max length with ellipsis
truncate() {
local str="$1"
local max="${2:-50}"
if [[ ${#str} -gt $max ]]; then
echo "${str:0:$((max-3))}..."
else
echo "$str"
fi
}
# Determine invocation type from frontmatter values
# Returns: "AI + user", "user-only", "AI-only"
get_invocation_type() {
local user_invocable="$1"
local disable_model="$2"
if [[ "$user_invocable" == "true" ]]; then
if [[ "$disable_model" == "true" ]]; then
echo "user-only"
else
echo "AI + user"
fi
else
echo "AI-only"
fi
}
# Process a single skill directory
# Usage: process_skill "scope" "skill_dir" "prefix"
process_skill() {
local scope="$1"
local skill_dir="$2"
local prefix="$3"
local skill_name
local skill_file=""
local description=""
local user_invocable=""
local disable_model=""
local invocation=""
# Skip if not a directory
[[ -d "$skill_dir" ]] || return 0
# Determine skill file (SKILL.md preferred, then README.md)
if [[ -f "$skill_dir/SKILL.md" ]]; then
skill_file="$skill_dir/SKILL.md"
elif [[ -f "$skill_dir/README.md" ]]; then
skill_file="$skill_dir/README.md"
fi
# Get skill name from frontmatter or folder name
local folder_name
folder_name=$(basename "$skill_dir")
if [[ -n "$skill_file" ]]; then
skill_name=$(extract_frontmatter "name" "$skill_file")
[[ -z "$skill_name" ]] && skill_name="$folder_name"
# Get description from frontmatter or first content line
description=$(extract_frontmatter "description" "$skill_file")
if [[ -z "$description" ]]; then
description=$(get_first_content_line "$skill_file")
fi
# Get invocation flags
user_invocable=$(extract_frontmatter "user-invocable" "$skill_file")
disable_model=$(extract_frontmatter "disable-model-invocation" "$skill_file")
else
skill_name="$folder_name"
description="(no description)"
fi
# Format skill name with prefix if provided (skip if name already contains prefix)
if [[ -n "$prefix" && ! "$skill_name" =~ ^"$prefix": ]]; then
skill_name="${prefix}:${skill_name}"
fi
# Truncate description
description=$(truncate "$description" 50)
# Determine invocation type
invocation=$(get_invocation_type "$user_invocable" "$disable_model")
# Output row (tab-separated for sorting)
echo -e "${scope}\t${skill_name}\t${description}\t${invocation}"
}
# Scan skills in a directory
# Usage: scan_skills "scope" "directory" "prefix"
scan_skills() {
local scope="$1"
local directory="$2"
local prefix="${3:-}"
[[ -d "$directory" ]] || return 0
for skill_dir in "$directory"/*/; do
[[ -d "$skill_dir" ]] || continue
process_skill "$scope" "$skill_dir" "$prefix"
done
}
# Scan plugin skills from cache directory
scan_plugin_skills() {
local plugins_cache=""
# Determine plugins cache root from BC_PLUGIN_ROOT
if [[ -n "$PLUGIN_ROOT" && -d "$PLUGIN_ROOT" ]]; then
# BC_PLUGIN_ROOT format: ~/.claude/plugins/cache/{repo}/{plugin}/{version}
# Go up to cache root: ../../..
plugins_cache=$(dirname "$(dirname "$(dirname "$PLUGIN_ROOT")")")
fi
[[ -d "$plugins_cache" ]] || return 0
# Scan all repos in cache
for repo_dir in "$plugins_cache"/*/; do
[[ -d "$repo_dir" ]] || continue
local repo_name
repo_name=$(basename "$repo_dir")
# Scan all plugins in repo
for plugin_dir in "$repo_dir"/*/; do
[[ -d "$plugin_dir" ]] || continue
local plugin_name
plugin_name=$(basename "$plugin_dir")
# Find latest version (highest version dir)
local latest_version=""
for version_dir in "$plugin_dir"/*/; do
[[ -d "$version_dir" ]] || continue
latest_version="$version_dir"
done
[[ -d "$latest_version" ]] || continue
# Scan skills in this plugin
local skills_dir="$latest_version/skills"
if [[ -d "$skills_dir" ]]; then
scan_skills "plugin" "$skills_dir" "$plugin_name"
fi
done
done
}
# --- Main ---
# Collect all skills
SKILLS=""
# 1. Global skills
if [[ -d "$GLOBAL_SKILLS" ]]; then
while IFS= read -r line; do
[[ -n "$line" ]] && SKILLS="${SKILLS}${line}"$'\n'
done < <(scan_skills "global" "$GLOBAL_SKILLS" "")
fi
# 2. Project skills
if [[ -d "$PROJECT_SKILLS" ]]; then
while IFS= read -r line; do
[[ -n "$line" ]] && SKILLS="${SKILLS}${line}"$'\n'
done < <(scan_skills "project" "$PROJECT_SKILLS" "")
fi
# 3. Plugin skills
while IFS= read -r line; do
[[ -n "$line" ]] && SKILLS="${SKILLS}${line}"$'\n'
done < <(scan_plugin_skills)
# Sort by scope order (global, plugin, project) then by name
# Custom sort: global=1, plugin=2, project=3
SORTED_SKILLS=$(echo -n "$SKILLS" | sed 's/^global/1_global/; s/^plugin/2_plugin/; s/^project/3_project/' | sort -t$'\t' -k1,1 -k2,2 | sed 's/^[0-9]_//')
# Output markdown table
echo "| Scope | Skill | Description | Invocation |"
echo "|-------|-------|-------------|------------|"
while IFS=$'\t' read -r scope skill desc invocation; do
[[ -z "$scope" ]] && continue
echo "| $scope | $skill | $desc | $invocation |"
done <<< "$SORTED_SKILLS"
echo ""
SKILL_COUNT=$(echo -n "$SKILLS" | grep -c '^' 2>/dev/null || echo 0)
echo "Total: $SKILL_COUNT skills found"
#!/bin/sh
# validate-skill.sh — Validate a Claude Code skill directory structure
# Usage: validate-skill.sh <skill-dir>
# Exit: 0 = all checks pass, 1 = any check fails
set -eu
SKILL_DIR="${1:-}"
if [ -z "$SKILL_DIR" ]; then
echo "Usage: validate-skill.sh <skill-dir>"
exit 1
fi
PASS=0
FAIL=0
check() {
if [ "$1" = "ok" ]; then
PASS=$((PASS + 1))
echo "✅ $2"
else
FAIL=$((FAIL + 1))
echo "❌ $2"
fi
}
# 1. No lowercase skill.md (ls -1 for exact case on case-insensitive FS)
if ls -1 "$SKILL_DIR" 2>/dev/null | grep -q '^skill\.md$'; then
check fail "skill.md found — must be SKILL.md (uppercase)"
else
check ok "No lowercase skill.md"
fi
# 2. SKILL.md exists
SKILL_FILE="$SKILL_DIR/SKILL.md"
if [ ! -f "$SKILL_FILE" ]; then
check fail "SKILL.md not found in $SKILL_DIR"
echo ""
echo "=== Result: $PASS passed, $FAIL failed ==="
exit 1
fi
check ok "SKILL.md exists"
# 3. Frontmatter delimiters (opening and closing ---)
FM_COUNT=$(grep -c '^---$' "$SKILL_FILE" 2>/dev/null || echo 0)
if [ "$FM_COUNT" -ge 2 ]; then
check ok "Frontmatter has opening and closing --- delimiters"
else
check fail "Frontmatter missing --- delimiters (found $FM_COUNT, need 2+)"
fi
# Extract frontmatter block (between first two --- lines)
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$SKILL_FILE" 2>/dev/null || true)
# 4. name field: present, kebab-case (with optional prefix:), max 64 chars
NAME=$(echo "$FRONTMATTER" | grep -E '^name:' | head -1 | sed 's/^name:[[:space:]]*//' | tr -d '"' | tr -d "'" || true)
if [ -z "$NAME" ]; then
check fail "name field missing in frontmatter"
elif [ ${#NAME} -gt 64 ]; then
check fail "name too long (${#NAME} chars, max 64)"
elif ! echo "$NAME" | grep -qE '^[a-z0-9][a-z0-9-]*(:[a-z0-9][a-z0-9-]*)?$'; then
check fail "name '$NAME' is not valid kebab-case (or prefix:kebab-case)"
else
check ok "name: '$NAME' (${#NAME} chars)"
fi
# 5. description field: present, max 1024 chars, not multiline (no | after description:)
DESC_LINE=$(echo "$FRONTMATTER" | grep -E '^description:' | head -1 || true)
if [ -z "$DESC_LINE" ]; then
check fail "description field missing in frontmatter"
else
# Check for multiline indicator (| or > after description:)
if echo "$DESC_LINE" | grep -qE '^description:[[:space:]]*[|>]'; then
check fail "description uses multiline syntax (| or >) — must be single line"
else
DESC=$(echo "$DESC_LINE" | sed 's/^description:[[:space:]]*//' | tr -d '"' | tr -d "'")
if [ ${#DESC} -gt 1024 ]; then
check fail "description too long (${#DESC} chars, max 1024)"
elif [ -z "$DESC" ]; then
check fail "description is empty"
else
check ok "description: ${#DESC} chars"
fi
fi
fi
# 6. Body (content after frontmatter) is non-empty
BODY=$(sed -n '/^---$/,/^---$/!p' "$SKILL_FILE" 2>/dev/null | grep -v '^$' || true)
if [ -z "$BODY" ]; then
check fail "Body content after frontmatter is empty"
else
BODY_LINES=$(echo "$BODY" | wc -l | tr -d ' ')
check ok "Body content present ($BODY_LINES non-empty lines)"
fi
# Summary
echo ""
echo "=== Result: $PASS passed, $FAIL failed ==="
[ "$FAIL" -eq 0 ] && exit 0 || exit 1