Skip to main content
Custom commands let you define reusable prompts that run when you type /command-name in the TUI. They support dynamic flow via arguments, shell output, and file references.

Built-in commands

Symbiotic Code ships with these commands: A custom command with the same name as a built-in command replaces it.

Creating commands

Create .md files in one of two directories: The file path (without .md) becomes the command name. Subfolders are part of the name: .symbiotic/commands/frontend/component.md is invoked as /frontend/component. The singular folder name command/ also works.
Project commands are only available when you launch Symbiotic Code inside that project (from the directory containing .symbiotic/ or one of its subdirectories).

Example

  1. Create a file named test.md in .symbiotic/commands/ with the following content:
.symbiotic/commands/test.md
  1. Use it in Symbiotic Code TUI:

JSON config

Alternatively, define commands under the command key in symbiotic.json (project root), .symbiotic/symbiotic.json (project), or ~/.config/symbiotic/symbiotic.json (global). .jsonc variants are also supported. The prompt goes in the required template field:
symbiotic.json
Supports // single-line comments (.jsonc style).

Frontmatter options

The same fields are available in Markdown frontmatter and in JSON config. Other frontmatter keys (for example Claude Code’s allowed-tools or argument-hint) are ignored.
A field with the wrong type (for example subtask: "yes") prevents the configuration from loading. A file with malformed YAML frontmatter is skipped and an error is shown.

Template syntax

Use these placeholders in your command templates:

$ARGUMENTS: full argument string

Pass the entire argument string as a value in the prompt. Example:
↪ $ARGUMENTS is replaced with src/core/session.ts in the prompt.

$1, $2, $3…: positional arguments

Pass the argument at the specified position as a value in the prompt. Arguments are split on whitespace. Example:
  • $1 → Sidebar
  • $2 → src/cli/tui/components
Arguments also support quoting:
The highest-numbered placeholder receives all remaining arguments: with /create-component Sidebar src/components with tests, $2 becomes src/components with tests. Placeholders without a matching argument are replaced with an empty string.
If a template contains neither $ARGUMENTS nor a $N placeholder, the arguments you type are appended to the end of the prompt.

!`command`: shell output injection

Inject the output of a shell command into the prompt.
The command runs in the current working directory, before the prompt is sent to the model. Its stdout is injected inline into the prompt. A failing shell command doesn’t stop the custom command.
Shell commands in templates run directly on your machine: they don’t go through tool permissions or the agents container. Arguments are substituted before the shell command runs, so a template like !`git log $1` executes whatever you pass as $1. Only use argument placeholders inside shell commands with input you trust.

@path: file references

Reference a file or directory with @ followed by its path. It is attached to the prompt.
Paths are resolved relative to the project root; ~/ refers to your home directory. If no file exists at that path but an agent has that name (for example @explore), that agent is invoked as a subagent. References to missing files are ignored.

MCP prompts and skills

Prompts exposed by MCP servers are also available as commands, named server:prompt (characters other than letters, digits, _ and - are replaced with _). Prompt arguments map to $1, $2, and so on, in order. Skills can also be invoked as /skill-name, unless a command with that name already exists.

Commands priority

When the same command name exists in multiple sources, the highest-priority source wins: Definitions are merged field by field: if a higher-priority definition omits a field (for example description), the value from the lower-priority source is kept. Configuration managed by your organization takes precedence over all of these sources.