# Opencode Commands

> A Claude skill from Timmy6942025/opencode-builder-skill.

- **Type:** Skill
- **Install:** `agentstack add skill-timmy6942025-opencode-builder-skill-opencode-commands`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Timmy6942025](https://agentstack.voostack.com/s/timmy6942025)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Timmy6942025](https://github.com/Timmy6942025)
- **Source:** https://github.com/Timmy6942025/opencode-builder-skill/tree/main/skills/opencode-commands

## Install

```sh
agentstack add skill-timmy6942025-opencode-builder-skill-opencode-commands
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# OpenCode Custom Commands

> **📚 Official Docs:** For the latest information, always refer to the official documentation:
> [https://opencode.ai/docs/commands/](https://opencode.ai/docs/commands/)

Expert skill for building, configuring, and troubleshooting OpenCode's custom command system. Covers markdown command files, JSON configuration, prompt placeholders, command options, built-in commands, keybinds, and overriding built-ins.

## Overview

OpenCode's custom command system lets you define reusable prompts that execute via slash commands in the TUI (e.g., `/test`, `/review`, `/deploy`). Commands are triggered by typing `/` followed by the command name in the prompt input.

Custom commands are **in addition to** the built-in commands like `/init`, `/undo`, `/redo`, `/share`, `/help`. Custom commands can also **override** built-in command names — if you define a custom command with the same name as a built-in, the custom version takes precedence.

Commands support prompt placeholders (`$ARGUMENTS`, `$1`, `$2`, `!`command``, `@filename`) for dynamic prompt construction, and options for agent routing, model override, and subagent invocation.

---

## Create via Markdown

The primary way to create custom commands is by placing markdown files in the `commands/` directory.

### Location

| Scope     | Path                            |
|-----------|----------------------------------|
| Project   | `.opencode/commands/`            |
| Global    | `~/.config/opencode/commands/`   |

The **file name** (minus `.md` extension) becomes the command name:

| File Name               | Command         |
|-------------------------|-----------------|
| `test.md`               | `/test`         |
| `review.md`             | `/review`       |
| `deploy-staging.md`     | `/deploy-staging` |
| `create-component.md`   | `/create-component` |

### Structure

A markdown command file has two parts:

1. **Frontmatter** (YAML between `---` delimiters) — defines command properties
2. **Content** (everything after the closing `---`) — becomes the prompt template sent to the LLM

### Frontmatter Fields

| Field         | Required | Description                                                                 |
|---------------|----------|-----------------------------------------------------------------------------|
| `description` | No       | Short description shown in the TUI command list when typing `/`             |
| `agent`       | No       | Which agent executes this command. If the agent is a subagent, triggers subagent invocation by default |
| `model`       | No       | Override the default model for this command                                  |

### Complete Example

Create `.opencode/commands/test.md`:

```markdown
---
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.
```

Usage in TUI:

```
/test
```

### Multi-line Prompts

The content after the frontmatter is the prompt template. You can use multiple paragraphs, code blocks, and any markdown formatting — everything is sent as-is to the LLM:

```markdown
---
description: Refactor module with best practices
---

You are a senior software engineer. Analyze the following module and refactor it according to these principles:

1. Single Responsibility Principle
2. DRY (Don't Repeat Yourself)
3. Clear naming conventions
4. Proper error handling

Ensure all existing tests still pass after refactoring.
```

### Nested Directories

Commands can be organized in subdirectories. The directory structure maps to a namespace:

```
.opencode/commands/
├── test.md              → /test
├── review.md            → /review
└── db/
    ├── migrate.md       → /db/migrate
    └── seed.md          → /db/seed
```

> **Note:** The exact namespace separator behavior depends on your OpenCode version. Verify with `!ls .opencode/commands/` if unsure.

---

## Create via JSON

You can also define commands in `opencode.json` (or `opencode.jsonc`) using the `command` field.

### JSON Configuration

```jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "command": {
    // This key becomes the command name
    "test": {
      // Required: the prompt sent to the LLM
      "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.",
      // Shown in TUI command list
      "description": "Run tests with coverage",
      // Which agent executes (optional)
      "agent": "build",
      // Override model (optional)
      "model": "anthropic/claude-3-5-sonnet-20241022"
    }
  }
}
```

Usage:

```
/test
```

### JSON vs Markdown

| Aspect              | JSON (`opencode.json`)         | Markdown (`.opencode/commands/`) |
|---------------------|-------------------------------|----------------------------------|
| Location            | Project root config file       | Dedicated directory              |
| Template field      | `template` (string, `\n` for newlines) | Content after frontmatter (natural newlines) |
| Multi-command       | All in one file                | One file per command             |
| Version control     | Changes mixed with other config | Isolated per command file        |
| Discoverability     | Requires reading config        | Browsable via file tree          |

**Recommendation:** Use markdown files for most custom commands. Use JSON for quick one-off commands or when you prefer centralized configuration.

---

## Prompt Placeholders

Prompt placeholders allow dynamic content injection into your command templates. They are evaluated at runtime when the command is executed.

### `$ARGUMENTS` — All Arguments as Single String

The `$ARGUMENTS` placeholder is replaced with **all arguments** passed to the command as a single concatenated string.

**Markdown example:**

```markdown
---
description: Create a new component
---

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

**JSON example:**

```json
{
  "command": {
    "component": {
      "template": "Create a new React component named $ARGUMENTS with TypeScript support.\nInclude proper typing and basic structure.",
      "description": "Create a new component"
    }
  }
}
```

**Usage:**

```
/component Button
```

**Resulting prompt:**

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

**Usage with multiple words:**

```
/component UserAvatar with image loading
```

**Resulting prompt:**

```
Create a new component named UserAvatar with image loading with TypeScript support.
Include proper typing and basic structure.
```

> **Note:** `$ARGUMENTS` captures everything after the command name as one string, including spaces. It does not split on spaces.

---

### `$1`, `$2`, `$3` — Positional Arguments

Individual arguments are accessed via positional parameters. Arguments are split by whitespace.

**Markdown example:**

```markdown
---
description: Create a new file with content
---

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

**JSON example:**

```json
{
  "command": {
    "create-file": {
      "template": "Create a file named $1 in the directory $2\nwith the following content: $3",
      "description": "Create a new file with content"
    }
  }
}
```

**Usage:**

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

**Resulting prompt:**

```
Create a file named config.json in the directory src
with the following content: { "key": "value" }
```

**Positional argument mapping:**

| Placeholder | Value        |
|-------------|--------------|
| `$1`        | `config.json`|
| `$2`        | `src`        |
| `$3`        | `{ "key": "value" }` |

**Additional positional arguments:**

- `$4`, `$5`, `$6`, ... — Access arguments by position (up to the number of arguments provided)
- Unreferenced positional parameters are simply ignored in the prompt

**Multi-word arguments:** Positional parameters split on whitespace. To pass a multi-word value as a single positional argument, quote it:

```
/create-file README.md . "Hello World"
```

This maps:
- `$1` → `README.md`
- `$2` → `.`
- `$3` → `Hello World`

---

### `!`command`` — Inject Bash Command Output

Use backtick syntax with `!` prefix to run a bash command and inject its output directly into the prompt. The command runs in your project's root directory.

**Syntax:** `!`command``

**Markdown example — Analyze test coverage:**

```markdown
---
description: Analyze test coverage
---

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

Based on these results, suggest improvements to increase coverage.
```

**Markdown example — Review recent changes:**

```markdown
---
description: Review recent changes
---

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

Review these changes and suggest any improvements.
```

**Markdown example — Check project structure:**

```markdown
---
description: Analyze project structure
---

Project file tree:
!`find . -type f -name "*.ts" | head -30`

Analyze the module organization and suggest improvements.
```

**JSON example:**

```json
{
  "command": {
    "review-changes": {
      "template": "Recent git commits:\n!`git log --oneline -10`\n\nReview these changes and suggest any improvements.",
      "description": "Review recent changes"
    }
  }
}
```

**Behavior:**

- The bash command executes in the project's root directory
- stdout is captured and inserted into the prompt at the placeholder position
- stderr is typically not included (or handled silently)
- If the command fails, the output may be empty or contain an error message
- The command runs synchronously — the prompt is not sent until the command completes
- Multiple `!`command`` placeholders can be used in a single prompt

**Advanced examples:**

```markdown
---
description: Check dependency versions
---

Current dependencies:
!`cat package.json | jq '.dependencies'`

Check for outdated or vulnerable packages.
```

```markdown
---
description: Lint and format check
---

Lint output:
!`npm run lint 2>&1`

Format check:
!`npx prettier --check . 2>&1`

Fix any issues found.
```

---

### `@filename` — Include File Content

Use `@` followed by a filename to include the file's content in the prompt. The file path is relative to the project root.

**Syntax:** `@filename` or `@path/to/file`

**Markdown example — Review a component:**

```markdown
---
description: Review component
---

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

**Markdown example — Compare files:**

```markdown
---
description: Compare implementations
---

Compare these two implementations:
@src/utils/old-helper.ts
@src/utils/new-helper.ts

Identify the differences and explain which approach is better.
```

**JSON example:**

```json
{
  "command": {
    "review-component": {
      "template": "Review the component in @src/components/Button.tsx.\nCheck for performance issues and suggest improvements.",
      "description": "Review component"
    }
  }
}
```

**Behavior:**

- The file content is resolved relative to the project root directory
- The file's content is included verbatim in the prompt
- The LLM receives the file content as context
- If the file does not exist, the placeholder may be included as-is or produce an error depending on the OpenCode version
- Multiple `@` references can be used in a single prompt

**Fuzzy file search:** In the TUI prompt input (outside of commands), typing `@` triggers a fuzzy file search. Inside command templates, `@` references are resolved literally by path.

---

## Command Options

Each custom command supports the following configuration options. These can be set in JSON (`opencode.json`) or via frontmatter in markdown files.

### template (Required for JSON; implicit in Markdown)

The prompt that will be sent to the LLM when the command is executed.

**In JSON:** The `template` field is **required**. Use `\n` for newlines within the string.

```json
{
  "command": {
    "test": {
      "template": "Run the full test suite with coverage report.\nFocus on failures and suggest fixes."
    }
  }
}
```

**In Markdown:** The template is the **content after the frontmatter**. No separate field needed — everything below the closing `---` becomes the template.

```markdown
---
description: Run tests
---

Run the full test suite with coverage report.
Focus on failures and suggest fixes.
```

---

### description

A brief description of what the command does. This is displayed in the TUI command list when you type `/` and is purely informational.

**In JSON:**

```json
{
  "command": {
    "test": {
      "template": "...",
      "description": "Run tests with coverage"
    }
  }
}
```

**In Markdown frontmatter:**

```markdown
---
description: Run tests with coverage
---
```

**In TUI:** When you type `/`, the command list shows each command's description next to its name:

```
/test      Run tests with coverage
/review    Review code changes
/deploy    Deploy to staging
```

---

### agent

Optionally specify which [agent](https://opencode.ai/docs/agents/) should execute this command. If the specified agent is a [subagent](https://opencode.ai/docs/agents/#subagents), the command will trigger a subagent invocation by default (see `subtask` below).

**In JSON:**

```json
{
  "command": {
    "review": {
      "template": "Review the recent code changes for quality and correctness.",
      "agent": "plan"
    }
  }
}
```

**In Markdown frontmatter:**

```markdown
---
description: Review code
agent: plan
---

Review the recent code changes for quality and correctness.
```

**Behavior:**

- If `agent` is not specified, the command uses the current agent (the one active in the session)
- If `agent` specifies a subagent, the command automatically invokes it as a subagent (unless `subtask: false` is set)
- If `agent` specifies the primary agent, the command runs in the primary context (unless `subtask: true` is set)

---

### subtask

A boolean that **forces** the command to trigger a [subagent](https://opencode.ai/docs/agents/#subagents) invocation. This is useful when you want the command to run in an isolated context without polluting your primary conversation.

**In JSON:**

```json
{
  "command": {
    "analyze": {
      "template": "Analyze the codebase for security vulnerabilities.",
      "subtask": true
    }
  }
}
```

**In Markdown frontmatter:**

```markdown
---
description: Security analysis
subtask: true
---

Analyze the codebase for security vulnerabilities.
```

**Behavior:**

- When `subtask: true`, the agent acts as a subagent regardless of its `mode` setting in agent configuration
- When `subtask: false`, the agent runs in its default mode even if it's a subagent
- If not specified, defaults to `false` unless the `agent` is a subagent (in which case it defaults to `true`)

**Use cases for `subtask: true`:**

- Long-running analysis that shouldn't block the main conversation
- Tasks where you want results returned without full conversation context
- Parallel execution of independent tasks
- Keeping the primary context clean for focused work

---

### model

Override the default model for this command. Useful when a specific task benefits from a different model (e.g., a reasoning-heavy task using a more capable model, or a simple task using a faster/cheaper model).

**In JSON:**

```json
{
  "command": {
    "analyze": {
      "template": "Analyze this codebase for architectural issues.",
      "model": "anthropic/claude-3-5-sonnet-20241022"
    }
  }
}
```

**In Markdown frontmatter:**

```markdown
---
description: Architectural analysis
model: anthropic/claude-3-5-sonnet-20241022
---

Analyze this codebase for architectural issues.
```

**Common model override patterns:**

| Use Case                        | Model St

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Timmy6942025](https://github.com/Timmy6942025)
- **Source:** [Timmy6942025/opencode-builder-skill](https://github.com/Timmy6942025/opencode-builder-skill)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-timmy6942025-opencode-builder-skill-opencode-commands
- Seller: https://agentstack.voostack.com/s/timmy6942025
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
