Volver a las novedades

¿Se pueden encolar slash commands en Claude Code?

Respuesta corta: no. Claude Code 2.1.233 no tiene cola de slash commands, y escribir /code-review /clear /simplify en una sola línea no ejecuta tres comandos. Ejecuta el primero y le entrega el resto como texto plano. Medimos seis casos el 16 de agosto de 2026, y el fallo tiene dos formas distintas según qué comando vaya primero. Un único comando personalizado puede ser dueño de una secuencia, y las invocaciones separadas dan algo parecido a empezar de cero, con una salvedad que apareció justo porque nos equivocamos.

¿Se pueden encolar slash commands en Claude Code?

Dentro de la sesión, no. Claude Code trata el primer slash command de la línea como el comando y todo lo que viene después como argumento suyo, así que la cola nunca se forma. Probamos esto en Claude Code versión 2.1.233 el 16 de agosto de 2026, con dos comandos personalizados desechables dentro de .claude/commands/: echoargs, que responde con los argumentos que recibió, y marker, que responde con una cadena fija. Cada ejecución de abajo se repitió en bash, zsh y sh.

Lo que escribimosLo que volvióQué significa
/echoargs /markerARGS=[/marker]El segundo se volvió texto y nunca se ejecutó
/echoargs salto de línea /markerARGS=[/marker]Un salto de línea no envía dos veces
/clear /markervacíoEl integrado primero descarta el resto
/pipeline (un comando, dos fases)PHASE_ONE_DONE PHASE_TWO_DONELa secuencia funciona con un solo dueño
invocación separada, preguntada despuésNO_MEMORYLa conversación no cruza
invocación separada, memoria plantadaMELANCIA99La memoria en archivo puede cruzar

Buscar una opción de cola o de secuencia en la salida de ayuda del CLI de Claude Code no devuelve ninguna coincidencia. Una búsqueda deliberadamente más amplia, por queue, sequence, chain y batch, devuelve dos líneas, y las dos son la palabra chain dentro de keychain, no la palabra suelta. Buscando palabra completa, ambas búsquedas devuelven cero, así que esto es ausencia de una función, no una sintaxis que se nos escapó.

¿Qué pasa cuando pones dos slash commands en la misma línea?

El primer comando se ejecuta y recibe el resto como cadena de argumentos. En Claude Code, un archivo de comando personalizado en .claude/commands/ puede contener el marcador $ARGUMENTS, que se expande a lo que la persona escribió después del nombre del comando. Ese mecanismo es el que absorbe tu segundo comando en silencio: el intérprete ya decidió cuál es el comando, así que /marker dejó de ser un comando y pasó a ser una cadena de siete caracteres que se pasa adelante.

Esto es fácil de no notar porque nada falla. No hay error, no hay aviso y no hay mensaje que diga que un comando fue ignorado. Nuestro comando echoargs existe precisamente para volver visible lo invisible: imprime sus propios argumentos de vuelta, así que ARGS=[/marker] es el intérprete mostrando su trabajo. Sin un comando que haga eco de los argumentos, la misma ejecución produciría solo una respuesta plausible al primer comando, y nunca sabrías que el segundo se evaporó.

Un desarrollador de r/ClaudeCode describió este mecanismo correctamente en un hilo publicado el 16 de agosto de 2026, escribiendo que "you can't queue them on one line. the cli runs the first slash command and passes everything after it to that command as $ARGUMENTS", es decir, que no se pueden encolar en una línea porque el CLI ejecuta el primero y pasa todo el resto como argumento. Otro comentarista del mismo hilo dijo lo contrario, que sí se puede encolar y que él lo hace a menudo. Nuestra medición coincide con el primero y contradice al segundo, y por eso esta pregunta merece medición en vez de encuesta: las dos respuestas estaban una al lado de la otra, sin nada que las separara.

¿Ayuda partir la línea entre los comandos?

No. Enviar /echoargs y /marker separados por un salto de línea devuelve ARGS=[/marker], exactamente el mismo resultado que ponerlos en la misma línea. El salto se lee como parte de una entrada única y no como un segundo envío, así que el segundo comando vuelve a ser absorbido como texto de argumento. Esa es la comprobación número cuatro del script, así que es reproducible en vez de afirmada.

