Skip to main content
luke@terminal:/blog$ ls
luke@terminal:/blog$ cat opencode-nested-slash-commands-architecture.md

OpenCode Nested Commands: $1 Solution, -102 Lines

Created: 2026-01-13 | 2 min read

Here's what tripped me up: I tried to make a slash command call another slash command.

I had two commands doing basically the same thing. One was my 4-agent blog review system—495 lines of voice validation, completeness checking, structure editing, and technical validation. The other was a wrapper that auto-selects the next post needing review, then calls the first command. 239 lines of tracking and selection logic.

What I Tried (and Why It Failed)

The wrapper command was supposed to be simple: /review-next-blog-post. This wrapper then called the custom slash command /review-blog-post-multi-agent @content/posts/specific-post on the "next" post to be reviewed in my list of posts, based on criteria I defined.

I tried different variations. Maybe the slash command syntax was wrong? Maybe I needed quotes or a different calling pattern? Still nothing. I spent way too long wondering why OpenCode was just... ignoring my nested command call.

Turns out OpenCode slash commands can't call other slash commands. Each command is like a separate executable. You can't have command-a trigger command-b from within command-a's definition.

The Realization

This actually makes sense—predictable behavior, no infinite loops, no command calling itself. But I didn't know that going in, and the lack of error feedback made the confusion worse.

I thought about a few options:

  • Could I work around this somehow with some intermediate command?
  • Maybe use the CLI tool to trigger commands?
  • Wait—what if I just made one command do both?

The last option felt right. Instead of trying to make commands nested, I needed a single command that could operate in two different modes.

The Solution: One Command, Two Modes OpenCode's $1 argument system handles this perfectly:

**Auto-Selection Mode (no arguments):**
`/review-blog-post-multi-agent`

**Direct Review Mode (specific post):**
`/review-blog-post-multi-agent @content/posts/blog-post-slug.md` or `path/to/blog-post.md`

**Mode Selection Logic:**
- If `$1` is provided AND not empty → Direct Review Mode
- If `$1` is empty or missing → Auto-Selection Mode

If $1 is provided, use the file directly. If it's missing, run auto-selection. The command now does both modes in one place—finds the next post OR reviews the one you specify.

The Result

The consolidation was a net improvement: from 2 commands totaling 734 lines to 1 command with 632 lines. That's -102 lines while adding more functionality.

Here's what changed:

  • Tracking logic: Moved from the wrapper command into project_docs/blog-review-tracking.json as reusable content
  • Auto-selection logic: Now part of the main command instead of a separate wrapper
  • Architecture: No nested dependencies—just one command that can operate in two modes
  • Usage: I can run /review-blog-post-multi-agent for auto-selection OR /review-blog-post-multi-agent @content/posts/specific-post.md for direct review