Pure data struct representing a registered skill in SkillKit.
SkillKit.Skill is a plain Elixir struct that carries all identity,
execution, and hook configuration for a skill. Execution is delegated
to the module named in :tool (default: SkillKit.Tools.Shell).
Struct Fields
| Field | Type | Default | Description |
|---|
:name | `String.t() | nil` | nil | Fully-qualified "namespace:skill_name" |
:namespace | `String.t() | nil` | nil | Namespace segment extracted from name |
:description | `String.t() | nil` | nil | Human-readable description |
:body | `String.t() | nil` | nil | Skill body / prompt template |
:location | `String.t() | nil` | nil | File path or source location for this skill |
:required_scope | [String.t()] | [] | Scopes required to call this skill |
:tool | module() | SkillKit.Tools.Shell | Module responsible for executing the skill |
:hooks | [SkillKit.Hook.t()] | [] | Lifecycle hooks attached to this skill |
:metadata | %{String.t() => term()} | %{} | Arbitrary key-value metadata from frontmatter |
Naming Convention
Skill names follow the format "namespace:skill_name", where:
- Both segments are lowercase, starting with a letter
- Segments may contain letters, digits, underscores, and hyphens
- Exactly one colon separates the namespace from the skill name
Examples: "files:read", "tools:web-search", "my-org:analyze_data"
Summary
Functions
Renders the skill body by substituting template tokens with values from args.
Types
Functions
Renders the skill body by substituting template tokens with values from args.
Supported tokens:
$ARGUMENTS— all arguments as a single string (fromargs["arguments"])$ARGUMENTS[N]— positional argument by 0-based index (space-split)$N— shorthand for$ARGUMENTS[N](e.g.,$0,$1)$SKILL_DIR/${SKILL_DIR}— directory of the skill (derived from:location)$SESSION_ID/${SESSION_ID}— session ID (fromargs["session_id"])- Legacy
${CLAUDE_SKILL_DIR}and${CLAUDE_SESSION_ID}are still supported.
When a scope implementing SkillKit.Scope is provided, any remaining
$VAR / ${VAR} tokens are resolved via Scope.resolve/3 as a final
fallback. Unresolved scope variables are left as-is.
If $ARGUMENTS (or $N) is NOT present in the body but arguments are provided,
appends \n\nARGUMENTS: <value> to the end.
Returns {:ok, ""} when body is nil.