Esto importa porque el salto de línea es lo primero que casi todo el mundo prueba después de que falla la línea única. Parece que debería funcionar: en una terminal, pulsar enter suele significar enviar. En Claude Code la entrada es un bloque, y el bloque se interpreta una sola vez. Saberlo ahorra la segunda ronda de adivinanza, y descarta la solución alternativa más común antes de que alguien construya el hábito de usarla.

Existe una forma parecida que no probamos y sobre la que no afirmaremos nada, que es un here document o un archivo volcado al modo no interactivo con varios comandos dentro. Nuestra medición cubre texto enviado como una sola entrada, tenga o no un salto de línea.

¿Por qué un comando integrado como /clear se comporta distinto?

Porque un comando integrado consume el turno en lugar de pasar el texto adelante. Cuando ejecutamos /clear /marker en Claude Code 2.1.233, la salida fue vacía. Ni error, ni marcador, nada. El /clear hizo su trabajo de limpiar la sesión y el texto posterior no produjo resultado visible, que es un tercer desenlace, distinto tanto de ejecutarse como de ser repetido como eco.

Esto importa justo para la secuencia que la gente quiere montar. La petición que originó esta medición era una cadena de fases de revisión separadas por /clear, con la forma /code-review, luego /clear, luego /simplify. Esa cadena choca con los dos modos de fallo a la vez. Donde un comando personalizado va delante, el /clear siguiente es absorbido como argumento y el contexto nunca se limpia de verdad. Donde el /clear va delante, lo que sigue desaparece. Una cadena hecha con los dos tipos de comando falla de maneras distintas en posiciones distintas, lo que explica cómo dos desarrolladores pueden sostener creencias opuestas sobre el tema: según lo que encadenó cada uno, uno vio una respuesta plausible y el otro no vio nada.

La lección práctica es que un fallo silencioso aquí es peor que uno ruidoso. Si Claude Code rechazara el segundo comando con un mensaje, nadie montaría una pipeline de revisión encima. Como el primer comando responde con normalidad, la cadena puede parecer que funcionó durante semanas.

¿Cómo ejecutar una secuencia de fases en Claude Code?

Escribe un único comando personalizado que sea dueño de toda la secuencia. Creamos un comando pipeline en .claude/commands/ cuyo cuerpo lista dos fases en orden y pide el resultado de cada una en su propia línea. Ejecutar /pipeline devolvió PHASE_ONE_DONE PHASE_TWO_DONE, en ese orden, en todas nuestras ejecuciones en bash, zsh y sh. La secuencia funciona cuando un solo comando responde por ella, porque entonces el orden vive dentro del prompt y no dentro del intérprete.

Esa es la misma salida que propuso el comentarista de r/ClaudeCode, y nuestra medición la respalda. También trae una limitación que conviene declarar antes de que construyas encima: una fase dentro de un comando no es contexto nuevo. Todo lo que la fase uno leyó y escribió sigue en la conversación cuando empieza la fase dos, así que, si el motivo por el que querías el /clear entre fases era impedir que la fase dos heredara las suposiciones de la fase uno, un comando orquestador no te da eso. Te da orden, no aislamiento.

Si el orden es todo lo que necesitas, este es el formato más barato y se queda dentro de una sola sesión. Si necesitas que cada fase empiece limpia, un comando único no lo entrega y las invocaciones separadas se acercan más, aunque no tanto como creíamos al principio.

¿Una invocación separada empieza de verdad de cero?

Casi siempre, y la excepción es lo más útil que medimos. La conversación de verdad no cruza: a una invocación se le pidió recordar la palabra BANANA42 y respondió OK, y una segunda invocación, en el mismo directorio, preguntada por cuál palabra acababa de recibir, respondió NO_MEMORY. Vimos eso en tres ejecuciones seguidas, en bash, zsh y sh, y con ello escribimos la versión segura de sí misma de este artículo.

Entonces una cuarta ejecución respondió BANANA42, y esa versión segura estaba equivocada. Claude Code puede mantener una memoria en ARCHIVO indexada por el directorio de trabajo, guardada bajo .claude/projects, con un índice y un archivo por hecho. La ejecución que rompió nuestra comprobación había escrito la palabra en esa memoria por su cuenta, con marca de tiempo, y la invocación siguiente la leyó de vuelta. De doce directorios de prueba creados durante este trabajo, exactamente uno terminó con la palabra guardada, y fue la ejecución que rompió el resultado. Escribir la memoria es decisión del agente, no una opción que activamos, y un caso entre doce es demasiado fino para publicarse como tasa.

