Skip to content

Commit c5c3a2a

Browse files
Add skill creation guidelines based on writing-skills (#70) (#74)
* Add skill creation guidelines based on writing-skills (#70) Integrate writing-skills guidelines into skern's skill create workflow: - Update DefaultBody() scaffold with recommended sections (Overview, When to Use, Core Pattern, Quick Reference, Common Mistakes) - Update default description to start with "Use when..." (CSO guideline) - Add lint hints for description trigger prefix and missing body sections - Add Writing Skills Guidelines section to AGENTS.md - Add docs/guide/writing-skills.md documentation page - Add comprehensive tests for new lint rules Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Refine writing-skills doc location and validator heuristics - Move docs/guide/writing-skills.md to docs/writing-skills.md and trim AGENTS.md to a summary that links to the dedicated doc - Expand trigger-phrase prefixes ("Use for/to", "Trigger when", "Apply when") and add "overview" to recommended body sections - Match recommended sections by markdown heading rather than substring to avoid false positives from inline mentions - Ignore .claude/ agent workspace Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Test that fresh scaffold produces zero lint hints Guard the central UX promise of the writing-skills guidelines integration: NewSkill + DefaultBody + defaultDescription must together pass lintStyle with zero hints. If any of those drift out of sync with a future lint-rule addition, this test fails. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2bf61d8 commit c5c3a2a

7 files changed

Lines changed: 508 additions & 27 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ dist/
88
coverage.out
99
coverage.html
1010

11-
# IDE
11+
# IDE / agent workspaces
12+
.claude/
1213
.idea/
1314
.vscode/
1415
*.swp

AGENTS.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ On subsequent encounters, the agent finds the existing skill via `skern skill se
169169
---
170170
name: skill-name
171171
description: |
172-
What this skill does and when to use it
172+
Use when <triggering conditions for this skill>.
173173
allowed-tools: []
174174
metadata:
175175
author:
@@ -184,13 +184,41 @@ metadata:
184184
date: "2025-07-15T10:30:00Z"
185185
---
186186

187-
## Instructions
187+
## Overview
188188

189-
Step-by-step instructions for the agent.
189+
1-2 sentence core principle of the skill.
190+
191+
## When to Use
192+
193+
- Triggering conditions and symptoms
194+
195+
## Core Pattern
196+
197+
The main technique or pattern (before/after for techniques).
198+
199+
## Quick Reference
200+
201+
- Scannable summary for fast lookup
202+
203+
## Common Mistakes
204+
205+
- Frequent errors and fixes
190206
```
191207

192208
Required fields: `name`, `description`. Directory name must match the `name` field.
193209

210+
### Writing Skills Guidelines
211+
212+
When creating or editing skills (via `skern skill create` or manually), follow these guidelines adapted from [superpowers/writing-skills](https://github.com/obra/superpowers/tree/main/skills/writing-skills). For full details, see [docs/writing-skills.md](docs/writing-skills.md).
213+
214+
Key points:
215+
216+
- **Description**: Start with "Use when..." — describe triggering conditions, not a workflow summary
217+
- **Naming**: `kebab-case`, verb-first active voice (`creating-skills` not `skill-creation`)
218+
- **Body structure**: Overview → When to Use → Core Pattern → Quick Reference → Common Mistakes
219+
- **Token budget**: Getting-started < 150 words; frequently-loaded < 200 words; others < 500 words
220+
- **Examples**: One excellent example beats many mediocre ones
221+
194222
### Skill Name Validation
195223

196224
Names must match `^[a-z0-9]+(-[a-z0-9]+)*$` and be 1-64 characters.

docs/writing-skills.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Writing Effective Skills
2+
3+
This guide covers how to write high-quality, discoverable, well-structured skills for skern. These guidelines are adapted from the [superpowers writing-skills](https://github.com/obra/superpowers/tree/main/skills/writing-skills) project and are built into skern's scaffolding and validation.
4+
5+
## Skill Types
6+
7+
| Type | Description | Example Name |
8+
|------|-------------|--------------|
9+
| **Technique** | Concrete method with actionable steps | `condition-based-waiting` |
10+
| **Pattern** | Mental model for problem-solving | `flatten-with-flags` |
11+
| **Reference** | API docs, syntax guides, lookup tables | `office-docs` |
12+
13+
## When to Create a Skill
14+
15+
Create a skill when:
16+
17+
- The technique was not intuitively obvious
18+
- You would reference it across multiple projects
19+
- The pattern applies broadly beyond one codebase
20+
- Others would benefit from it
21+
22+
Do **not** create a skill for:
23+
24+
- One-time solutions or narratives about specific sessions
25+
- Patterns already well-documented in official tooling
26+
27+
## Description: Claude Search Optimization (CSO)
28+
29+
The `description` field in your SKILL.md frontmatter is the most critical field for agent discoverability. Agents match skills by description, so how you write it directly affects whether your skill gets loaded.
30+
31+
**Start with "Use when..."** and describe the triggering conditions:
32+
33+
```yaml
34+
# Good
35+
description: |
36+
Use when tests hang or flake due to timing-dependent assertions.
37+
Symptoms: intermittent CI failures, setTimeout in test code.
38+
39+
# Bad — summarizes the workflow (agents may shortcut)
40+
description: |
41+
A skill that teaches agents how to write better async tests
42+
using condition-based waiting patterns.
43+
```
44+
45+
**Why this matters:** When a description summarizes the skill's workflow, an agent may follow the description as a shortcut instead of reading the full SKILL.md body.
46+
47+
**Keyword tips:**
48+
49+
- Include error messages agents might encounter
50+
- Add symptom words: "flaky", "hanging", "race condition", "timeout"
51+
- Use tool names and common synonyms
52+
53+
## Naming Conventions
54+
55+
- Use `kebab-case` with lowercase letters, numbers, and hyphens
56+
- Prefer verb-first active voice: `creating-skills` not `skill-creation`
57+
- Be specific: `condition-based-waiting` not `async-test-helpers`
58+
59+
Names must match `^[a-z0-9]+(-[a-z0-9]+)*$` and be 1-64 characters.
60+
61+
## Recommended Body Structure
62+
63+
When you run `skern skill create`, the scaffold includes these sections by default:
64+
65+
### Overview
66+
67+
1-2 sentences describing the core principle or technique. Keep it concise.
68+
69+
### When to Use
70+
71+
List triggering conditions as bullet points:
72+
73+
- Symptoms that signal this skill is needed
74+
- Specific use cases
75+
- When **not** to use this skill (counter-examples help agents avoid false matches)
76+
77+
### Core Pattern
78+
79+
The main technique or pattern. For techniques, use a before/after comparison:
80+
81+
```markdown
82+
## Core Pattern
83+
84+
**Before (anti-pattern):**
85+
`setTimeout(check, 1000)` — arbitrary delay, still flaky
86+
87+
**After (correct):**
88+
`waitFor(() => expect(value).toBe(true))` — condition-based, deterministic
89+
```
90+
91+
### Quick Reference
92+
93+
A scannable table or bullet list for fast lookup. Agents should be able to use this section as a cheat sheet without reading the full skill.
94+
95+
### Common Mistakes
96+
97+
Frequent errors and their fixes. Helps agents self-correct.
98+
99+
## Token Efficiency
100+
101+
Skills are loaded into agent context windows, so brevity matters:
102+
103+
| Skill Category | Target Word Count |
104+
|----------------|-------------------|
105+
| Getting-started workflows | < 150 words |
106+
| Frequently-loaded skills | < 200 words |
107+
| Other skills | < 500 words |
108+
109+
**Tips:**
110+
111+
- Use cross-references instead of repeating shared concepts
112+
- Compress examples to the minimum that demonstrates the point
113+
- Move heavy reference material (100+ lines) to supporting files
114+
115+
## Code Examples
116+
117+
- **One excellent example beats many mediocre ones**
118+
- Use the most relevant language for the skill's domain
119+
- Keep examples copy-pasteable and runnable
120+
121+
## File Organization
122+
123+
| Layout | When to Use |
124+
|--------|------------|
125+
| Single `SKILL.md` | All content fits in one file |
126+
| `SKILL.md` + supporting files | Heavy reference (100+ lines) or reusable tool code |
127+
128+
Supporting files live in the same directory as `SKILL.md`. Reference them in the body.
129+
130+
## Anti-Patterns to Avoid
131+
132+
- **Narrative storytelling** — "In session 2025-10-03, I encountered..." Skills are reusable references, not journals.
133+
- **Multi-language examples** — Pick one language. Multiple languages dilute quality and waste tokens.
134+
- **Generic labels** — Avoid `helper1`, `step3`, `utils`. Use descriptive names.
135+
- **Workflow summaries in description** — The description field is for triggering conditions only.
136+
137+
## Validation Hints
138+
139+
Skern's validator provides hints when your skill deviates from these guidelines:
140+
141+
- **Description missing trigger prefix** — Hints when the description doesn't start with "Use when", "Use for", "Use to", etc.
142+
- **Missing recommended sections** — Hints when the body is missing "When to Use", "Core Pattern", "Quick Reference", or "Common Mistakes" sections.
143+
- **Body too short** — Hints when the body has fewer than 20 words.
144+
- **Description too vague** — Hints when the description has fewer than 3 words.
145+
146+
These are non-blocking hints (not errors), designed to guide you toward better skills.
147+
148+
## Next Steps
149+
150+
- [Quick Start](/guide/quick-start) — create and install your first skill
151+
- [Skill Format](/concepts/skill-format) — full SKILL.md specification
152+
- [Validation Reference](/reference/validation) — all validation rules

internal/skill/scaffold.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,46 @@
11
package skill
22

33
// DefaultBody returns the default body content for a new skill.
4+
// The template follows the writing-skills guidelines: Overview, When to Use,
5+
// Core Pattern, Quick Reference, and Common Mistakes sections.
46
func DefaultBody() string {
5-
return "## Instructions\n\nTODO: Add step-by-step instructions for the agent.\n"
7+
return `## Overview
8+
9+
<!-- 1-2 sentences: the core principle or technique this skill provides. -->
10+
11+
TODO: Describe the core principle of this skill.
12+
13+
## When to Use
14+
15+
<!-- Triggering conditions — symptoms and use cases that signal this skill is needed. -->
16+
17+
- TODO: Add triggering conditions
18+
19+
## Core Pattern
20+
21+
<!-- The main technique or pattern. Use before/after examples for techniques. -->
22+
23+
TODO: Describe the core pattern or technique.
24+
25+
## Quick Reference
26+
27+
<!-- Scannable summary — a table or bullet list for fast lookup. -->
28+
29+
- TODO: Add quick reference items
30+
31+
## Common Mistakes
32+
33+
<!-- Frequent errors and their fixes. -->
34+
35+
- TODO: Add common mistakes and how to avoid them
36+
`
37+
}
38+
39+
// defaultDescription returns the default placeholder description for a new skill.
40+
// Follows the writing-skills guideline: start with "Use when..." to describe
41+
// triggering conditions, not a workflow summary.
42+
func defaultDescription() string {
43+
return "Use when TODO: describe the triggering conditions for this skill.\n"
644
}
745

846
// NewSkill creates a new Skill with sensible defaults.
@@ -13,7 +51,7 @@ func NewSkill(name, description, authorName, authorType, authorPlatform string)
1351
// NewSkillWithBody creates a new Skill with a custom body. If body is empty, DefaultBody() is used.
1452
func NewSkillWithBody(name, description, authorName, authorType, authorPlatform, body string) *Skill {
1553
if description == "" {
16-
description = "TODO: Describe what this skill does and when to use it.\n"
54+
description = defaultDescription()
1755
}
1856

1957
if body == "" {

internal/skill/scaffold_test.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ func TestNewSkill_NameOnly(t *testing.T) {
1010
s := NewSkill("my-skill", "", "", "", "")
1111

1212
assert.Equal(t, "my-skill", s.Name)
13+
assert.Contains(t, s.Description, "Use when")
1314
assert.Contains(t, s.Description, "TODO")
1415
assert.Equal(t, "0.0.1", s.Metadata.Version)
15-
assert.Contains(t, s.Body, "## Instructions")
16+
assert.Contains(t, s.Body, "## Overview")
17+
assert.Contains(t, s.Body, "## When to Use")
18+
assert.Contains(t, s.Body, "## Core Pattern")
19+
assert.Contains(t, s.Body, "## Quick Reference")
20+
assert.Contains(t, s.Body, "## Common Mistakes")
1621
}
1722

1823
func TestNewSkill_WithDescription(t *testing.T) {
@@ -39,6 +44,17 @@ func TestNewSkill_WithAgentAuthor(t *testing.T) {
3944

4045
func TestDefaultBody(t *testing.T) {
4146
body := DefaultBody()
42-
assert.Contains(t, body, "## Instructions")
47+
assert.Contains(t, body, "## Overview")
48+
assert.Contains(t, body, "## When to Use")
49+
assert.Contains(t, body, "## Core Pattern")
50+
assert.Contains(t, body, "## Quick Reference")
51+
assert.Contains(t, body, "## Common Mistakes")
4352
assert.Contains(t, body, "TODO")
4453
}
54+
55+
func TestDefaultDescription(t *testing.T) {
56+
desc := defaultDescription()
57+
assert.True(t, len(desc) > 0)
58+
assert.Contains(t, desc, "Use when")
59+
assert.Contains(t, desc, "TODO")
60+
}

0 commit comments

Comments
 (0)