Help the user create a new dynamic skill. A dynamic skill is a Nunjucks template that gets rendered at prompt time via a UserPromptSubmit hook, injecting context-aware instructions into the agent's prompt.
-
Ask the user for the skill name (lowercase, kebab-case, e.g. run-tests, deploy-app).
-
Ask what context sources the skill needs (can be one or more):
- Preferences — values from
preferences.json (booleans, strings, numbers shared across all skills)
- Project files — file contents injected via
files.json (maps variable names to project file paths)
- Environment variables — values from
process.env, accessed as {{ env.VAR_NAME }}
-
Create the folder structure under .claude/dynamic-skills/<skill-name>/:
.claude/dynamic-skills/<skill-name>/
├── template.njk # Always created
└── files.json # Only if the skill uses project files
-
Generate template.njk using the appropriate patterns based on the chosen context sources:
For preferences — use conditional blocks:
{% if preference_name %}
Instructions when preference is true/set
{% else %}
Instructions when preference is false/unset
{% endif %}
For project files — use variable interpolation (variables are loaded from files.json):
Use the following content:
{{ variable_name }}
For environment variables — use the env object:
{% if env.CI %}
Running in CI environment
{% else %}
Running locally as {{ env.USER }}
{% endif %}
All three can be combined in a single template.
-
Generate files.json (only if the skill uses project files). This maps variable names to relative file paths from the project root:
{
"variable_name": "path/to/file.md"
}
-
Update preferences.json if the skill introduces new preferences. Add the new keys to .claude/dynamic-skills/preferences.json with sensible defaults. Do not remove existing preferences.
-
Tell the user their skill is ready and can be invoked by typing #<skill-name> in any prompt.