Best for
- Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better trigge…
clacky-ai/openclacky/lib/clacky/default_skills/skill-creator/SKILL.md
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
Decision brief
A skill for creating new skills and iteratively improving them.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/clacky-ai/openclacky --skill "lib/clacky/default_skills/skill-creator"Inspect the Agent Skill "skill-creator" from https://github.com/clacky-ai/openclacky/blob/faaa347a1fd5a855f8e205c379c4994e757b703c/lib/clacky/default_skills/skill-creator/SKILL.md at commit faaa347a1fd5a855f8e205c379c4994e757b703c. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
This skill supports two modes:
require 'net/http' require 'json' require 'fileutils'
Write evalmetadata.json for each test case:
Don't wait until all runs finish — draft quantitative assertions as you go and explain them to the user.
For each run, evaluate assertions against the outputs. Save results to grading.json in each run directory.
Permission review
The documentation includes network, browsing, or remote request actions.
task: "Create a skill to extract and summarize content from URLs. The skill should: 1) fetch the URL using terminal with curl, 2) parse the HTML to extract main text content, 3) generate a concise markdown summary. Expected input: URL strinThe documentation asks the agent to run terminal commands or scripts.
**Scripts** — prefer **Ruby** (`.rb` files); Clacky is Ruby-native. Run with `ruby path/to/script.rb`. Python is available but Ruby is the default choiceThe documentation asks the agent to run terminal commands or scripts.
Invoke from SKILL.md by referencing the script via the Supporting Files block — at runtime, the AI receives the full absolute path of every supporting file. Refer to it as `SKILL_DIR` in instructions so the AI substitutes the correct path fThe documentation asks the agent to create, modify, or delete local files.
### Step 1: For each test case, create the eval directory and run both variantsThe documentation asks the agent to create, modify, or delete local files.
Create `benchmark.json` in the iteration directory. List `with_skill` before `without_skill` for each eval:Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 92/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 1,160 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
A skill for creating new skills and iteratively improving them.
This skill supports two modes:
The full workflow with user interviews, test cases, and iteration cycles. Use when creating or refining skills manually.
At a high level, the process of creating a skill goes like this:
eval-viewer/generate_review.py to generate a static HTML viewer for the user to review results and leave feedbackYour job is to figure out where the user is in this process and jump in to help them progress through these stages. Maybe they say "I want to make a skill for X" — help narrow down the intent, write a draft, write test cases, evaluate, and repeat. Or maybe they already have a draft — go straight to the eval/iterate part.
Always be flexible. If the user says "skip the evals, just vibe with me", do that instead.
Trigger: When invoked with mode: "quick" in the task arguments.
Fast, opinionated skill creation without user interaction. This mode is used by the agent's self-evolution system to automatically create or improve skills.
Behavior:
~/.clacky/skills/auto-<name>-<timestamp>/ (or improve existing skill in place)Expected arguments when using quick mode:
task: Clear description of what to automate and how (be specific about workflow steps)mode: Must be set to "quick"suggested_name: (optional) Proposed skill identifier (lowercase, hyphens OK)Quick mode principles:
disable-model-invocation: false and user-invocable: trueExample invocation from the agent's self-evolution system:
invoke_skill(
skill_name: "skill-creator",
task: "Create a skill to extract and summarize content from URLs. The skill should: 1) fetch the URL using terminal with curl, 2) parse the HTML to extract main text content, 3) generate a concise markdown summary. Expected input: URL string. Expected output: markdown summary with title and key points.",
mode: "quick",
suggested_name: "url-summarizer"
)
This skill runs inside Clacky (openclacky). Key platform specifics:
~/.clacky/skills/<skill-name>/ — always create new skills here (global user skills, visible to Web UI and all sessions). To locate an existing skill, check these paths in order using glob or ls: (1) .clacky/skills/ — project-level skills, (2) ~/.clacky/skills/ — user-level skills. Built-in skills (shipped with the gem) are always available via invoke_skill by name — no file lookup needed. Never use find / or broad filesystem searches to locate skills..rb files); Clacky is Ruby-native. Run with ruby path/to/script.rb. Python is available but Ruby is the default choicepython3 — if Python scripts are needed (e.g., generate_review.py), use python3 explicitlyrun_loop.py, run_eval.py) work in Clacky — they use clacky agent --json to detect invoke_skill events. See the Description Optimization section for usagePay attention to context cues to understand how technical the user is. In general:
It's always OK to briefly explain a term if you're in doubt.
Start by understanding what the user wants. If the current conversation already shows a workflow they want to capture (tools used, sequence of steps, corrections made, input/output formats), extract answers from history first — the user may just need to fill gaps and confirm.
Ask about edge cases, input/output formats, example files, success criteria, and dependencies before writing test prompts. Come prepared with context to reduce burden on the user.
Components to fill in:
false (always include this)true to make the skill appear in the WebUI chatbox / command list. Always include this — without it, users cannot manually invoke the skill from the Clacky Web UI session chat.Clacky-specific: Every skill MUST include
disable-model-invocation: falseanduser-invocable: truein the YAML frontmatter, or it will be invisible in the WebUI/command list. The minimal valid frontmatter is:--- name: my-skill description: 'Your description here. Avoid colons followed by a space (like "wants to: do X") inside the description — they break YAML parsing and the skill will silently fail to load. Wrap the entire description in single quotes to be safe, or rephrase to avoid the colon pattern.' disable-model-invocation: false user-invocable: true ---YAML description gotcha: If the description contains
word: valuepatterns (colons followed by space), YAML treats them as key-value pairs and the frontmatter parse fails silently. Always wrap description values in single quotes. Avoid embedded double-quotes inside single-quoted strings (use rephrasing instead).
After writing SKILL.md — always validate and auto-fix: Run this immediately after creating or updating any skill file:
ruby SKILL_DIR/scripts/validate_skill_frontmatter.rb /path/to/new-skill/SKILL.mdThe script validates the YAML frontmatter and auto-fixes common issues (unquoted descriptions, multi-line block scalars with colons). If it prints
OK:— you're done. If it printsAuto-fixed and saved— it repaired the file automatically. If it printsERROR— manual fix required.
Skills are created at ~/.clacky/skills/<skill-name>/:
~/.clacky/skills/skill-name/
├── SKILL.md (required)
│ ├── YAML frontmatter (name, description required)
│ └── Markdown instructions
└── Bundled Resources (optional)
├── scripts/ - Executable code (prefer .rb Ruby scripts)
├── references/ - Docs loaded into context as needed
└── assets/ - Files used in output (templates, icons, fonts)
Skills use a three-level loading system:
Key patterns:
references/ files and add clear pointersDomain organization — When a skill supports multiple frameworks/domains, organize by variant:
my-skill/
├── SKILL.md (workflow + which reference to load)
└── references/
├── rails.md
├── django.md
└── express.md
When a skill needs to execute code — API calls, file processing, data transforms — bundle a Ruby script instead of writing inline shell commands. This is cleaner, reusable, and more maintainable.
Ruby script template:
#!/usr/bin/env ruby
# skill-name/scripts/do_something.rb
# Usage: ruby path/to/do_something.rb [args]
require 'net/http'
require 'json'
require 'fileutils'
# Read args
input = ARGV[0]
if input.nil? || input.strip.empty?
warn "Usage: ruby do_something.rb <input>"
exit 1
end
# ... logic ...
puts result # stdout is the output
Invoke from SKILL.md by referencing the script via the Supporting Files block — at runtime, the AI receives the full absolute path of every supporting file. Refer to it as SKILL_DIR in instructions so the AI substitutes the correct path from the Supporting Files list:
ruby "SKILL_DIR/scripts/do_something.rb" "argument"
Never hardcode paths like ~/.clacky/skills/my-skill/scripts/... — they break when the skill is installed at a different location. Never use find to locate scripts — the Supporting Files block always provides the correct absolute paths.
Ruby standard library covers most needs (net/http, json, fileutils, uri, time). No gems needed for basic API calls.
Skills must not contain malware, exploit code, or anything that could compromise security. A skill's contents should not surprise the user if described. Don't create misleading skills or skills designed for unauthorized access or data exfiltration.
Use the imperative form in instructions.
Defining output formats:
## Report structure
Use this exact template:
# [Title]
## Executive summary
## Key findings
## Recommendations
Examples pattern:
## Commit message format
**Example 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication
Explain why things are important rather than just issuing commands. Use theory of mind — make the skill general, not over-fitted to specific examples. Write a draft, then look at it with fresh eyes and improve it. If you find yourself writing ALWAYS or NEVER in all caps, that's a yellow flag — try to reframe as an explanation of why, so the agent understands the reasoning rather than just following a rule.
After writing the skill draft, come up with 2–3 realistic test prompts — the kind of thing a real user would actually say. Share them with the user for review, then run them.
Save test cases to evals/evals.json:
{
"skill_name": "example-skill",
"evals": [
{
"id": 1,
"prompt": "User's task prompt",
"expected_output": "Description of expected result",
"files": []
}
]
}
Don't write assertions yet — just the prompts. Add assertions in the next step.
See references/schemas.md for the full schema.
This is one continuous sequence — don't stop partway through.
Since Clacky has no subagents, run test cases serially in the current session. For each test case, simulate two runs:
Put results in <skill-name>-workspace/ as a sibling to the skill directory. Organize by iteration (iteration-1/, iteration-2/, etc.), and within that by test case (use descriptive names like eval-create-report, not eval-0).
<skill-name>-workspace/
└── iteration-1/
├── eval-<descriptive-name>/
│ ├── eval_metadata.json
│ ├── with_skill/
│ │ ├── outputs/ ← files produced
│ │ └── grading.json ← filled in later
│ └── without_skill/
│ ├── outputs/
│ └── grading.json
└── benchmark.json ← filled in after all evals
Write eval_metadata.json for each test case:
{
"eval_id": 1,
"eval_name": "descriptive-name",
"prompt": "The task prompt",
"assertions": []
}
Running a with_skill eval: Read the skill's SKILL.md fully, then execute the task as instructed by the skill — create files, run scripts, write outputs to with_skill/outputs/.
Running a without_skill eval: Execute the same task using only general knowledge. Write outputs to without_skill/outputs/. This is the baseline.
Don't wait until all runs finish — draft quantitative assertions as you go and explain them to the user.
Good assertions are objectively verifiable and descriptively named — someone glancing at the benchmark should immediately understand what each one checks. Subjective skills are better evaluated qualitatively; don't force assertions onto things that need human judgment.
Update eval_metadata.json with assertions once drafted. Also update evals/evals.json.
For each run, evaluate assertions against the outputs. Save results to grading.json in each run directory.
The grading.json format (exact field names matter for the viewer):
{
"eval_id": 1,
"configuration": "with_skill",
"expectations": [
{
"text": "The script uses absolute paths",
"passed": true,
"evidence": "Script uses $HOME/... throughout"
}
],
"pass_count": 1,
"total_count": 1,
"pass_rate": 1.0
}
For assertions that can be checked programmatically, write and run a Ruby script — it's faster and more reliable than eyeballing:
#!/usr/bin/env ruby
# Check assertion: output file contains expected content
output = File.read("with_skill/outputs/result.md")
puts output.include?("expected phrase") ? "PASS" : "FAIL"
Create benchmark.json in the iteration directory. List with_skill before without_skill for each eval:
{
"skill_name": "my-skill",
"iteration": 1,
"configurations": [
{
"name": "with_skill",
"label": "With skill",
"evals": [
{"eval_id": 1, "eval_name": "eval-name", "pass_rate": 1.0, "pass_count": 3, "total_count": 3}
],
"overall_pass_rate": 1.0,
"total_pass": 3,
"total_assertions": 3
},
{
"name": "without_skill",
"label": "Without skill (baseline)",
"evals": [
{"eval_id": 1, "eval_name": "eval-name", "pass_rate": 0.33, "pass_count": 1, "total_count": 3}
],
"overall_pass_rate": 0.33,
"total_pass": 1,
"total_assertions": 3
}
],
"delta": {
"pass_rate_improvement": 0.67,
"summary": "With skill: 100% | Without skill: 33% | Delta: +67pp"
},
"analyst_observations": [
"..."
]
}
Or run the aggregation script (from the skill-creator directory):
python3 -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>
Read the benchmark data and surface patterns the aggregate stats might hide. See agents/analyzer.md for what to look for — things like assertions that always pass regardless of skill (non-discriminating), high-variance evals, and time/effort tradeoffs.
Generate the viewer first. Get the outputs in front of the user before making any changes.
python3 <skill-creator-path>/eval-viewer/generate_review.py \
<workspace>/iteration-N \
--skill-name "my-skill" \
--benchmark <workspace>/iteration-N/benchmark.json \
--static /tmp/<skill-name>-review.html
open /tmp/<skill-name>-review.html
For iteration 2+, also pass --previous-workspace <workspace>/iteration-<N-1>.
Tell the user: "I've opened the results in your browser. 'Outputs' tab lets you click through each test case and leave feedback; 'Benchmark' shows the quantitative comparison. When you're done, come back and let me know."
Outputs tab: One test case at a time.
Benchmark tab: Pass rates, per-eval breakdowns, analyst observations.
Navigation: prev/next buttons or arrow keys. "Submit All Reviews" saves to feedback.json.
When the user says they're done, read feedback.json:
{
"reviews": [
{"run_id": "eval-0-with_skill", "feedback": "missing axis labels on chart", "timestamp": "..."},
{"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."}
],
"status": "complete"
}
Empty feedback = user was happy with that test case. Focus on cases with specific complaints.
This is the heart of the loop. You've run tests, the user reviewed results — now make the skill better.
Generalize from feedback. You're iterating on a few examples, but the skill will be used across thousands of different prompts. Avoid overfitting to specific examples. If there's a stubborn issue, try different metaphors or different approaches rather than adding more rigid rules.
Keep it lean. Remove things that aren't pulling their weight. Read the execution trace, not just the final output — if the skill is making the agent waste time on unproductive steps, cut those parts.
Explain the why. Try hard to explain why each instruction matters. Agents are smart — they perform better when they understand the reasoning rather than following rules blindly. If you find yourself writing ALWAYS or NEVER in all caps, reframe it as an explanation.
Look for repeated work. If every test case resulted in writing similar helper logic (e.g., an API call setup, a file parser), that's a signal to bundle a reusable Ruby script into scripts/ and tell the skill to use it.
iteration-<N+1>/ directory (with_skill and without_skill)--previous-workspace pointing at the previous iterationKeep going until:
For more rigorous comparison, read agents/comparator.md and agents/analyzer.md. Optional — the human review loop is usually sufficient.
The description field in SKILL.md frontmatter is the primary triggering mechanism. After creating or improving a skill, offer to optimize it.
Clacky note:
run_eval.pyandrun_loop.pyhave been adapted for Clacky. They useclacky agent --json(NDJSON streaming) to detectinvoke_skilltool calls targeting temp skills in~/.clacky/skills/. Queries run serially (single agent).improve_description.pycalls the LLM directly via OpenRouter using~/.clacky/config.ymlcredentials.
Step 1: Generate trigger eval queries
Create 20 eval queries — a mix of should-trigger and should-not-trigger. Save as JSON:
[
{"query": "the user prompt", "should_trigger": true},
{"query": "another prompt", "should_trigger": false}
]
Queries must be realistic — concrete, specific, with enough context that a real user would actually say them. Include file paths, personal context, column names, backstory. Use a mix of lengths and styles (casual, formal, typos, abbreviations). Focus on edge cases.
Bad: "Format this data", "Extract text from PDF", "Create a chart"
Good: "ok so my boss just sent me this xlsx file (its in downloads, called Q4 sales final FINAL v2.xlsx) and she wants me to add a column showing profit margin. Revenue is column C, costs in column D i think"
Should-trigger queries (8–10): Different phrasings of the same intent — some formal, some casual. Include cases where the user doesn't explicitly name the skill but clearly needs it. Uncommon use cases, and cases where this skill competes with another but should win.
Should-not-trigger queries (8–10): Near-misses — queries that share keywords but actually need something different. The negative cases should be genuinely tricky, not obviously irrelevant ("write a fibonacci function" as a negative for a PDF skill is too easy).
Step 2: Review with user
Use the HTML template in assets/eval_review.html:
__EVAL_DATA_PLACEHOLDER__ with the JSON array, __SKILL_NAME_PLACEHOLDER__ with the skill name, __SKILL_DESCRIPTION_PLACEHOLDER__ with the current description/tmp/eval_review_<skill-name>.html and open it~/Downloads/eval_set.jsonStep 3: Run automated optimization (recommended)
Use the scripts from the skill-creator scripts/ directory. Run from the skill-creator root:
# Single eval run — check current description pass rate
python3 -m scripts.run_eval \
--eval-set ~/Downloads/eval_set.json \
--skill-path ~/.clacky/skills/my-skill \
--verbose
# Full optimize loop — auto-improves description over N iterations
python3 -m scripts.run_loop \
--eval-set ~/Downloads/eval_set.json \
--skill-path ~/.clacky/skills/my-skill \
--max-iterations 5 \
--runs-per-query 1 \
--verbose
# Outputs: best description + HTML report (auto-opens in browser)
Notes:
--num-workers needed (or it's ignored) — Clacky runs queries serially--model needed — uses the model from ~/.clacky/config.yml automatically~/.clacky/skills/ and cleaned up after each queryclacky agent --json process to avoid session contaminationStep 3 (manual fallback)
If scripts fail, manually iterate: for each query in the eval set, judge whether the description would trigger. Tally passes/fails. Write improved description targeting failures. Repeat 2–3 times.
Focus on:
Step 4: Apply the result
Update the skill's SKILL.md frontmatter with the improved description. Show the user before/after.
Skills appear in Clacky's available_skills list. The agent consults a skill based on the description match — but only for tasks it can't handle alone. Simple, one-step queries often won't trigger even with a good description. Make eval queries substantive enough that the skill genuinely helps.
New skills are created directly in ~/.clacky/skills/<skill-name>/ — no packaging step needed. The skill is immediately available in all sessions and the Web UI.
If distributing externally, you can package it:
python3 -m scripts.package_skill <path/to/skill-folder>
This creates a .skill file. Direct the user to the resulting file path.
agents/grader.md — How to evaluate assertions against outputsagents/comparator.md — How to do blind A/B comparison between two outputsagents/analyzer.md — How to analyze why one version beat anotherreferences/schemas.md — JSON structures for evals.json, grading.json, benchmark.jsongenerate_review.py so the user can reviewAdd these steps to your todo list. Specifically: always generate the eval viewer before revising the skill — the user's feedback is the primary signal, not your own judgment of the outputs.
Alternatives
daymade/claude-code-skills
Create new skills, modify and improve existing skills, and measure skill performance. This daymade edition supersedes the official skill-creator plugin — when both appear in the skill list, always use this one. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy. Also use for its three specialized distillations, even
CherryHQ/cherry-studio
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
bytedance/deer-flow
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
notque/vexjoy-agent
Create and iteratively improve skills through eval-driven validation.