/writing-skills
Use when creating new golem-powers skills, editing existing skills, or verifying skills work. Covers create skill, write skill, skill template, skill structure. NOT for: using existing skills (invoke them directly), superpowers skills (different structure).
$ golems-cli skills install writing-skillsUpdated 2 weeks ago
Meta-skill for creating executable skills. Skills are tools that Claude can invoke and automatically execute.
Skill Structure
Every golem-powers skill MUST have this structure:
skills/golem-powers/<skill-name>/
├── SKILL.md # REQUIRED: Frontmatter + documentation
├── CLAUDE.md # OPTIONAL: Environment requirements, complex setup
├── scripts/ # REQUIRED: Executable files
│ ├── default.sh # Pattern A: Bash script
│ └── run.sh # Pattern B: Wrapper for TypeScript
├── src/ # OPTIONAL: TypeScript source (Pattern B)
│ └── index.ts
├── package.json # OPTIONAL: Required if using TypeScript
├── bun.lock # OPTIONAL: Required if using TypeScript
└── workflows/ # OPTIONAL: Multi-step procedures
├── create.md
└── verify.md
SKILL.md Frontmatter (REQUIRED)
---
name: <skill-name>
description: <when to use this skill - shown in skill discovery>
execute: scripts/default.sh # Path to script Claude runs on invocation
---The execute: field is what makes a skill executable. When Claude loads a skill with execute: frontmatter, it MUST run that script IMMEDIATELY via Bash before any other action.
Dual Execution Patterns
Pattern A: Bash Script
Best for: Simple CLI wrappers, no dependencies, quick operations.
Frontmatter:
execute: scripts/review.shStructure:
skill-name/
├── SKILL.md
└── scripts/
└── review.sh # chmod +x
Script conventions:
- Scripts output Markdown for Claude to parse
- Use
set -euo pipefailfor safety - Exit 0 on success, non-zero on failure
- Print errors to stderr, results to stdout
- MUST use BASH_SOURCE for path detection (see Path Standard below)
Example script:
#!/usr/bin/env bash
set -euo pipefail
# REQUIRED: Self-detect script location (works from any cwd)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
echo "## Review Results"
echo ""
some-cli-tool review --format markdownPattern B: TypeScript/Bun
Best for: Complex logic, API calls, type safety, structured data processing.
Frontmatter:
execute: scripts/run.sh --action=defaultStructure:
skill-name/
├── SKILL.md
├── scripts/
│ └── run.sh # Wrapper that calls bun
├── src/
│ └── index.ts # Main TypeScript file
├── package.json
└── bun.lock
The wrapper script (scripts/run.sh):
#!/usr/bin/env bash
set -euo pipefail
# REQUIRED: Self-detect script location (works from any cwd)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
cd "$SKILL_DIR"
bun run src/index.ts "$@"TypeScript requirements:
- Use Bun runtime (fast, TypeScript-native)
- Accept CLI arguments via
process.argv - Output Markdown or JSON to stdout
- Handle errors gracefully with exit codes
CLI Pattern (for TypeScript skills)
Use flags to support multiple operations in one skill:
--action Flag
execute: scripts/run.sh --action=defaultAvailable actions defined in your TypeScript:
const action = process.argv.find(a => a.startsWith('--action='))?.split('=')[1] || 'default';
switch (action) {
case 'default':
// Main skill behavior
break;
case 'verify':
// Verification mode
break;
case 'list':
// List mode
break;
}--env Flag
For environment selection:
scripts/run.sh --action=deploy --env=prodconst env = process.argv.find(a => a.startsWith('--env='))?.split('=')[1] || 'dev';Full SKILL.md source — includes LLM directives, anti-patterns, and technical instructions stripped from the Overview tab.
Meta-skill for creating executable skills. Skills are tools that Claude can invoke and automatically execute.
Skill Structure
Every golem-powers skill MUST have this structure:
skills/golem-powers/<skill-name>/
├── SKILL.md # REQUIRED: Frontmatter + documentation
├── CLAUDE.md # OPTIONAL: Environment requirements, complex setup
├── scripts/ # REQUIRED: Executable files
│ ├── default.sh # Pattern A: Bash script
│ └── run.sh # Pattern B: Wrapper for TypeScript
├── src/ # OPTIONAL: TypeScript source (Pattern B)
│ └── index.ts
├── package.json # OPTIONAL: Required if using TypeScript
├── bun.lock # OPTIONAL: Required if using TypeScript
└── workflows/ # OPTIONAL: Multi-step procedures
├── create.md
└── verify.md
SKILL.md Frontmatter (REQUIRED)
---
name: <skill-name>
description: <when to use this skill - shown in skill discovery>
execute: scripts/default.sh # Path to script Claude runs on invocation
---The execute: field is what makes a skill executable. When Claude loads a skill with execute: frontmatter, it MUST run that script IMMEDIATELY via Bash before any other action.
Dual Execution Patterns
Pattern A: Bash Script
Best for: Simple CLI wrappers, no dependencies, quick operations.
Frontmatter:
execute: scripts/review.shStructure:
skill-name/
├── SKILL.md
└── scripts/
└── review.sh # chmod +x
Script conventions:
- Scripts output Markdown for Claude to parse
- Use
set -euo pipefailfor safety - Exit 0 on success, non-zero on failure
- Print errors to stderr, results to stdout
- MUST use BASH_SOURCE for path detection (see Path Standard below)
Example script:
#!/usr/bin/env bash
set -euo pipefail
# REQUIRED: Self-detect script location (works from any cwd)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
echo "## Review Results"
echo ""
some-cli-tool review --format markdownPattern B: TypeScript/Bun
Best for: Complex logic, API calls, type safety, structured data processing.
Frontmatter:
execute: scripts/run.sh --action=defaultStructure:
skill-name/
├── SKILL.md
├── scripts/
│ └── run.sh # Wrapper that calls bun
├── src/
│ └── index.ts # Main TypeScript file
├── package.json
└── bun.lock
The wrapper script (scripts/run.sh):
#!/usr/bin/env bash
set -euo pipefail
# REQUIRED: Self-detect script location (works from any cwd)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
cd "$SKILL_DIR"
bun run src/index.ts "$@"TypeScript requirements:
- Use Bun runtime (fast, TypeScript-native)
- Accept CLI arguments via
process.argv - Output Markdown or JSON to stdout
- Handle errors gracefully with exit codes
CLI Pattern (for TypeScript skills)
Use flags to support multiple operations in one skill:
--action Flag
execute: scripts/run.sh --action=defaultAvailable actions defined in your TypeScript:
const action = process.argv.find(a => a.startsWith('--action='))?.split('=')[1] || 'default';
switch (action) {
case 'default':
// Main skill behavior
break;
case 'verify':
// Verification mode
break;
case 'list':
// List mode
break;
}--env Flag
For environment selection:
scripts/run.sh --action=deploy --env=prodconst env = process.argv.find(a => a.startsWith('--env='))?.split('=')[1] || 'dev';Execution Rule
CRITICAL: When loading a golem-powers skill with execute: frontmatter, the agent MUST run that script IMMEDIATELY before any other action.
This means:
- Agent loads the skill SKILL.md
- Agent sees
execute: scripts/foo.sh - Agent IMMEDIATELY runs the script via shell — path depends on CLI:
- Claude Code:
bash ~/.claude/commands/<skill>/scripts/foo.sh - Codex / Cursor / Gemini:
bash ~/.agents/skills/<skill>/scripts/foo.sh
- Claude Code:
- Agent reads the output
- Only THEN does the agent proceed with other actions
This ensures skills are executable tools, not just documentation.
Quick Actions
| What you want | Workflow |
|---|---|
| Create a new skill | workflows/create.md |
| Audit skill structure | workflows/audit.md |
Template Generator
Use the included script to scaffold new skills:
# Claude Code
bash ~/.claude/commands/writing-skills/scripts/create-skill.sh \
--name=my-skill \
--type=bash
# Codex / Cursor / Gemini
bash ~/.agents/skills/writing-skills/scripts/create-skill.sh \
--name=my-skill \
--type=bashOptions:
--name=<skill-name>(required): Name for the new skill--type=bash|typescript(required): Execution pattern--output=<path>(optional): Output directory (default: ./skills/golem-powers/)
This creates:
- Pattern A (bash):
SKILL.md,scripts/default.sh - Pattern B (typescript):
SKILL.md,scripts/run.sh,src/index.ts,package.json
Examples
See working examples in this repo:
skills/golem-powers/example-bash/- Simple bash skillskills/golem-powers/example-typescript/- TypeScript/Bun skill
Safety Rules
- Always chmod +x - All scripts must be executable
- Test before commit - Run
shellcheckon all .sh files - Output Markdown - Scripts should return Markdown Claude can parse
- Exit codes matter - 0 = success, non-zero = failure
- Use BASH_SOURCE pattern - All scripts MUST self-detect their location
Path Standard (CRITICAL)
All skill scripts MUST use this pattern for portability:
#!/usr/bin/env bash
set -euo pipefail
# REQUIRED: Self-detect script location (works from any cwd)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
# Now use absolute paths relative to skill
source "$SKILL_DIR/config.sh" # If neededFor project detection (when script needs prd-json/, package.json, etc.):
# Walk up from cwd to find project root
find_project_root() {
local dir="$PWD"
while [[ ! -d "$dir/prd-json" && "$dir" != "/" ]]; do
dir="$(dirname "$dir")"
done
if [[ -d "$dir/prd-json" ]]; then
echo "$dir"
else
echo ""
fi
}
PROJECT_ROOT="$(find_project_root)"
if [[ -z "$PROJECT_ROOT" ]]; then
echo "Error: Cannot find prd-json/ directory" >&2
exit 1
fiWhy this matters:
- Skills are symlinked into a CLI-specific directory, but agents run from project directories:
- Claude Code:
~/.claude/commands/<skill>/ - Codex / Cursor / Gemini:
~/.agents/skills/<skill>/
- Claude Code:
- Relative paths like
./scripts/foo.shfail when cwd != skill directory - BASH_SOURCE provides reliable self-location regardless of invocation context or CLI
See contexts/skill-authoring.md for full details.
Best Pass Rate
100%
Opus 4.6
Assertions
10
3 models tested
Avg Cost / Run
$0.2309
across models
Fastest (p50)
3.5s
Haiku 4.5
Behavior Evals
Phase 2 baseline — skill quality on ClaudeBehavior Baseline
| Assertion | Opus 4.6 | Sonnet 4.6 | Haiku 4.5 | Consensus |
|---|---|---|---|---|
| follows-skill-anatomy | 1/3 | |||
| includes-not-for-section | 3/3 | |||
| checks-for-duplicates | 3/3 | |||
| validates-against-template | 2/3 | |||
| reads-before-editing | 1/3 | |||
| identifies-specific-issues | 2/3 | |||
| preserves-existing-structure | 2/3 | |||
| audits-all-sections | 3/3 | |||
| checks-references | 2/3 | |||
| provides-actionable-fixes | 2/3 |
Token Usage
Cost per Run
| Model | Input Tokens | Output Tokens | Cost / Run | Cost / 1K Runs |
|---|---|---|---|---|
| Opus 4.6 | 5,328 | 6,965 | $0.6023 | $602.30 |
| Sonnet 4.6 | 3,898 | 5,148 | $0.0889 | $88.90 |
| Haiku 4.5 | 1,356 | 862 | $0.0014 | $1.40 |
Response Time (p50)
Response Time (p95)
| Model | p50 | p95 | Overhead |
|---|---|---|---|
| Opus 4.6 | 4.2s | 7.8s | +87% |
| Sonnet 4.6 | 5.8s | 8.2s | +43% |
| Haiku 4.5 | 3.5s | 5.0s | +40% |
Last evaluated: 2026-03-12 · Data is generated from skill assertions (real cross-model benchmarks coming soon)
Changelog entries are derived from eval runs and skill version updates. Full cascading changelog (Phase 4D) coming soon.
Best Pass Rate
100%
Assertions
10
Models Tested
3
Evals Run
3
- +Initial release to Golems skill library
- +10 assertions across 3 eval scenarios
- +2 workflows included: audit, create