Clipboard History Service
8.3 ClipboardHistoryService — Full clipboard access
Runs in: view only. Clipboard reads/writes are tied to user interaction and live in the view's proxy bag.
Permission required: clipboard:read for reads, clipboard:write for writes.
interface IClipboardHistoryService {
// Read
readCurrentClipboard(): Promise<{ type: ClipboardItemType; content: string }>;
readCurrentText(): Promise<string>;
getRecentItems(limit?: number): Promise<ClipboardHistoryItem[]>;
// Write
writeToClipboard(item: ClipboardHistoryItem): Promise<void>;
pasteItem(item: ClipboardHistoryItem): Promise<void>;
simulatePaste(): Promise<boolean>;
// Manage history
toggleItemFavorite(itemId: string): Promise<boolean>;
deleteItem(itemId: string): Promise<boolean>;
clearNonFavorites(): Promise<boolean>;
// Utilities
formatClipboardItem(item: ClipboardHistoryItem): string;
normalizeImageData(content: string): string;
isValidImageData(content: string): boolean;
initialize(): Promise<void>;
stopMonitoring(): void;
hideWindow(): Promise<void>;
}
// Clipboard item types
enum ClipboardItemType {
Text = 'text',
Html = 'html',
Rtf = 'rtf',
Image = 'image',
Files = 'files',
}
// Optional metadata captured with the item (shape depends on type)
interface ClipboardItemMetadata {
width?: number; // Image items
height?: number; // Image items
fileCount?: number; // Files items
fileNames?: string[]; // Files items
sizeBytes?: number;
mimeType?: string;
}
// Source application info captured at copy time.
// bundleId is set on macOS; path is set on Windows/Linux (and macOS bundle path).
// iconUrl is resolved from the icon cache at capture time — may be absent.
interface ClipboardSourceApp {
name: string;
bundleId?: string;
path?: string;
windowTitle?: string;
iconUrl?: string;
}
interface ClipboardHistoryItem {
id: string;
type: ClipboardItemType;
content?: string;
preview?: string;
createdAt: number;
favorite: boolean;
metadata?: ClipboardItemMetadata;
sourceApp?: ClipboardSourceApp;
}
Usage:
const clip = context.getService<IClipboardHistoryService>('clipboard');
// Read what is currently on the clipboard (format-aware)
const current = await clip.readCurrentClipboard();
if (current.type === 'text') {
console.log(current.content);
}
// Read the current clipboard as plain text, regardless of flavor (HTML/RTF/files
// are coerced to their text representation). Useful when feeding clipboard
// content into search, URL templates, or snippets.
const text = await clip.readCurrentText();
// Get the 20 most recent clipboard history items
const items = await clip.getRecentItems(20);
// Each item may carry the app it was copied from (name + icon + window title).
// Useful for building filters ("show only items from Chrome") or for providing
// richer UI in clipboard-manager extensions.
for (const item of items) {
if (item.sourceApp) {
console.log(`${item.preview} — from ${item.sourceApp.name}`);
}
}
// Write a new text item to the clipboard
await clip.writeToClipboard({
id: crypto.randomUUID(),
type: ClipboardItemType.Text,
content: 'Hello from my extension',
createdAt: Date.now(),
favorite: false,
});
// Paste an item by simulating keyboard paste
await clip.pasteItem(items[0]);
// Favorite/unfavorite an item (survives clearNonFavorites)
const isFavorite = await clip.toggleItemFavorite(items[0].id);
// Delete a specific item
await clip.deleteItem(items[0].id);
// Check if a content string is valid base64 image data
if (clip.isValidImageData(someContent)) {
const normalized = clip.normalizeImageData(someContent);
}