Skills
Package instructions, scripts and references as SKILL.md skills that the agent loads when a task calls for them.
A skill is a folder with a SKILL.md file: instructions for one kind of task, plus any scripts, templates or reference files they need. The agent sees each skill's name and description, and loads the full instructions only when a task matches. You can also run a skill yourself as a slash command.
Cusp uses the open Agent Skills format, so skills you already have work as is, from .claude/skills/, .agents/skills/ or .codex/skills/.
Where skills live
| Scope | Directories, in lookup order |
|---|---|
| Project | .cusp/skills/, .claude/skills/, .agents/skills/, .codex/skills/ |
| User | ~/.cusp/skills/, ~/.claude/skills/, ~/.agents/skills/, ~/.codex/skills/ |
Each skill is a directory: .cusp/skills/release-notes/SKILL.md. When two skills have the same name, the first one found wins, so a project skill overrides a user skill with the same name.
A minimal skill
---
name: release-notes
description: Draft release notes from the commits since the last tag. Use when the user asks for release notes, a changelog entry, or "what changed since …".
---
1. Find the last tag with `git describe --tags --abbrev=0`.
2. List commits since then with `git log <tag>..HEAD --oneline --no-merges`.
3. Group them into Features, Fixes and Internal. Drop chores and merge commits.
4. Write one line per change, in the past tense, without commit hashes.
5. Show the draft. Don't write any files unless asked.The description is what the agent uses to decide when the skill applies. Say what it does and when to use it, in the words a user would actually type.
Frontmatter
| Field | Type | Meaning |
|---|---|---|
name | string | The skill's name and slash command. Defaults to the directory name |
description | string | What it does and when to use it. Shown to the model |
when_to_use | string | Extra guidance on when to invoke it |
argument-hint | string | Shown after the command name in completion, such as [version] |
arguments | string[] | Names for positional arguments, for $name substitution |
allowed-tools | string[] | Tools pre-approved while the skill runs, in rule syntax, such as Bash(git log *) |
disallowed-tools | string[] | Tools denied while the skill runs |
model | string | Run the skill on a specific model |
effort | string | Reasoning effort while the skill runs |
context | fork | Run the skill in a forked subagent instead of the main conversation |
agent | string | With context: fork, the subagent type to use |
background | boolean | With context: fork, run it in the background |
paths | string[] | Globs. The skill is offered only when the agent works on matching files |
disable-model-invocation | boolean | Only you can run it, as a slash command |
user-invocable | boolean | Set to false to hide it from the slash menu, so only the model can use it |
hooks | object | Hooks active while the skill runs, in the hooks format |
shell | string | Shell used for !`command` expansion |
Arguments
When you run /release-notes v0.2.0, the text after the command is the argument string.
| Placeholder | Becomes |
|---|---|
$ARGUMENTS | The whole argument string |
$ARGUMENTS[0], $0 | The first positional argument (0-based) |
$1, $2, … | Later positional arguments |
$version | A named argument, if arguments: [version] is set |
\$ | A literal dollar sign |
If you pass arguments but the skill has no placeholder, Cusp appends them as ARGUMENTS: … at the end, so they're never lost.
Variables
${CUSP_SKILL_DIR} (or ${CLAUDE_SKILL_DIR}) is the directory that contains SKILL.md. Use it to point at files shipped with the skill:
Fill in the template at ${CUSP_SKILL_DIR}/template.md.
Run `python ${CUSP_SKILL_DIR}/scripts/check.py` and fix what it reports.Shell expansion
!`command` runs a command when the skill loads and inserts its output in place. Use it to give the agent current context without spending a tool call:
Current branch: !`git branch --show-current`
Uncommitted changes:
!`git status --short`The output is inserted as is and isn't expanded again. If the command fails, loading the skill fails with the exit code and output, so you know why.
Set disableSkillShellExecution: true in settings to turn this off.
Supporting files
Put anything the skill needs next to SKILL.md:
.cusp/skills/release-notes/
├── SKILL.md
├── template.md
└── scripts/
└── group_commits.pyThe agent reads these files only when the instructions tell it to, so a large reference document costs nothing until it's needed.
Controlling skills
Turn individual skills off, or limit how they can be used, with skillOverrides in settings:
{
"skillOverrides": {
"release-notes": "user-invocable-only",
"legacy-deploy": "off"
}
}| Value | Effect |
|---|---|
on | Default: listed for the model and available as a command |
name-only | Listed by name only, without the description |
user-invocable-only | Only available as a slash command |
off | Not loaded |
disableSkills: true turns off all skills.
Permissions
Running a skill is itself a tool call (Skill), so you can control it with rules: Skill(deploy), Skill(deploy *) for a skill with any arguments, or Skill(ops:*) for every skill in the ops namespace.
Single-file commands
A command is a skill without its folder: one Markdown file that runs as /name. Cusp reads them from .cusp/commands/ and .claude/commands/, and from the same folders in your home directory. When a skill and a command share a name, the skill wins.
Other agents' commands, such as Codex prompts, Gemini CLI's TOML commands and Cursor commands, are converted into this form by the import. See Import your setup.
Parallel agents
Run several agents on one repository without collisions — worktrees, subagents, workflows, steering and the Board — and what's still in preview.
Agents
Define subagents in Markdown with frontmatter, in the format your existing agent files already use, and delegate work to them with fresh context.