Quieres un prompt de varias líneas en kiro-cli o en la TUI de agent: una lista de requisitos, un diff explicado, contexto que no cabe en una frase. Pulsas Enter y se envía a medias.
Ctrl+J inserta la línea en casi cualquier terminal, incluido tmux. Hasta que lo pulsas dentro de la terminal integrada de VS Code (o de un derivado como Cursor o Kiro IDE) y desaparece el panel.
Este post es corto a propósito. Complementa el mapa de herramientas IAG con un detalle de teclado que esas CLIs documentan mal.
El truco
Enter envía. Ctrl+J inserta el salto de línea.
| Herramienta | Nueva línea (siempre) | Otras, si el terminal las reporta |
|---|---|---|
| OpenCode | Shift+Enter / Ctrl+Enter (la app las intercepta) | (ninguna) |
| Kiro CLI | Ctrl+J | Shift+Enter, Alt+Enter; /editor abre $EDITOR |
Cursor Agent (agent) | Ctrl+J; \ y luego Enter | Shift+Enter; Option+Enter tras /setup-terminal |
Ctrl+J no es un atajo inventado por Kiro. Es el carácter de control que el terminal lleva décadas emitiendo. No hay otro Ctrl+letra que haga lo mismo: J es la décima letra del alfabeto latino, y Ctrl+J es el único byte ASCII 10 (LF). Ctrl+M es CR (el Enter que envía). Ctrl+I es Tab. No existe un «Ctrl+K pero para newline».
Lo que sí existe son otras combinaciones que la TUI interpreta como “nueva línea” sin emitir LF:
| Combinación | Qué viaja por el cable | Dónde funciona de serie |
|---|---|---|
| Ctrl+J | LF (\n, ASCII 10) | Cualquier terminal real; en VS Code el workbench se lo queda |
\ + Enter | barra invertida y luego CR; la TUI lo traduce a newline | Cursor Agent, también en tmux y en la terminal de VS Code |
| Shift+Enter | secuencia con modificador (no es LF) | iTerm2, Ghostty, Kitty, Warp, Zed |
| Alt+Enter / Option+Enter | suele ser ESC+CR u otra secuencia | Terminal.app, Ghostty; VS Code solo tras configurar |
Shift+Enter y Alt+Enter no son Ctrl+J con otra etiqueta. Dependen de que el emulador distinga el modificador. En gnome-terminal, en muchos IDEs y dentro de tmux, Shift+Enter llega como un Enter normal y envía el prompt. Por eso las docs de Cursor y Kiro llaman a Ctrl+J (y, en Agent, a \+Enter) la opción universal.
Kiro documenta /settings terminal para auto-configurar Shift+Enter. Cursor documenta /setup-terminal. Ambos acaban escribiendo un keymap del emulador (en VS Code, un sendSequence) para que esa combinación deje de ser un Enter disfrazado.
Por qué funciona
Un Ctrl+letra no es magia del sistema operativo. En el modelo teletype / VT100, Ctrl más una letra produce el byte letra & 0x1F: el carácter de control correspondiente.
| Atajo | Carácter | ASCII | Equivalente |
|---|---|---|---|
| Ctrl+J | LF | 10 | \n |
| Ctrl+M | CR | 13 | Enter |
| Ctrl+I | HT | 9 | Tab |
| Ctrl+[ | ESC | 27 | Escape |
| Ctrl+D | EOT | 4 | EOF / cerrar input |
| Ctrl+L | FF | 12 | Limpiar pantalla (a menudo) |
| Ctrl+H | BS | 8 | Backspace (a veces) |
Enter es CR (Ctrl+M). Ctrl+J es LF. Kiro y Agent, en la TUI, tratan LF como newline: si el editor se come Ctrl+J antes, no llega nada al input. OpenCode intercepta Shift+Enter a nivel de aplicación y no depende de ese byte.
Hay tres capas, y cada una puede quedarse el evento:
Teclado → terminal (bytes) → TUI (interpretación)
En un emulador de verdad (WezTerm, Alacritty, iTerm2, GNOME Terminal) las tres capas colaboran y Ctrl+J es LF. En la terminal integrada de un IDE la capa del medio es el workbench: decide si el atajo es suyo o del proceso que corre dentro.
Linux y macOS se comportan igual en terminal real. En Windows, Windows Terminal + WSL, Git Bash o SSH también. PowerShell, cmd y cualquier campo de texto de una GUI no siguen estas reglas: ahí Ctrl+J no es LF.
El conflicto en VS Code (y derivados)
En Visual Studio Code, Ctrl+J (Cmd+J en macOS) está ligado a workbench.action.togglePanel: mostrar u ocultar el panel inferior. Cursor, Kiro IDE y el resto de forks heredan el mapa de teclas. Si ejecutas kiro-cli o agent dentro de esa terminal, Ctrl+J no llega al TUI. Llega al workbench. El panel se pliega.
En macOS el atajo del panel suele ser Cmd+J, así que Ctrl+J puede funcionar en la terminal integrada. El roce feo es Linux y Windows, donde Ctrl+J es el toggle del panel.
No hay un segundo Ctrl+… de fábrica que inserte LF y deje Ctrl+J para el panel. En Cursor Agent no hace falta: escribe \ y pulsa Enter. Lo he comprobado en la terminal integrada de Cursor: inserta la línea, no oculta el panel y no toca el keymap. (La documentación de Agent lo da también por bueno en tmux y por SSH.) En Kiro, sin remapear, queda /editor (abre $EDITOR) o pegar texto ya multilínea.
Si quieres Shift+Enter en esa terminal, no es gratis: hay que configurar el IDE (/setup-terminal en Agent, /settings terminal en Kiro), que acaba en un sendSequence. El resto de esta sección es eso: recuperar el LF de Ctrl+J, o mandar el byte 10 con otra tecla.
Dejar que Ctrl+J llegue al TUI
VS Code intercepta una lista de comandos cuando la terminal tiene el foco (terminal.integrated.commandsToSkipShell). workbench.action.togglePanel está en esa lista. Si lo sacas, Ctrl+J vuelve a ser LF para el proceso:
{
"terminal.integrated.commandsToSkipShell": [
"-workbench.action.togglePanel"
]
}
El panel sigue ocultándose con Ctrl+` (el atajo de siempre de la terminal). Solo cedes Ctrl+J mientras el cursor está en la terminal.
Enviar LF con otra tecla
Si no quieres tocar el toggle, manda el byte a mano. \u000a es LF (el mismo 10 que Ctrl+J). No uses \u000d: eso es CR, el Enter que envía el prompt.
{
"key": "ctrl+enter",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u000a" },
"when": "terminalFocus"
}
Elige una combinación que el IDE no reserve ya. Ctrl+Enter a veces está ocupado; Alt+J o Ctrl+Shift+J suelen estar libres. Misma receta en Cursor y Kiro IDE: el comando se llama igual.
También puedes reasignar Ctrl+J solo con la terminal enfocada a ese sendSequence. Entonces Ctrl+J en el editor sigue plegando el panel, y en la terminal inserta la línea. Sigue siendo un cambio de keymap; es el más preciso si vives en el IDE.
No pelear con el IDE
Si \+Enter no te basta o estás en Kiro: abre la TUI en WezTerm, Alacritty o el emulador que ya uses. Ahí Ctrl+J es LF y no hay panel que ocultar. Pegar texto multilínea desde el portapapeles también funciona en casi todas las TUIs.
La TUI del agente y el chat del sidebar de Cursor no son la misma superficie. Este conflicto solo aparece cuando el agente corre en la terminal integrada.
Cierre
Enter envía porque es CR. Ctrl+J inserta una línea porque es LF: no hay otro Ctrl+letra equivalente. Shift+Enter y Alt+Enter son atajos de la TUI, no del terminal, y fallan donde el emulador no reporta el modificador. En Agent, \+Enter cubre ese hueco sin pelear con VS Code. En el resto, o le devuelves el LF al TUI, o escribes el prompt donde el editor no pisa el teclado.