onin-sdk 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -0
- package/dist/api/__tests__/clipboard-metadata.test.d.ts +4 -0
- package/dist/api/__tests__/lifecycle.test.d.ts +4 -0
- package/dist/api/ai.d.ts +124 -0
- package/dist/api/clipboard.d.ts +346 -0
- package/dist/api/command.d.ts +213 -0
- package/dist/api/dialog.d.ts +285 -0
- package/dist/api/fs.d.ts +198 -0
- package/dist/api/lifecycle.d.ts +139 -0
- package/dist/api/notification.d.ts +118 -0
- package/dist/api/request.d.ts +200 -0
- package/dist/api/scheduler.d.ts +142 -0
- package/dist/api/settings.d.ts +223 -0
- package/dist/api/storage.d.ts +379 -0
- package/dist/api/window.d.ts +74 -0
- package/dist/core/adapters/base.d.ts +75 -0
- package/dist/core/adapters/index.d.ts +10 -0
- package/dist/core/adapters/inline.d.ts +17 -0
- package/dist/core/adapters/postmessage.d.ts +47 -0
- package/dist/core/adapters/window.d.ts +37 -0
- package/dist/core/dispatch.d.ts +46 -0
- package/dist/core/environment.d.ts +26 -0
- package/dist/core/ipc.d.ts +66 -0
- package/dist/core/runtime.d.ts +64 -0
- package/dist/event-DiwgtsjL.js +29 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +1538 -0
- package/dist/index.umd.cjs +1 -0
- package/dist/types/errors.d.ts +210 -0
- package/dist/types/permissions.d.ts +208 -0
- package/dist/utils/debug.d.ts +23 -0
- package/dist/utils/error-parser.d.ts +64 -0
- package/dist/utils/retry.d.ts +123 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Onin Plugin SDK
|
|
2
|
+
|
|
3
|
+
Onin 插件开发 SDK,提供完整的 API 支持。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install onin-plugin-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { command, notification, storage } from 'onin-plugin-sdk';
|
|
15
|
+
|
|
16
|
+
// 注册动态命令
|
|
17
|
+
await command.register({
|
|
18
|
+
code: 'hello-world',
|
|
19
|
+
name: 'Hello World',
|
|
20
|
+
keywords: [{ name: 'hello' }],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// 处理命令执行
|
|
24
|
+
await command.handle((code, args) => {
|
|
25
|
+
if (code === 'hello-world') {
|
|
26
|
+
notification.show({
|
|
27
|
+
title: 'Hello!',
|
|
28
|
+
body: 'Welcome to Onin Plugin SDK',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API 概览
|
|
35
|
+
|
|
36
|
+
### Command API
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// 动态注册命令
|
|
40
|
+
await command.register({
|
|
41
|
+
code: 'my-command',
|
|
42
|
+
name: '我的命令',
|
|
43
|
+
keywords: [{ name: '关键词' }],
|
|
44
|
+
matches: [{ type: 'text', name: '文本匹配', min: 1 }],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// 处理命令执行
|
|
48
|
+
await command.handle((code, args) => {
|
|
49
|
+
console.log('收到命令:', code, args);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// 移除动态命令
|
|
53
|
+
await command.remove('my-command');
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Notification API
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
await notification.show({
|
|
60
|
+
title: '标题',
|
|
61
|
+
body: '内容',
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Storage API
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
await storage.setItem('key', { data: 'value' });
|
|
69
|
+
const value = await storage.getItem('key');
|
|
70
|
+
await storage.removeItem('key');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### HTTP API
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const response = await http.get('https://api.example.com/data');
|
|
77
|
+
const data = await http.post('https://api.example.com/create', {
|
|
78
|
+
body: JSON.stringify({ name: 'test' }),
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### File System API
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
await fs.writeFile('data.json', JSON.stringify(data));
|
|
86
|
+
const content = await fs.readFile('data.json');
|
|
87
|
+
const exists = await fs.exists('data.json');
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Dialog API
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const result = await dialog.confirm({
|
|
94
|
+
title: '确认',
|
|
95
|
+
message: '是否继续?',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const files = await dialog.open({
|
|
99
|
+
multiple: true,
|
|
100
|
+
filters: [{ name: 'Images', extensions: ['png', 'jpg'] }],
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Clipboard API
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const text = await clipboard.readText();
|
|
108
|
+
await clipboard.writeText('Hello');
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 类型定义
|
|
112
|
+
|
|
113
|
+
所有 API 都有完整的 TypeScript 类型定义,编辑器会自动提供智能提示。
|
|
114
|
+
|
|
115
|
+
## 更多文档
|
|
116
|
+
|
|
117
|
+
查看 [完整 API 文档](./docs) 获取更多信息。
|
package/dist/api/ai.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
export type MessageContent = {
|
|
2
|
+
type: 'text';
|
|
3
|
+
text: string;
|
|
4
|
+
} | {
|
|
5
|
+
type: 'image_url';
|
|
6
|
+
image_url: {
|
|
7
|
+
url: string;
|
|
8
|
+
detail?: 'auto' | 'low' | 'high';
|
|
9
|
+
};
|
|
10
|
+
} | {
|
|
11
|
+
type: 'image_base64';
|
|
12
|
+
image_base64: string;
|
|
13
|
+
media_type?: string;
|
|
14
|
+
};
|
|
15
|
+
export interface ChatMessage {
|
|
16
|
+
role: 'system' | 'user' | 'assistant';
|
|
17
|
+
content: MessageContent[];
|
|
18
|
+
}
|
|
19
|
+
export interface ChatRequest {
|
|
20
|
+
model?: string;
|
|
21
|
+
messages: ChatMessage[];
|
|
22
|
+
temperature?: number;
|
|
23
|
+
max_tokens?: number;
|
|
24
|
+
stream?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface AIProvider {
|
|
27
|
+
id: string;
|
|
28
|
+
provider_type: string;
|
|
29
|
+
name: string;
|
|
30
|
+
display_name?: string | null;
|
|
31
|
+
base_url: string;
|
|
32
|
+
default_model: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface AICapabilities {
|
|
35
|
+
/** Whether the provider supports image inputs (both URL and base64) */
|
|
36
|
+
supports_images: boolean;
|
|
37
|
+
/** Whether the provider supports streaming responses */
|
|
38
|
+
supports_streaming: boolean;
|
|
39
|
+
/** Whether the provider supports function calling */
|
|
40
|
+
supports_function_calling: boolean;
|
|
41
|
+
/** Maximum context window in tokens */
|
|
42
|
+
max_context_tokens?: number;
|
|
43
|
+
/** Maximum number of images allowed per message (undefined = unlimited) */
|
|
44
|
+
max_images_per_message?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ModelInfo {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
context_window?: number;
|
|
51
|
+
}
|
|
52
|
+
export interface ValidationResult {
|
|
53
|
+
valid: boolean;
|
|
54
|
+
message?: string;
|
|
55
|
+
models_count?: number;
|
|
56
|
+
}
|
|
57
|
+
export declare function createTextMessage(role: 'system' | 'user' | 'assistant', text: string): ChatMessage;
|
|
58
|
+
export declare function createImageMessage(text: string, images: Array<string | {
|
|
59
|
+
url: string;
|
|
60
|
+
detail?: 'auto' | 'low' | 'high';
|
|
61
|
+
}>): ChatMessage;
|
|
62
|
+
/**
|
|
63
|
+
* Send a chat request to the configured AI provider.
|
|
64
|
+
* @param prompt - The user prompt or conversation history
|
|
65
|
+
* @param options - Additional options like model override
|
|
66
|
+
* @returns The AI response text
|
|
67
|
+
*/
|
|
68
|
+
declare function ask(prompt: string | ChatMessage[], options?: Partial<ChatRequest>): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Stream a chat response from the configured AI provider.
|
|
71
|
+
* @param prompt - The user prompt
|
|
72
|
+
* @param onChunk - Callback for each text chunk
|
|
73
|
+
* @param options - Additional options
|
|
74
|
+
* @returns Promise that resolves when stream is complete
|
|
75
|
+
*/
|
|
76
|
+
declare function stream(prompt: string | ChatMessage[], onChunk: (chunk: string) => void, options?: Partial<ChatRequest>): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Check if AI functionality is available (provider configured)
|
|
79
|
+
*/
|
|
80
|
+
declare function isAvailable(): Promise<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* Get capabilities of the current active provider
|
|
83
|
+
*/
|
|
84
|
+
declare function getCapabilities(): Promise<AICapabilities | null>;
|
|
85
|
+
/**
|
|
86
|
+
* List available models from the current active provider
|
|
87
|
+
*/
|
|
88
|
+
declare function listModels(): Promise<ModelInfo[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Validate a provider configuration.
|
|
91
|
+
* Note: Mainly for settings UI, generic plugins might not need this.
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
declare function validateProvider(baseUrl: string, apiKey?: string): Promise<ValidationResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Create a conversation manager for handling multi-turn chats
|
|
97
|
+
*/
|
|
98
|
+
declare function createConversation(systemPrompt?: string): Conversation;
|
|
99
|
+
/**
|
|
100
|
+
* Helper class to manage conversation history
|
|
101
|
+
*/
|
|
102
|
+
export declare class Conversation {
|
|
103
|
+
private messages;
|
|
104
|
+
constructor(systemPrompt?: string);
|
|
105
|
+
addMessage(message: ChatMessage): void;
|
|
106
|
+
ask(prompt: string | ChatMessage, options?: Partial<ChatRequest>): Promise<string>;
|
|
107
|
+
stream(prompt: string | ChatMessage, onChunk: (chunk: string) => void, options?: Partial<ChatRequest>): Promise<void>;
|
|
108
|
+
getHistory(): ChatMessage[];
|
|
109
|
+
clear(): void;
|
|
110
|
+
getLastResponse(): string | null;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* AI namespace for interacting with configured AI providers.
|
|
114
|
+
*/
|
|
115
|
+
export declare const ai: {
|
|
116
|
+
ask: typeof ask;
|
|
117
|
+
stream: typeof stream;
|
|
118
|
+
isAvailable: typeof isAvailable;
|
|
119
|
+
getCapabilities: typeof getCapabilities;
|
|
120
|
+
listModels: typeof listModels;
|
|
121
|
+
validateProvider: typeof validateProvider;
|
|
122
|
+
createConversation: typeof createConversation;
|
|
123
|
+
};
|
|
124
|
+
export {};
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { parseClipboardError } from '../utils/error-parser';
|
|
2
|
+
/**
|
|
3
|
+
* Reads text content from the clipboard.
|
|
4
|
+
* @returns Promise that resolves to the text in the clipboard, or null if the clipboard is empty or doesn't contain text.
|
|
5
|
+
* @throws {PluginError} With code `CLIPBOARD_UNAVAILABLE` when clipboard is not accessible
|
|
6
|
+
* @throws {PluginError} With code `CLIPBOARD_ACCESS_DENIED` when permission is denied
|
|
7
|
+
* @throws {PluginError} With code `PERMISSION_DENIED` for general permission issues
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* async function getClipboardText() {
|
|
11
|
+
* try {
|
|
12
|
+
* const text = await clipboard.readText();
|
|
13
|
+
* if (text) {
|
|
14
|
+
* console.log('Clipboard text:', text);
|
|
15
|
+
* } else {
|
|
16
|
+
* console.log('Clipboard is empty or does not contain text.');
|
|
17
|
+
* }
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* if (errorUtils.isErrorCode(error, 'CLIPBOARD_ACCESS_DENIED')) {
|
|
20
|
+
* console.error('Clipboard access denied');
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
* @since 0.1.0
|
|
26
|
+
* @group API
|
|
27
|
+
*/
|
|
28
|
+
export declare function readText(): Promise<string | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Writes the specified text to the clipboard.
|
|
31
|
+
* @param text - The text to write to the clipboard.
|
|
32
|
+
* @returns Promise that resolves when the operation is complete.
|
|
33
|
+
* @throws {PluginError} With code `CLIPBOARD_UNAVAILABLE` when clipboard is not accessible
|
|
34
|
+
* @throws {PluginError} With code `CLIPBOARD_ACCESS_DENIED` when permission is denied
|
|
35
|
+
* @throws {PluginError} With code `PERMISSION_DENIED` for general permission issues
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* async function setClipboardText() {
|
|
39
|
+
* try {
|
|
40
|
+
* await clipboard.writeText('Hello from the plugin!');
|
|
41
|
+
* console.log('Text written to clipboard.');
|
|
42
|
+
* } catch (error) {
|
|
43
|
+
* console.error('Failed to write to clipboard:', error.message);
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
* @since 0.1.0
|
|
48
|
+
* @group API
|
|
49
|
+
*/
|
|
50
|
+
export declare function writeText(text: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Reads image data from the clipboard and returns it as a Base64 string.
|
|
53
|
+
* @returns Promise that resolves to the Base64 encoded string of the image, or null if the clipboard is empty or doesn't contain an image.
|
|
54
|
+
* @throws {PluginError} With code `CLIPBOARD_FORMAT_UNSUPPORTED` when image format is not supported
|
|
55
|
+
* @throws {PluginError} With code `CLIPBOARD_UNAVAILABLE` when clipboard is not accessible
|
|
56
|
+
* @throws {PluginError} With code `CLIPBOARD_ACCESS_DENIED` when permission is denied
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* async function getClipboardImage() {
|
|
60
|
+
* try {
|
|
61
|
+
* const imageBase64 = await clipboard.readImage();
|
|
62
|
+
* if (imageBase64) {
|
|
63
|
+
* const imgElement = document.createElement('img');
|
|
64
|
+
* imgElement.src = `data:image/png;base64,${imageBase64}`;
|
|
65
|
+
* document.body.appendChild(imgElement);
|
|
66
|
+
* } else {
|
|
67
|
+
* console.log('Clipboard does not contain an image.');
|
|
68
|
+
* }
|
|
69
|
+
* } catch (error) {
|
|
70
|
+
* if (errorUtils.isErrorCode(error, 'CLIPBOARD_FORMAT_UNSUPPORTED')) {
|
|
71
|
+
* console.error('Image format not supported');
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
* @since 0.1.0
|
|
77
|
+
* @group API
|
|
78
|
+
*/
|
|
79
|
+
export declare function readImage(): Promise<string | null>;
|
|
80
|
+
/**
|
|
81
|
+
* Writes image data to the clipboard.
|
|
82
|
+
* @param imageData - The image's Base64 encoded string or Uint8Array data.
|
|
83
|
+
* @returns Promise that resolves when the operation is complete.
|
|
84
|
+
* @throws {PluginError} With code `CLIPBOARD_FORMAT_UNSUPPORTED` when image format is not supported
|
|
85
|
+
* @throws {PluginError} With code `CLIPBOARD_UNAVAILABLE` when clipboard is not accessible
|
|
86
|
+
* @throws {PluginError} With code `CLIPBOARD_ACCESS_DENIED` when permission is denied
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* async function setClipboardImage(base64Data: string) {
|
|
90
|
+
* try {
|
|
91
|
+
* await clipboard.writeImage(base64Data);
|
|
92
|
+
* console.log('Image written to clipboard.');
|
|
93
|
+
* } catch (error) {
|
|
94
|
+
* console.error('Failed to write image to clipboard:', error.message);
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
* @since 0.1.0
|
|
99
|
+
* @group API
|
|
100
|
+
*/
|
|
101
|
+
export declare function writeImage(imageData: string | Uint8Array): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Clears all content from the clipboard.
|
|
104
|
+
* @returns Promise that resolves when the operation is complete.
|
|
105
|
+
* @throws {PluginError} With code `CLIPBOARD_UNAVAILABLE` when clipboard is not accessible
|
|
106
|
+
* @throws {PluginError} With code `CLIPBOARD_ACCESS_DENIED` when permission is denied
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* async function clearClipboard() {
|
|
110
|
+
* try {
|
|
111
|
+
* await clipboard.clear();
|
|
112
|
+
* console.log('Clipboard cleared.');
|
|
113
|
+
* } catch (error) {
|
|
114
|
+
* console.error('Failed to clear clipboard:', error.message);
|
|
115
|
+
* }
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
* @since 0.1.0
|
|
119
|
+
* @group API
|
|
120
|
+
*/
|
|
121
|
+
export declare function clear(): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Checks if the clipboard currently contains text content.
|
|
124
|
+
* @returns Promise that resolves to true if the clipboard contains text, false otherwise.
|
|
125
|
+
* @throws {PluginError} Same error conditions as {@link readText}
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* async function checkText() {
|
|
129
|
+
* try {
|
|
130
|
+
* if (await clipboard.hasText()) {
|
|
131
|
+
* console.log('Clipboard has text.');
|
|
132
|
+
* const text = await clipboard.readText();
|
|
133
|
+
* console.log('Text content:', text);
|
|
134
|
+
* } else {
|
|
135
|
+
* console.log('Clipboard does not have text.');
|
|
136
|
+
* }
|
|
137
|
+
* } catch (error) {
|
|
138
|
+
* console.error('Failed to check clipboard text:', error.message);
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
* @since 0.1.0
|
|
143
|
+
* @group API
|
|
144
|
+
*/
|
|
145
|
+
export declare function hasText(): Promise<boolean>;
|
|
146
|
+
/**
|
|
147
|
+
* Checks if the clipboard currently contains image content.
|
|
148
|
+
* @returns Promise that resolves to true if the clipboard contains an image, false otherwise.
|
|
149
|
+
* @throws {PluginError} Same error conditions as {@link readImage}
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* async function checkImage() {
|
|
153
|
+
* try {
|
|
154
|
+
* if (await clipboard.hasImage()) {
|
|
155
|
+
* console.log('Clipboard has an image.');
|
|
156
|
+
* const imageData = await clipboard.readImage();
|
|
157
|
+
* console.log('Image data available:', !!imageData);
|
|
158
|
+
* } else {
|
|
159
|
+
* console.log('Clipboard does not have an image.');
|
|
160
|
+
* }
|
|
161
|
+
* } catch (error) {
|
|
162
|
+
* console.error('Failed to check clipboard image:', error.message);
|
|
163
|
+
* }
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
* @since 0.1.0
|
|
167
|
+
* @group API
|
|
168
|
+
*/
|
|
169
|
+
export declare function hasImage(): Promise<boolean>;
|
|
170
|
+
/**
|
|
171
|
+
* Copies text to the clipboard, alias for `writeText`.
|
|
172
|
+
* @param text - The text to copy.
|
|
173
|
+
* @returns Promise that resolves when the operation is complete.
|
|
174
|
+
* @throws {PluginError} Same error conditions as {@link writeText}
|
|
175
|
+
* @see {@link writeText} - For detailed error information
|
|
176
|
+
* @since 0.1.0
|
|
177
|
+
* @group API
|
|
178
|
+
*/
|
|
179
|
+
export declare function copy(text: string): Promise<void>;
|
|
180
|
+
/**
|
|
181
|
+
* Pastes text content from the clipboard, alias for `readText`.
|
|
182
|
+
* @returns Promise that resolves to the text in the clipboard, or null if empty.
|
|
183
|
+
* @throws {PluginError} Same error conditions as {@link readText}
|
|
184
|
+
* @see {@link readText} - For detailed error information
|
|
185
|
+
* @since 0.1.0
|
|
186
|
+
* @group API
|
|
187
|
+
*/
|
|
188
|
+
export declare function paste(): Promise<string | null>;
|
|
189
|
+
/**
|
|
190
|
+
* Clipboard content type enumeration
|
|
191
|
+
* @since 0.1.0
|
|
192
|
+
* @group Types
|
|
193
|
+
*/
|
|
194
|
+
export type ClipboardContentType = 'text' | 'image' | 'files' | 'empty';
|
|
195
|
+
/**
|
|
196
|
+
* File information in clipboard
|
|
197
|
+
* @interface ClipboardFile
|
|
198
|
+
* @since 0.1.0
|
|
199
|
+
* @group Types
|
|
200
|
+
*/
|
|
201
|
+
export interface ClipboardFile {
|
|
202
|
+
/** Full file path */
|
|
203
|
+
path: string;
|
|
204
|
+
/** File name */
|
|
205
|
+
name: string;
|
|
206
|
+
/** Whether this is a directory */
|
|
207
|
+
is_directory: boolean;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Enhanced metadata about clipboard content including type, timestamp, and age information
|
|
211
|
+
* @interface ClipboardMetadata
|
|
212
|
+
* @since 0.1.0
|
|
213
|
+
* @group Types
|
|
214
|
+
*/
|
|
215
|
+
export interface ClipboardMetadata {
|
|
216
|
+
/** The text content in the clipboard, or null if no text */
|
|
217
|
+
text: string | null;
|
|
218
|
+
/** List of file paths if clipboard contains files, or null if no files */
|
|
219
|
+
files: ClipboardFile[] | null;
|
|
220
|
+
/** The type of content in the clipboard */
|
|
221
|
+
contentType: ClipboardContentType;
|
|
222
|
+
/**
|
|
223
|
+
* Unix timestamp (in seconds) when the clipboard content was last updated.
|
|
224
|
+
*
|
|
225
|
+
* Note: This timestamp is independent from the app's auto_clear_time_limit setting.
|
|
226
|
+
* Even if the app clears its internal state, this timestamp will still reflect
|
|
227
|
+
* when the system clipboard was actually modified.
|
|
228
|
+
*
|
|
229
|
+
* May be null only if:
|
|
230
|
+
* - Clipboard monitoring hasn't started yet
|
|
231
|
+
* - The clipboard has never been modified since app start
|
|
232
|
+
*/
|
|
233
|
+
timestamp: number | null;
|
|
234
|
+
/**
|
|
235
|
+
* Age of the clipboard content in seconds (time since it was copied).
|
|
236
|
+
* Calculated as: current_time - timestamp.
|
|
237
|
+
* Will be null if timestamp is null.
|
|
238
|
+
*/
|
|
239
|
+
age: number | null;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Gets comprehensive clipboard metadata including content type, timestamp, and age.
|
|
243
|
+
* This enhanced API provides detailed information about clipboard content:
|
|
244
|
+
* - Content type detection (text, image, files, or empty)
|
|
245
|
+
* - Text content (if available)
|
|
246
|
+
* - Image detection
|
|
247
|
+
* - File paths (if files were copied)
|
|
248
|
+
* - Timestamp when content was copied
|
|
249
|
+
* - Age in seconds (automatically calculated)
|
|
250
|
+
*
|
|
251
|
+
* @returns Promise that resolves to comprehensive clipboard metadata
|
|
252
|
+
* @throws {PluginError} Same error conditions as {@link readText}
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* // Basic usage - check content type and age
|
|
256
|
+
* const metadata = await clipboard.getMetadata();
|
|
257
|
+
* console.log('Content type:', metadata.contentType);
|
|
258
|
+
* console.log('Age:', metadata.age, 'seconds');
|
|
259
|
+
*
|
|
260
|
+
* // Handle different content types
|
|
261
|
+
* switch (metadata.contentType) {
|
|
262
|
+
* case 'text':
|
|
263
|
+
* console.log('Text:', metadata.text);
|
|
264
|
+
* break;
|
|
265
|
+
* case 'image':
|
|
266
|
+
* console.log('Clipboard contains an image');
|
|
267
|
+
* break;
|
|
268
|
+
* case 'files':
|
|
269
|
+
* console.log('Files:', metadata.files?.map(f => f.name));
|
|
270
|
+
* break;
|
|
271
|
+
* case 'empty':
|
|
272
|
+
* console.log('Clipboard is empty');
|
|
273
|
+
* break;
|
|
274
|
+
* }
|
|
275
|
+
*
|
|
276
|
+
* // Time-based filtering using age
|
|
277
|
+
* if (metadata.age !== null && metadata.age < 10) {
|
|
278
|
+
* console.log('Content is fresh (less than 10 seconds old)');
|
|
279
|
+
* await processContent(metadata);
|
|
280
|
+
* }
|
|
281
|
+
*
|
|
282
|
+
* // Check for image
|
|
283
|
+
* if (metadata.contentType === 'image') {
|
|
284
|
+
* console.log('Image detected in clipboard');
|
|
285
|
+
* }
|
|
286
|
+
*
|
|
287
|
+
* if (metadata.files && metadata.files.length > 0) {
|
|
288
|
+
* console.log('Files copied:', metadata.files.length);
|
|
289
|
+
* metadata.files.forEach(file => {
|
|
290
|
+
* console.log(`- ${file.name} (${file.is_directory ? 'dir' : 'file'})`);
|
|
291
|
+
* });
|
|
292
|
+
* }
|
|
293
|
+
* ```
|
|
294
|
+
* @since 0.1.0
|
|
295
|
+
* @group API
|
|
296
|
+
*/
|
|
297
|
+
export declare function getMetadata(): Promise<ClipboardMetadata>;
|
|
298
|
+
/**
|
|
299
|
+
* Clipboard API namespace - provides functions for interacting with the system clipboard
|
|
300
|
+
*
|
|
301
|
+
* Supports reading and writing text and image data to/from the system clipboard.
|
|
302
|
+
* All operations require appropriate permissions and handle various clipboard states gracefully.
|
|
303
|
+
*
|
|
304
|
+
* @namespace clipboard
|
|
305
|
+
* @version 0.1.0
|
|
306
|
+
* @since 0.1.0
|
|
307
|
+
* @group API
|
|
308
|
+
* @see {@link parseClipboardError} - For error handling utilities
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* import { clipboard } from 'onin-plugin-sdk';
|
|
312
|
+
*
|
|
313
|
+
* // Read text from clipboard
|
|
314
|
+
* const text = await clipboard.readText();
|
|
315
|
+
*
|
|
316
|
+
* // Write text to clipboard
|
|
317
|
+
* await clipboard.writeText('Hello World');
|
|
318
|
+
*
|
|
319
|
+
* // Check if clipboard has content
|
|
320
|
+
* if (await clipboard.hasText()) {
|
|
321
|
+
* console.log('Clipboard has text content');
|
|
322
|
+
* }
|
|
323
|
+
*
|
|
324
|
+
* // Get metadata with timestamp
|
|
325
|
+
* const metadata = await clipboard.getMetadata();
|
|
326
|
+
* console.log('Content age:', Date.now() / 1000 - metadata.timestamp);
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
export declare const clipboard: {
|
|
330
|
+
/** Core methods */
|
|
331
|
+
readText: typeof readText;
|
|
332
|
+
writeText: typeof writeText;
|
|
333
|
+
readImage: typeof readImage;
|
|
334
|
+
writeImage: typeof writeImage;
|
|
335
|
+
clear: typeof clear;
|
|
336
|
+
/** Check methods */
|
|
337
|
+
hasText: typeof hasText;
|
|
338
|
+
hasImage: typeof hasImage;
|
|
339
|
+
/** Metadata methods */
|
|
340
|
+
getMetadata: typeof getMetadata;
|
|
341
|
+
/** Convenience methods */
|
|
342
|
+
copy: typeof copy;
|
|
343
|
+
paste: typeof paste;
|
|
344
|
+
/** Error handling tools */
|
|
345
|
+
parseClipboardError: typeof parseClipboardError;
|
|
346
|
+
};
|