diff --git a/pkg/tui/commands/commands.go b/pkg/tui/commands/commands.go index f3eeed72f..1deacef21 100644 --- a/pkg/tui/commands/commands.go +++ b/pkg/tui/commands/commands.go @@ -107,6 +107,26 @@ func builtInSessionCommands() []Item { return core.CmdHandler(messages.ExitSessionMsg{}) }, }, + { + ID: "session.quit", + Label: "Quit", + SlashCommand: "/quit", + Description: "Quit the application (alias for /exit)", + Category: "Session", + Execute: func(string) tea.Cmd { + return core.CmdHandler(messages.ExitSessionMsg{}) + }, + }, + { + ID: "session.q", + Label: "Quit (short)", + SlashCommand: "/q", + Description: "Quit the application (alias for /exit)", + Category: "Session", + Execute: func(string) tea.Cmd { + return core.CmdHandler(messages.ExitSessionMsg{}) + }, + }, { ID: "session.export", Label: "Export", diff --git a/pkg/tui/page/chat/chat.go b/pkg/tui/page/chat/chat.go index 357e297db..7eb86530f 100644 --- a/pkg/tui/page/chat/chat.go +++ b/pkg/tui/page/chat/chat.go @@ -624,6 +624,13 @@ func (p *chatPage) cancelStream(showCancelMessage bool) tea.Cmd { // handleSendMsg handles incoming messages from the editor, either processing // them immediately or queuing them if the agent is busy. func (p *chatPage) handleSendMsg(msg msgtypes.SendMsg) (layout.Model, tea.Cmd) { + // Handle "exit", "quit", and ":q" as special keywords to quit the session + // immediately, equivalent to the /exit slash command. + switch strings.TrimSpace(msg.Content) { + case "exit", "quit", ":q": + return p, core.CmdHandler(msgtypes.ExitSessionMsg{}) + } + // Predefined slash commands (e.g., /yolo, /exit, /compact) execute immediately // even while the agent is working - they're UI commands that don't interrupt the stream. // Custom agent commands (defined in config) should still be queued.