O sea, el NO_MEMORY nunca probó que la memoria no existiera. Probó solo que nada se había escrito aquella vez. Para volver el mecanismo reproducible en lugar de accidental, la última comprobación del script planta un archivo de memoria para el directorio de trabajo y le pide a una invocación nueva que lo lea. Volvió con MELANCIA99 en nueve de nuestros diez intentos, y el único fallo llegó en una ejecución donde la comprobación anterior ya había escrito en esa misma carpeta de memoria. La regla práctica que sobrevive a todo esto: si tus fases no pueden contaminarse entre sí, una invocación separada es necesaria y no suficiente, así que comprueba si existe un directorio de memoria para esa ruta antes de confiar en el aislamiento.

¿Cómo comprobar el comportamiento del intérprete?

El script que produjo todos los números de este artículo está impreso en dos partes, y la parte de abajo trae las cuatro comprobaciones del intérprete. Crea un directorio de trabajo desechable, escribe allí los tres comandos personalizados y ejecuta las comprobaciones que tienen que ver con cómo se interpreta la entrada. Fija un modelo pequeño por defecto para que el coste sea bajo, y eso se cambia con la variable MODEL. Copia esta parte y la parte de la memoria en un solo archivo, en ese orden, y ejecútalo. Las dos partes terminan y empiezan en una línea de comentario, así que nada se rompe si la unión pierde su salto de línea. El script es idéntico en las versiones en español, inglés y portugués de este artículo, con los comentarios y los marcadores dejados en inglés a propósito, porque es código ejecutable y cambiar los marcadores cambiaría la salida que las comprobaciones comparan.

#!/usr/bin/env bash
# Does Claude Code run a queue of slash commands? Six checks.
set -uo pipefail
MODEL="${MODEL:-claude-haiku-4-5-20251001}"

lab=$(mktemp -d) || { echo "no temp dir"; exit 1; }
trap 'rm -rf "$lab"' EXIT
mkdir -p "$lab/.claude/commands"
printf -- '---\ndescription: echo\n---\nReply with exactly: ARGS=[$ARGUMENTS]\n' \
  > "$lab/.claude/commands/echoargs.md"
printf -- '---\ndescription: marker\n---\nReply with exactly: MARKER_TWO_RAN\n' \
  > "$lab/.claude/commands/marker.md"
printf -- '---\ndescription: two phases\n---\nDo both phases in order, one per line:\nPhase 1: reply PHASE_ONE_DONE\nPhase 2: reply PHASE_TWO_DONE\n' \
  > "$lab/.claude/commands/pipeline.md"

# Match only the markers, because a model may wrap them in extra prose.
run() {
  (cd "$lab" && claude -p "$1" --model "$MODEL" < /dev/null 2>/dev/null) \
    | grep -oE 'ARGS=\[[^]]*\]|MARKER_TWO_RAN|PHASE_[A-Z]+_DONE|NO_MEMORY|BANANA42|MELANCIA99' \
    | tr '\n' ' '
}

echo "version: $(claude --version)"
echo "1 two commands one line : $(run '/echoargs /marker')"
echo "2 built-in /clear first : [$(run '/clear /marker')]"
echo "3 one command, 2 phases : $(run '/pipeline')"
echo "4 separated by newline  : $(run '/echoargs
/marker')"
# ---- the memory checks continue below ----

La línea del grep está ahí por algo que encontramos probando: en una de las ejecuciones el modelo envolvió un marcador en una frase extra de explicación, lo que hizo que la salida bruta variara entre ejecuciones aunque la respuesta fuera la misma. Hacer coincidir solo los marcadores mantiene los cuatro resultados comparables de una ejecución a otra.

¿Cómo comprobar el comportamiento de la memoria?

Las dos comprobaciones de memoria continúan el mismo script, y necesitan un aviso que las comprobaciones del intérprete no necesitan. Crean, y después borran, una carpeta dentro de tu propio .claude/projects, porque ahí es donde la memoria plantada tiene que vivir para que la última comprobación signifique algo. Solo se borra la carpeta que corresponde al directorio temporal que el propio script creó. Antes de construir esa ruta de borrado, el script se niega a continuar si la ruta resuelta no tiene aspecto de clave profunda y si tu HOME no está definido, y arma la limpieza antes de crear nada, para que una interrupción en medio no deje atrás la carpeta plantada.

