mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-14 03:30:26 +00:00
feat(ui): add /copy slash command to copy last message
- Register /copy (alias /cp) in the System command category - Walk the scrollback to find the last user/assistant/reasoning message, skipping transient system messages - Reuse internal/ui/clipboard.CopyToClipboard for OSC 52 + native clipboard support (works over SSH) - Document the command in /help
This commit is contained in:
@@ -161,6 +161,12 @@ var SlashCommands = []SlashCommand{
|
|||||||
Category: "Navigation",
|
Category: "Navigation",
|
||||||
Aliases: []string{"/r"},
|
Aliases: []string{"/r"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "/copy",
|
||||||
|
Description: "Copy the last message to the system clipboard",
|
||||||
|
Category: "System",
|
||||||
|
Aliases: []string{"/cp"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "/export",
|
Name: "/export",
|
||||||
Description: "Export session (JSONL by default, or /export path.jsonl)",
|
Description: "Export session (JSONL by default, or /export path.jsonl)",
|
||||||
|
|||||||
@@ -3110,6 +3110,8 @@ func (m *AppModel) handleSlashCommand(sc *commands.SlashCommand, args string) te
|
|||||||
return m.handleResumeCommand()
|
return m.handleResumeCommand()
|
||||||
case "/export":
|
case "/export":
|
||||||
return m.handleExportCommand(args)
|
return m.handleExportCommand(args)
|
||||||
|
case "/copy":
|
||||||
|
return m.handleCopyCommand()
|
||||||
case "/share":
|
case "/share":
|
||||||
return m.handleShareCommand()
|
return m.handleShareCommand()
|
||||||
case "/import":
|
case "/import":
|
||||||
@@ -3524,6 +3526,7 @@ func (m *AppModel) printHelpMessage() {
|
|||||||
"**System:**\n" +
|
"**System:**\n" +
|
||||||
"- `/compact [instructions]`: Summarise older messages to free context space\n" +
|
"- `/compact [instructions]`: Summarise older messages to free context space\n" +
|
||||||
"- `/clear`: Clear message history\n" +
|
"- `/clear`: Clear message history\n" +
|
||||||
|
"- `/copy`: Copy the last message to the system clipboard\n" +
|
||||||
"- `/export [path]`: Export session as JSONL\n" +
|
"- `/export [path]`: Export session as JSONL\n" +
|
||||||
"- `/import <path.jsonl>`: Import session from JSONL file\n" +
|
"- `/import <path.jsonl>`: Import session from JSONL file\n" +
|
||||||
"- `/reset-usage`: Reset usage statistics\n" +
|
"- `/reset-usage`: Reset usage statistics\n" +
|
||||||
@@ -4284,6 +4287,48 @@ func (m *AppModel) handleNameCommand(args string) tea.Cmd {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleCopyCommand copies the last user or assistant message to the system
|
||||||
|
// clipboard. Skips transient system messages (e.g. /help output) so the user
|
||||||
|
// gets the actual last conversational message.
|
||||||
|
func (m *AppModel) handleCopyCommand() tea.Cmd {
|
||||||
|
if len(m.messages) == 0 {
|
||||||
|
m.printSystemMessage("No messages to copy.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
text string
|
||||||
|
role string
|
||||||
|
)
|
||||||
|
for i := len(m.messages) - 1; i >= 0; i-- {
|
||||||
|
switch msg := m.messages[i].(type) {
|
||||||
|
case *TextMessageItem:
|
||||||
|
if msg.role == "user" || msg.role == "assistant" {
|
||||||
|
text = msg.content
|
||||||
|
role = msg.role
|
||||||
|
}
|
||||||
|
case *StreamingMessageItem:
|
||||||
|
if msg.role == "assistant" || msg.role == "reasoning" {
|
||||||
|
text = msg.content.String()
|
||||||
|
role = msg.role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if text != "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(text) == "" {
|
||||||
|
m.printSystemMessage("No copyable message found.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m.printSystemMessage(fmt.Sprintf(
|
||||||
|
"Copied last %s message to clipboard (%d chars).", role, len(text),
|
||||||
|
))
|
||||||
|
return clipboard.CopyToClipboard(text)
|
||||||
|
}
|
||||||
|
|
||||||
// handleExportCommand exports the current session to a file.
|
// handleExportCommand exports the current session to a file.
|
||||||
// Usage: /export — copies the JSONL file to cwd with a descriptive name.
|
// Usage: /export — copies the JSONL file to cwd with a descriptive name.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user