OpenCode Custom Commands

Custom commands allow you to encapsulate commonly used prompts into a short command. In the TUI,/command nameyou can execute it with one keystroke, avoiding repeated entry of the same prompt.

For example, encapsulate the complex prompt "run tests and analyze failure reasons" as/testEach time, you only need to enter two characters to trigger it.

Custom commands are/init、/undo、/redo、/share、/helpextensions beyond built-in commands, etc.

If your custom command has the same name as a built-in command,the custom command will override the built-in command.Please avoid usinginit、undo、redo、share、helpas a custom command name, unless you explicitly need to replace the built-in behavior.


Two Definition Methods

Custom commands support two definition methods with exactly the same effect. You can choose based on your personal preference:

Method File Applicable Scenario
JSON Configuration opencode.jsonofcommandField Fewer commands, prefer centralized management of all configurations
Markdown File commands/in the directory.mdfile Longer command content, prefer maintaining each command separately

Method 1: JSON Configuration

Inopencode.jsonofcommandDefine it in the field; the key name is the command name:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "command": {
    "test": {                           // Command name, invoked via /test in the TUI
      "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.",
                                        // template: the prompt content sent to the LLM (required)
      "description": "Run tests with coverage",
                                        // description: the description shown in the TUI command list (optional)
      "agent": "build",                 // agent: the agent that executes this command (optional)
      "model": "anthropic/claude-3-5-sonnet-20241022"
                                        // model: overrides the model used by this command (optional)
    }
  }
}

After configuration is complete, type in the TUI input box/testand press Enter to execute the command.


Method 2: Markdown Files

Incommands/Create in the directory.mda file to define the command.The file name is the command name.The file content is divided into two parts:

  • Frontmatter(---the YAML section wrapped by ---): defines the command's attributes
  • Body(content below the Frontmatter): becomes the prompt template sent to the LLM

Markdown files support two storage locations:

  • Project-level:.opencode/commands/命令名.md(only valid for the current project)
  • Global:~/.config/opencode/commands/命令名.md(valid for all projects)
<!-- 文件路径:.opencode/commands/test.md -->
---
description: Run tests with coverage
agent: build
model: anthropic/claude-3-5-sonnet-20241022
---

Run the full test suite with coverage report and show any failures.
Focus on the failing tests and suggest fixes.

The file name istest.md, so the command name istest, and in the TUI, it is invoked via/test.


Prompt Template Syntax

The command's prompt (templatefield or Markdown body) supports the following special syntax, allowing the prompt to dynamically respond to arguments, inject command output in real time, or reference file contents.

1. Passing Arguments ($ARGUMENTS)

Use the$ARGUMENTSplaceholder to receive the arguments passed when the command is invoked, inserted as a whole string:

<!-- 文件路径:.opencode/commands/component.md -->
---
description: Create a new React component
---

Create a new React component named $ARGUMENTS with TypeScript support.
Include proper typing and basic structure.

When invoking, append the arguments after the command name:

/component Button

$ARGUMENTSwill be replaced withButtonThe actual executed prompt becomes:

Create a new React component named Button with TypeScript support.
Include proper typing and basic structure.

2. Positional Parameters ($1, $2, $3...)

When you need to pass multiple independent arguments, you can use positional parameters$1、$2、$3to reference each argument separately, separated by spaces; wrap arguments containing spaces in quotes:

<!-- 文件路径:.opencode/commands/create-file.md -->
---
description: Create a new file with content
---

Create a file named $1 in the directory $2
with the following content: $3

Invocation example (arguments containing spaces are wrapped in quotes):

/create-file config.json src "{ \"key\": \"value\" }"

Replacement results for each placeholder:

Placeholder Replaced with
$1 config.json
$2 src
$3 { "key": "value" }

3. Injecting Shell Command Output (!`command`)

Using the!`shell命令`syntax, you can run a Shell command when the command is executed and insert its output directly into the prompt. The Shell command runs in theproject root directory. This is very useful when you need the LLM to analyze real-time data (such as test results, git logs, etc.):

<!-- 文件路径:.opencode/commands/analyze-coverage.md -->
---
description: Analyze test coverage
---

Here are the current test results:
!`npm test`

Based on these results, suggest improvements to increase coverage.
<!-- 文件路径:.opencode/commands/review-changes.md -->
---
description: Review recent git changes
---

