Custom Commands

Add your own prompt templates to the slash menu, in Markdown or TOML. Covers $ARGUMENTS expansion, namespaces, and project or user scopes.

The Command Deck's slash menu is open for you to extend. Alongside the built-ins (/help, /models, /export, and more), your ⚡ skills, and your custom agents, you can add commands: reusable prompt templates you run as /name.

The format

A command is a COMMAND.md file. Use the nested layout (<slug>/COMMAND.md) or the flat layout (<slug>.md). It has optional frontmatter and a Markdown body:

.stella/commands/review.md
---
name: review
description: Review the working diff like our team does.
---

Review the current diff for correctness first, style second.
Focus areas: $ARGUMENTS

- Flag any change without a matching test.
- Check error paths before happy paths.

Both frontmatter fields are optional. Skip name: and stella uses the filename stem, or the directory name in the nested layout. Skip description: and stella uses the body's first non-empty line. Only the body is required. A command with an empty body is skipped, with a diagnostic message rather than a hard error.

Fields

name

The command name, without the leading slash and without any namespace.

Default the filename stem

description

The description shown in the slash menu.

Default the body's first line

argument-hint

What the argument slot expects, such as <pr-number>. It shows next to the name in the menu. It's for humans only — nothing checks your input against it. A command that refused to run just because your input didn't match the hint would be worse than one that passes the text through.

allowed-tools

The tools this command's turn may use. Leave it out and the command runs with every tool the session already has.

Default no restriction

model

Pin a model for this command's turn, written as provider/model_id.

Default the session's model

disable-model-invocation

Set this to true so only you can run the command. The model can never trigger it on its own. Use it for commands that should always be a deliberate choice.

Default false

Write any field in kebab-case or snake_case. argument-hint and argument_hint both work.

disable-model-invocation exists to turn a capability off. If stella can't read the value, it treats the command as still on. A typo leaves the command open to the model instead of quietly locking it out.

Markdown or TOML

Write a command as Markdown with frontmatter (<slug>.md) or as TOML (<slug>.toml). Both formats support the same fields and produce the same command. TOML isn't a more advanced option, just a different way to write the same thing. A workspace can mix both.

.stella/commands/review.toml
name = "review"
description = "Review the working diff like our team does."
argument-hint = "<focus-areas>"
allowed-tools = ["task_list", "get_state", "list_state"]
disable-model-invocation = true
prompt = """
Review the current diff for correctness first, style second.
Focus areas: $ARGUMENTS

- Flag any change without a matching test.
- Check error paths before happy paths.
"""

In TOML, the body lives under prompt instead of at the end of the file. That's the real reason to reach for TOML. A prompt string needs no frontmatter fence, so a template that already contains Markdown, or a --- line, has nothing to escape. TOML also gives you a real array for allowed-tools instead of a comma-delimited string.

stella commands convert turns a Markdown command into TOML. stella commands list shows every command available in your workspace.

Namespaces

A command one level down is namespaced by its folder, and you call it with a colon:

.stella/commands/deploy.toml          →  /deploy
.stella/commands/vercel/deploy.toml   →  /vercel:deploy

Only commands support namespaces. Skills and agents don't, and each still needs one file per definition. A namespace folder with no loadable command inside it isn't skipped quietly. You get a diagnostic instead.

Argument expansion

Type /review auth module and stella fills in the template, then runs the result as your prompt.

  • Every $ARGUMENTS in the body is replaced with whatever you typed after the command name. That's auth module in this example.
  • If the body has no $ARGUMENTS placeholder, your arguments are still used. stella adds them as a paragraph at the end. This means prompt files written for other tools work here with no changes.

Where commands live

Project

Commit it, and everyone who clones the repo gets the command in their slash menu.

Path
<workspace>/.stella/commands/
Travels with
the repo
User

Your own templates, available in every repo you open.

Path
~/.stella/commands/
Travels with
you, across every workspace

stella loads user-scope commands first, then project-scope commands. If both define the same name, the project version wins. Built-in commands can never be overridden. When a custom name collides across kinds, commands win over skills, and skills win over agents.

Trusted repos

A command from a repo you cloned doesn't run until you mark the repo trusted, with STELLA_TRUST_PROJECT=1. Your own commands in ~/.stella/commands/ are always available. Only project-scope commands are held back, because a prompt template shipped inside someone else's repo is content you didn't write.

If a command you added to .stella/commands/ doesn't show up in the slash menu or in stella commands list, check whether the repo is trusted before you check the file. The loader is telling you what will actually run.

Bring in existing commands

Running stella init (or /init) brings in command definitions from other agent tools you already use, as symlinks. It reads from .claude/commands/ and .agents/commands/ in your workspace, and from ~/.claude/commands/ and ~/.agents/commands/ for your user scope. Your existing setup carries over instead of getting rewritten. If .claude and .agents both define the same name, .claude wins. A command you already defined in stella is never overwritten, and running init again is always safe. The same process brings in skills and agents too. See the full details on the Custom Agents page.

Commands are prompt templates, nothing more. For a reusable persona with its own restricted toolbelt, define a custom agent. To give the agent a genuinely new action, like a deploy script or a database query, define a custom tool. To run shell commands on lifecycle events, use hooks.