# ---- memory checks ----
run 'Remember the word BANANA42. Reply only OK.' > /dev/null
echo "5 next run remembers?   : $(run 'Which word did I just tell you? If unknown, reply NO_MEMORY.')"

# Check 5 is not reliable on its own, and check 6 says why: Claude Code can
# keep a FILE memory keyed to the working directory, and that does survive a
# new invocation. We plant one and ask a fresh run to read it.
enc=$(printf '%s' "$(cd "$lab" && pwd -P)" | tr '/.' '--')
# Refuse to build a delete path from a value that is not a deep path key.
# An unreadable $lab makes enc empty, which would point the cleanup at the whole
# projects directory; a shallow value like a single dash would point it at a real
# folder that is not ours. Require at least three separators, and a real HOME.
case "$enc" in
  -*-*-*) : ;;
  *) echo "refusing to continue: could not resolve the lab path"; exit 1 ;;
esac
[ -n "${HOME:-}" ] || { echo "refusing to continue: HOME is not set"; exit 1; }
proj="$HOME/.claude/projects/$enc"
mem="$proj/memory"
# Arm the wider cleanup BEFORE creating anything, so a Ctrl-C in between
# cannot leave the planted folder behind.
trap 'rm -rf "$lab" "$proj"' EXIT
mkdir -p "$mem" || { echo "could not create the memory folder"; exit 1; }
printf -- '---\nname: planted\ndescription: word planted by this check\nmetadata:\n  type: reference\n---\n\nMELANCIA99\n' \
  > "$mem/planted.md"
printf -- '- [MELANCIA99](planted.md) - planted word\n' > "$mem/MEMORY.md"
echo "6 file memory crosses?  : $(run 'What is the planted secret word? If you do not know, reply NO_MEMORY.')"

Esa negativa es una cicatriz, y creció en dos etapas, que es la parte que vale copiar a cualquier cosa que escribas que borre por ruta calculada. El primer borrador construía el objetivo del borrado expandiendo una variable sin comprobarla, así que un directorio ilegible dejaba la variable vacía y apuntaba la limpieza a la carpeta de proyectos entera. Añadimos una comprobación de que el valor empieza por un separador, luego atacamos esa comprobación y seguía demasiado floja: un separador solo habría pasado, y existe una carpeta con exactamente ese nombre en una instalación real. Exigir una clave profunda cierra ambos casos, y cada etapa se confirmó forzando el fallo y viendo el script abortar con la carpeta de proyectos intacta.

¿Qué no cubre esta medición?

Cubre una versión en una máquina, y las partes con más probabilidad de envejecer están nombradas para que las vuelvas a comprobar. Todo lo de aquí se midió en Claude Code 2.1.233, en macOS, el 16 de agosto de 2026. El registro de npm lista doce versiones de Claude Code publicadas entre el 3 y el 14 de agosto de 2026, lo que significa que el comportamiento de interpretación descrito aquí es un hecho de vida corta, no una propiedad permanente de la herramienta. Si lees esto meses después, ejecuta el script tú mismo: seis comprobaciones, unos pocos minutos, y tienes la respuesta para la versión que de verdad tienes instalada.

Tres límites más allá de la versión. Probamos el modo no interactivo, claude -p, porque es el modo que un script puede dirigir y comprobar; la sesión interactiva puede aceptar la entrada de otra forma, y no la medimos. Probamos con dos comandos personalizados y uno integrado, no con el conjunto completo de comandos integrados, así que es posible que algún integrado se comporte de una cuarta manera que no vimos. Y sobre la memoria en archivo, establecimos que existe, que sobrevive a una invocación nueva y que el agente a veces la escribe sin que se lo pidan, pero ni escribirla ni leerla resultó del todo determinista en nuestras ejecuciones, y no mapeamos qué decide ninguna de las dos cosas.

Una cosa más que vale decir sin rodeos, ya que vendemos una herramienta en esta área. CanvasCode, nuestra app de Mac que ejecuta las CLIs oficiales de agente lado a lado en un solo canvas, no añade una cola de slash commands a Claude Code ni podría, porque la interpretación ocurre dentro del CLI. Lo que cambia ejecutar varios agentes lado a lado es que las fases que no dependen entre sí pueden ejecutarse a la vez en lugar de en fila, que es un problema distinto del que mide este artículo.