CreateSkill
Framework for creating and validating skills in the Forge ecosystem. Ported from PAI's CreateSkill and adapted to forge conventions.
Workflow Routing
| Workflow | Trigger | Section |
|---|---|---|
| Create | "create a skill", "new skill", "write a skill" | Create Workflow |
| Validate | "validate skill", "check skill structure" | Validate Workflow |
Forge Skill Conventions
Where Skills Live
| Location | Purpose |
|---|---|
Core/skills/SkillName/ | Framework-level skills (Init, Update, CreateSkill) |
Modules/forge-*/skills/SkillName/ | Module skills (Log, Draft, TLP, etc.) |
$FORGE_USER_ROOT/Orchestration/Skills/SkillName/ | Vault workspace — for drafting/editing in Obsidian |
All parent directories must be registered in plugin.json under the skills array. Skills in the vault workspace override module skills of the same name (load order: last wins).
SKILL.md Structure
Every skill is a single SKILL.md file with YAML frontmatter:
--- name: SkillName description: What it does. USE WHEN trigger phrase one, trigger phrase two, or trigger phrase three. Additional capabilities. ---
Frontmatter rules:
- •
name:— PascalCase for multi-word (e.g.,VaultOperations,DailyPlan), natural casing for single words (e.g.,Log,Draft,Init) - •
description:— single line, under 1024 characters, includesUSE WHENwith intent-based triggers joined by commas/OR - •Optional:
argument-hint:for skills invoked with/SkillName <args>(e.g.,"[natural language description]") - •Optional:
version:for versioned skills - •No separate
triggers:orworkflows:arrays in YAML
Body Structure
# SkillName Brief description of what the skill does. ## Instructions (or ## Usage) Step-by-step procedure. Use numbered steps for sequential operations. ### Step 1: Description [What to do] ### Step 2: Description [What to do] ## Constraints - Boundary conditions and rules - What NOT to do
For skills with multiple workflows: Use ## Workflow Routing table in the body linking to sections within the same file. Keep everything in one SKILL.md unless it exceeds ~200 lines — then consider splitting workflows into separate sections with clear headings.
Naming Conventions
| Component | Convention | Examples |
|---|---|---|
| Skill directory | PascalCase | CreateSkill, DailyPlan, VaultOperations |
| Single-word skill | Natural case | Log, Draft, Init, Update |
| SKILL.md | Always SKILL.md | — |
CLI Tool Integration
When a skill wraps a CLI tool (Rust binary, shell script), include:
- •Tool location — where the binary lives (e.g.,
Modules/forge-obsidian/bin/obsidian-base) - •Usage examples — concrete
bashblocks showing invocation - •Intent-to-flag mapping — table translating natural language to CLI flags
- •Output format — what the tool returns (JSONL, plain text, etc.)
Hook Integration
Skills can execute shell commands on load using ! backtick lines at the end of SKILL.md:
!`dispatch skill-load forge-reflect`
These run when the skill is invoked. Use for loading additional context, checking prerequisites, or initializing state.
Canon + Sidecar Pattern
Promoted skills use two files side by side:
| File | Purpose | Managed by |
|---|---|---|
SKILL.md | Canon — Claude Code frontmatter (name:, description:, argument-hint:, version:) + skill body | Claude / AI |
SKILL.yaml | Sidecar — Obsidian metadata (title:, aliases:, tags:, keywords:, collection:, icon:, cssclasses:, created:, updated:, related:) | Obsidian Linter |
Why separate files? The Obsidian Linter reformats frontmatter on save — it adds title:, reorders keys, and may strip unrecognized fields like name:. If both Claude Code and Obsidian metadata live in SKILL.md, the Linter overwrites Claude's fields. Separating them prevents cross-contamination.
Round-trip workflow:
- •
forge-promoteextracts non-Claude keys intoSKILL.yaml(viapromote.yamlallowlist) - •
forge-draftmergesSKILL.yamlback into frontmatter when pulling into the vault - •The allowlist lives in
Modules/forge-obsidian/promote.yaml
Rule: Moving skills upstream (vault → module) MUST always produce both files. A promote without a sidecar is incomplete.
Development Lifecycle
- •Draft —
/Draft SkillNamecopies a module skill to the vault workspace for editing in Obsidian (restores sidecar metadata into frontmatter) - •Edit — modify the vault copy; it immediately overrides the module version
- •Promote —
/Promote SkillNamepushes the vault copy back to its source module (extracts sidecar, strips vault keys, creates Upstream symlink) - •Register — run
/Updateto regenerate configs if skill directories changed
For brand-new skills: create directly in $FORGE_USER_ROOT/Orchestration/Skills/SkillName/SKILL.md with source_module: <target-module> in frontmatter, then /Promote when ready.
Create Workflow
Step 1: Understand the request
Determine:
- •What does this skill do?
- •What should trigger it? (intent phrases for
USE WHEN) - •Does it wrap a CLI tool, or is it purely procedural?
- •Which module should it live in? (or Core, or vault-only)
If the user hasn't specified, ask using AskUserQuestion.
Step 2: Determine the target location
| Scenario | Location |
|---|---|
| Framework capability | Core/skills/SkillName/SKILL.md |
| Module-specific | Modules/forge-<module>/skills/SkillName/SKILL.md |
| Personal/experimental | $FORGE_USER_ROOT/Orchestration/Skills/SkillName/SKILL.md |
Check that the parent directory is registered in plugin.json. If not, it needs to be added (or an existing registered directory used).
Step 3: Write the SKILL.md
Follow the structure from Forge Skill Conventions above.
Checklist while writing:
- • Frontmatter has
name:anddescription:withUSE WHEN - • Description is single-line, under 1024 characters
- • Body starts with
# SkillNameheading - • Clear step-by-step instructions (numbered steps for sequential operations)
- • If wrapping a CLI tool: usage examples, intent-to-flag mapping, output format
- • Constraints section with boundary conditions
- • No unnecessary complexity — minimum needed for the task
Step 4: Create the skill directory and file
mkdir -p <target-location>/SkillName
Write the SKILL.md using the Write tool.
Step 5: Register if needed
If the skill is in a new directory not already in plugin.json, update the skills array:
{
"skills": [
"./Core/skills",
"./Modules/forge-obsidian/skills",
...
]
}
Then run /Update to regenerate platform configs.
Step 6: Verify
- •Check the skill appears in
/Skillsoutput - •Test invocation: does the description trigger correctly?
- •Review: does the procedure work end-to-end?
Validate Workflow
Step 1: Read the target skill
cat <path-to>/SkillName/SKILL.md
Step 2: Check frontmatter
- •
name:present and uses correct casing - •
description:is single-line withUSE WHENclause - •
description:is under 1024 characters - • No deprecated fields (
triggers:,workflows:arrays) - • Optional fields (
argument-hint:,version:) are correctly formatted
Step 3: Check body structure
- • Starts with
# SkillNameheading (matchesname:frontmatter) - • Has clear instructions (numbered steps, usage section, or workflow routing)
- • If multiple workflows:
## Workflow Routingtable present - • Constraints or rules section for boundary conditions
- • No unnecessary sections or boilerplate
Step 4: Check CLI tool integration (if applicable)
- • Tool path is documented
- • Usage examples with
bashblocks - • Intent-to-flag mapping table (if tool has flags)
- • Output format described
Step 5: Check registration
# Verify the skill's parent directory is in plugin.json cat .claude-plugin/plugin.json | grep -c "skills"
- • Skill's parent directory is listed in
plugin.jsonskillsarray - • Skill appears in
/Skillsoutput
Step 6: Report
COMPLIANT — all checks pass.
NON-COMPLIANT — list failures with specific fixes. Offer to fix automatically.
Examples
Example 1: Create a skill for a CLI tool
User: "Create a skill for the obsidian-base binary" → Invokes Create workflow → Determines: wraps CLI tool in forge-obsidian → Writes SKILL.md with usage examples, intent-to-flag mapping → Places in Modules/forge-obsidian/skills/ObsidianBase/SKILL.md
Example 2: Validate an existing skill
User: "Validate the Log skill" → Invokes Validate workflow → Reads Modules/forge-journals/skills/Log/SKILL.md → Checks frontmatter, body structure, registration → Reports compliance status
Example 3: Create a personal skill
User: "Create a skill for managing my reading list" → Invokes Create workflow → Determines: personal/experimental → vault workspace → Creates $FORGE_USER_ROOT/Orchestration/Skills/ReadingList/SKILL.md → Adds source_module: for future promotion