Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/kimi_cli/ui/shell/slash.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from kimi_cli.ui.shell.mcp_status import render_mcp_console
from kimi_cli.ui.shell.task_browser import TaskBrowserApp
from kimi_cli.utils.changelog import CHANGELOG
from kimi_cli.utils.clipboard import copy_text_to_clipboard
from kimi_cli.utils.datetime import format_relative_time
from kimi_cli.utils.slashcmd import SlashCommand, SlashCommandRegistry

Expand Down Expand Up @@ -537,6 +538,46 @@ async def title(app: Shell, args: str):
console.print(f"[green]Session title set to: {new_title}[/green]")


@registry.command
def copy(app: Shell, args: str):
"""Copy the latest assistant response to the system clipboard"""
soul = ensure_kimi_soul(app)
if soul is None:
return

if args.strip():
console.print("[yellow]Usage: /copy[/yellow]")
return

latest_text: str | None = None
saw_assistant = False

for message in reversed(soul.context.history):
if message.role != "assistant":
continue

saw_assistant = True
text = message.extract_text(sep="\n").strip()
if text:
latest_text = text
break
Comment on lines +560 to +563
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Copy only the most recent assistant message

The /copy loop currently keeps scanning past the newest assistant message until it finds any earlier assistant message with non-empty text, so if the latest assistant turn contains no text (for example, a tool-call-only assistant message), the command will silently copy an older reply instead of reporting that the latest response is not copyable. This can copy stale content and mislead users who expect /copy to reflect the most recent assistant output.

Useful? React with 👍 / 👎.


if latest_text is None:
if saw_assistant:
console.print("[yellow]The latest assistant response has no text to copy.[/yellow]")
else:
console.print("[yellow]No assistant response found to copy.[/yellow]")
return

try:
copy_text_to_clipboard(latest_text)
except Exception as exc:
console.print(f"[red]Failed to copy to clipboard: {exc}[/red]")
return

console.print("[green]Copied the latest assistant response to clipboard.[/green]")


@registry.command(name="sessions", aliases=["resume"])
async def list_sessions(app: Shell, args: str):
"""List sessions and resume optionally"""
Expand Down
5 changes: 5 additions & 0 deletions src/kimi_cli/utils/clipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ def is_clipboard_available() -> bool:
return False


def copy_text_to_clipboard(text: str) -> None:
"""Copy plain text to the system clipboard."""
pyperclip.copy(text)


def grab_media_from_clipboard() -> ClipboardResult | None:
"""Read media from the clipboard.

Expand Down
Loading