refactor(skills): make SKILL.md the required entry point
Standardize on Claude Code's SKILL.md format as every skill's source of truth. skill.toml becomes an optional metadata layer for runtime, input schema, and versioning — never for the prompt body. - validate.py: require SKILL.md in every skill dir; when skill.toml also exists, cross-check name/description consistency to prevent drift - Add SKILL.md to the two custom-skill examples - Move the meeting-agenda prompt body out of skill.toml into SKILL.md - Rewrite skills/README.md to document the md-first, toml-as-metadata convention Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
adf2323330
commit
6c0faf06ef
5 files changed
+122
-71
No files matched your search
+48
-40
@@ -1,29 +1,58 @@
|
||||
# Skills
|
||||
|
||||
Reusable skill definitions for LibreFang agents. Skills are either prompt templates or code scripts that agents can invoke to perform specific tasks.
|
||||
Reusable skill definitions for LibreFang agents. A skill is either a prompt
|
||||
template or a code script that an agent can invoke to perform a specific task.
|
||||
|
||||
## Structure
|
||||
## File Convention
|
||||
|
||||
Every skill directory **must** contain a `SKILL.md` (the entry point).
|
||||
A `skill.toml` is **optional** and only needed for structured metadata that
|
||||
does not fit in Markdown frontmatter (runtime, input schema, version, tags).
|
||||
|
||||
```
|
||||
skills/
|
||||
├── docker/
|
||||
│ └── SKILL.md # Prompt-only expert — no skill.toml needed
|
||||
├── custom-skill-prompt/
|
||||
│ └── skill.toml # Prompt-only skill
|
||||
│ ├── SKILL.md # Prompt body + name/description
|
||||
│ └── skill.toml # Runtime + input schema
|
||||
└── custom-skill-python/
|
||||
├── skill.toml # Skill manifest
|
||||
└── main.py # Python implementation
|
||||
├── SKILL.md # Overview (prompt body unused)
|
||||
├── skill.toml # Runtime = python, entry = main.py
|
||||
└── main.py
|
||||
```
|
||||
|
||||
## Skill Types
|
||||
### `SKILL.md` (required)
|
||||
|
||||
### Prompt-Only
|
||||
The source of truth for the skill's prompt and identity. Must start with YAML
|
||||
frontmatter containing at least `name` and `description`:
|
||||
|
||||
No code needed -- pure prompt engineering:
|
||||
```markdown
|
||||
---
|
||||
name: docker
|
||||
description: Docker expert for containers, Compose, and Dockerfiles.
|
||||
---
|
||||
|
||||
You are a Docker specialist. You help users build, run, debug, and optimize
|
||||
containers...
|
||||
```
|
||||
|
||||
This format is compatible with Claude Code skills, so a `SKILL.md` authored
|
||||
here can be dropped into other tools without modification.
|
||||
|
||||
### `skill.toml` (optional)
|
||||
|
||||
Add one only when you need to declare any of:
|
||||
|
||||
- `[runtime]` — `promptonly` / `python` / `node` / `shell` (default is `promptonly`)
|
||||
- `[input]` — typed input parameter schema
|
||||
- `version`, `author`, `tags` — structured metadata
|
||||
|
||||
```toml
|
||||
[skill]
|
||||
name = "meeting-agenda"
|
||||
version = "0.1.0"
|
||||
description = "Generate a structured meeting agenda"
|
||||
description = "Generate a structured meeting agenda from a topic and duration."
|
||||
tags = ["meeting", "productivity"]
|
||||
|
||||
[runtime]
|
||||
@@ -32,36 +61,14 @@ type = "promptonly"
|
||||
[input]
|
||||
topic = { type = "string", description = "The meeting topic", required = true }
|
||||
duration_minutes = { type = "string", description = "Duration in minutes", required = true }
|
||||
|
||||
[prompt]
|
||||
template = """
|
||||
Create a meeting agenda for:
|
||||
Topic: {{topic}}
|
||||
Duration: {{duration_minutes}} minutes
|
||||
"""
|
||||
```
|
||||
|
||||
### Python
|
||||
**Consistency rule:** if both files exist, `skill.name` and `skill.description`
|
||||
in `skill.toml` must match the `name` and `description` in `SKILL.md`'s
|
||||
frontmatter. The validator enforces this to prevent drift.
|
||||
|
||||
Custom logic with a Python entry point:
|
||||
|
||||
```toml
|
||||
[skill]
|
||||
name = "my-skill"
|
||||
version = "0.1.0"
|
||||
description = "Skill with custom logic"
|
||||
|
||||
[runtime]
|
||||
type = "python"
|
||||
entry = "main.py"
|
||||
|
||||
[input]
|
||||
data = { type = "string", description = "Input data", required = true }
|
||||
```
|
||||
|
||||
### Other Runtimes
|
||||
|
||||
Also supported: `node`, `shell`.
|
||||
**Do not duplicate the prompt body in TOML.** The prompt lives in `SKILL.md`;
|
||||
`skill.toml` is for metadata the prompt cannot express.
|
||||
|
||||
## Testing Skills Locally
|
||||
|
||||
@@ -72,9 +79,10 @@ librefang skill test ./skills/custom-skill-prompt \
|
||||
|
||||
## Adding a New Skill
|
||||
|
||||
1. Create `skills/<name>/skill.toml`
|
||||
2. Add implementation files if not `promptonly`
|
||||
3. Run `python scripts/validate.py`
|
||||
4. Submit a PR
|
||||
1. Create `skills/<name>/SKILL.md` with frontmatter (`name`, `description`) and the prompt body.
|
||||
2. If you need `[runtime]`, `[input]`, or structured metadata, add `skills/<name>/skill.toml`.
|
||||
3. Add implementation files (`main.py`, etc.) when `runtime` is not `promptonly`.
|
||||
4. Run `python scripts/validate.py`.
|
||||
5. Submit a PR.
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
Reference in new issue
Block a user