/** * @license * Copyright 2025 Vybestack LLC * SPDX-License-Identifier: Apache-2.0 */ import { copyToClipboard } from '../utils/commandUtils.js'; import type { SlashCommand, SlashCommandActionReturn } from './types.js'; import { CommandKind } from './types.js'; import { debugLogger } from '@vybestack/llxprt-code-telemetry'; export const copyCommand: SlashCommand = { name: 'copy', description: 'Copy the last result or code snippet to clipboard', kind: CommandKind.BUILT_IN, autoExecute: true, action: async (context, _args): Promise => { const client = context.services.config?.getAgentClient(); // Check if chat is initialized before accessing it if (client == null || client.hasChatInitialized() !== true) { return { type: 'message', messageType: 'info', content: 'No chat history available yet', }; } const chat = client.getChat(); const history = chat.getHistory(); // Get the last message from the AI (ai speaker) const lastAiMessage = history.filter((item) => item.speaker === 'ai').pop(); if (!lastAiMessage) { return { type: 'message', messageType: 'info', content: 'No output in history', }; } // Extract text from the blocks const lastAiOutput = lastAiMessage.blocks .filter( (block): block is { type: 'text'; text: string } => block.type === 'text', ) .map((block) => block.text) .join(''); if (lastAiOutput) { try { await copyToClipboard(lastAiOutput); return { type: 'message', messageType: 'info', content: 'Last output copied to the clipboard', }; } catch (error) { const message = error instanceof Error ? error.message : String(error); debugLogger.debug(message); return { type: 'message', messageType: 'error', content: `Failed to copy to the clipboard. ${message}`, }; } } else { return { type: 'message', messageType: 'info', content: 'Last AI output contains no text to copy.', }; } }, };