Recent git commits:
!`git log --oneline -10`

Review these changes and suggest any improvements or potential issues.

When the command is executed,!`git log --oneline -10`it will be replaced with the actual git log output, and then sent to the LLM together with the prompt.

4. Referencing File Contents (@file_path)

Using the@file pathsyntax, the content of the specified file can be automatically included in the prompt without manual copy-paste:

<!-- 文件路径:.opencode/commands/review-component.md -->
---
description: Review a component for performance issues
---

Review the component in @src/components/Button.tsx.
Check for performance issues and suggest improvements.

When the command is executed,@src/components/Button.tsxit will be replaced with the complete content of the file, allowing the LLM to directly analyze the file code.


Detailed Configuration Options

The following are all configuration options supported by custom commands. In Markdown files, write them in the frontmatter; in JSON configuration, write them under the command object:

Option Required Type Description
template Required (JSON method) String The prompt content sent to the LLM. In the Markdown method, the body itself is the template; no separate declaration is needed.
description Optional String A brief description of the command. When you type/, it is displayed in the TUI command list, helping to quickly identify the command's purpose.
agent Optional String The name of the agent that executes this command. If not specified, the currently selected agent is used. If a subagent is specified, the command triggers a subagent call by default.
subtask Optional Boolean Set totruecan force the command to run as a subagent, avoiding pollution of the main session context. Set tofalsecan prohibit subagent invocation behavior.
model Optional String Overrides the model used by this command, in the formatprovider/model-idsuch asanthropic/claude-3-5-sonnet-20241022

The Relationship Between agent and subtask

agentandsubtaskThey jointly control how the command is executed:

  • ifagentIf the specified agent is a subagent (mode is subagent), the commandtriggers a subagent call by defaultand executes in an independent context without affecting the main session.
  • If you do not want this behavior, setsubtasktofalseto force execution in the main session.
  • If you setsubtasktotrue, regardless of the agent'smodesettings, the command always runs as a subagent, suitable for scenarios requiring complete context isolation.

Example

{
  "$schema": "https://opencode.ai/config.json",
  "command": {
    "analyze": {
      "template": "Analyze the codebase for potential security vulnerabilities.",
      "description": "Security analysis (runs independently, does not pollute the main session)",
      "subtask": true,            // Force it to run as a subagent; the analysis results do not occupy the main session context
      "model": "anthropic/claude-3-5-sonnet-20241022"
    },
    "review": {
      "template": "Review the current code changes.",
      "description": "Code review (runs in the current agent)",
      "agent": "plan",            // Use the plan agent to execute
      "subtask": false            // Disable subagent invocation and run in the main session
    }
  }
}

Comprehensive Usage Examples

Example 1: Multi-parameter Code Generation Command

<!-- 文件路径:.opencode/commands/gen-api.md -->
---
description: Generate a REST API endpoint
agent: build
---

Generate a $1 REST API endpoint for the resource "$2".
Place the file in the $3 directory.
Include input validation, error handling, and JSDoc comments.

<!-- 调用示例:/gen-api POST user src/api -->
<!-- $1 = POST,$2 = user,$3 = src/api -->

Example 2: Code Review Command Combining Shell Output and File References

<!-- 文件路径:.opencode/commands/pr-review.md -->
---
description: Review changes in current branch against main
agent: plan
subtask: true
---

Please review the following changes for code quality, potential bugs, and security issues.

## Recent commits
!`git log main..HEAD --oneline`

## Changed files
!`git diff main --name-only`

## Diff content
!`git diff main`

## Project coding guidelines
@.opencode/AGENTS.md

Provide structured feedback with severity levels (critical / warning / suggestion).

Example 3: Scheduled Data Snapshot Command (JSON Method)

{
  "$schema": "https://opencode.ai/config.json",
  "command": {
    "healthcheck": {
      "description": "Check project health status",
      "template": "Analyze the project health based on the following data:\n\nDependency vulnerabilities:\n!`npm audit --json`\n\nOutdated packages:\n!`npm outdated`\n\nTest results:\n!`npm test -- --passWithNoTests 2>&1 | tail -20`\n\nSummarize the issues by severity and suggest a prioritized action plan.",
      "model": "anthropic/claude-3-5-sonnet-20241022",
      "subtask": true
    }
  }
}
Other Extensions