Slash commands do not compose

Status Fixed / completed
Maintainer reply ✓ Yes — bcherny
Activity 9 comments · opened Apr 2, 2025 · closed Sep 24, 2025
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

I'm trying to create a few useful slash commands for our codebase, but their usefulness is limited by the fact that they do not compose.

As an example, consider the built-in /pr_comments command. It's nice and useful, and after running it you can simply say "now fix them" to address existing comments.

But I'd like to use /pr_comments in my own slash command /project:fix-pr-comments, and as far as I can tell that doesn't work, because claude doesn't seem aware of what slash commands are at all:

> run the /pr_comments command

⏺ I need to find where /pr_comments command is located and how to run it. Let me search for this in the codebase.

View original on GitHub ↗

9 Comments

bcherny collaborator · 1 year ago

Really interesting idea. We'll explore this.

hesreallyhim · 1 year ago

Yeah I haven't gone down this path personally but the idea of multi-agent workflows and delegating tasks or prompt-chaining seems like this is really important. Also I reallllly wish I could say "please execute the <SLASH_COMMAND>" now, but it's not possible.

hesreallyhim · 1 year ago

Maybe you could experiment with piping commands like claude -p "Review my PR and provide clear instructions for how to improve it" | "Read the provided PR review and come up with a list of sequential tasks" | "pick the smallest task and implement the functionality for it"

wanderingnature · 1 year ago

Try this - it uses both slash commands and bash scripts but it works as far as my trivial POC has shown:

Running chained commands

/project:command1 hello_from_command1 | /project:command2 > /project:command1 is running… hello_from_command1 | /project:command2

● I'll analyze the command and execute it properly as a chained slash command.

● Bash(source functions/command1.sh hello_from_command1)…
⎿output from command 1 with argument: hello_from_command1

● Bash(source functions/command2.sh "output from command 1 with argument: hello_from_command1")…
⎿command2 showing the output from command1: output from command 1 with argument: hello_from_command1

How To: Chained Commands

CLAUDE.md

## Claude Session Guidelines

## Slash Commands
Custom slash commands are stored, per your documentation in the .claude/command directory
You will never search for slash command files, they are in the standard directory

## Slash Command Chaining
Slash command chaining is a user enhancement to Claude Codes custom slash commands

## Slash Command Idenitification
Any use of the string '/project:' refers to Clause custom slash commands and never to a path

## Claude Behavior
Claude will never treat '/project:' as a path but will always treat it as a slash command

## Allow Chained Slash Commands
If the user connects two (or more) slash commands with the unix pipe symbol '|' then consider these commands are chained and the output of the first command should be 'piped' to the second command in the exact same way that the pipe command works in the terminal

## How to run chained slash commands
/project:command1 # runs the slash command command1

A pipe character '|' means that the output shopuld be sent to the command after the '|' character

/project:command1 argument_for_command1 | /project:command2   # runs the slash command command1 with the argument "arg_for_command1" and captures the output, then it runs the slash command /project:command2 [output]

it really is very simple, you just capture the output from the first command and then run the next command as if the user put it directly on the prompt

Command Files

Location: .claude/commands/*.md

command1.md

CLAUDE ACTION:

I will execute command1 and capture [OUTPUT]:

# Get everything after the command itself
RAW_INPUT="$*"
# Extract everything before the first '|'
arg1="${RAW_INPUT%%|*}"
export argument=arg1
source functions/command1.sh $argument

command2.md

CLAUDE ACTION: I will execute command2
export argument=$ARGUMENTS
source functions/command2.sh $argument

Bash Scripts

Location: functions/*.sh

command1.sh

#!/bin/bash
echo "output from command 1 with argument: $1"

command2.sh

#bin/bash
echo "command2 showing the output from command1: $1"

Attention

I did not have much success getting Claude to recognize the '|' character as ending the arguments to the first command (or between any command) - so I put that into the first bash script at the start of the chain:

Get everything after the command itself

RAW_INPUT="$*"

Extract everything before the first '|'

arg1="${RAW_INPUT%%|*}"

which just tosses everything after the '|' - it would get more complicated the more you want to chain commands as you may need to handle the pipe all along the chain...

WarrenZhu050413 · 1 year ago

Second this. It could also be interesting if it is piping between different sub-agents, so that in long pipes the context do not become contaminated.

hesreallyhim · 1 year ago

@wanderingnature fwiw I have proof that Claude is able to hallucinate non-existent slash commands on the spot. I think it kinda knows what a slash command is and it tries really hard to fulfill the user's intention. Like I was able to get "/translate-to-spanish" to work without ever mentioning or defining that command before.

@WarrenZhu050413 that would be great, but I don't think sub agents can communicate with one another directly (at least not with the Sub Agents official functionality)

jleechan2015 · 12 months ago

I made a whole repo with chained slash commands! Works decently well and enables a higher level of automation

https://github.com/jleechanorg/claude-commands

filipesilva · 11 months ago

@bcherny I think the SlashCommand tool in 1.0.123 addresses this issue.

github-actions[bot] · 11 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.