mulby-cli 1.1.5

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.
Files changed (59) hide show
  1. package/PLUGIN_DEVELOP_PROMPT.md +1164 -0
  2. package/README.md +852 -0
  3. package/assets/default-icon.png +0 -0
  4. package/dist/commands/ai-session.js +44 -0
  5. package/dist/commands/build.js +111 -0
  6. package/dist/commands/config-ai.js +291 -0
  7. package/dist/commands/config.js +53 -0
  8. package/dist/commands/create/ai-create.js +183 -0
  9. package/dist/commands/create/assets.js +53 -0
  10. package/dist/commands/create/basic.js +72 -0
  11. package/dist/commands/create/index.js +73 -0
  12. package/dist/commands/create/react.js +136 -0
  13. package/dist/commands/create/templates/basic.js +383 -0
  14. package/dist/commands/create/templates/react/backend.js +72 -0
  15. package/dist/commands/create/templates/react/config.js +166 -0
  16. package/dist/commands/create/templates/react/docs.js +78 -0
  17. package/dist/commands/create/templates/react/hooks.js +469 -0
  18. package/dist/commands/create/templates/react/index.js +41 -0
  19. package/dist/commands/create/templates/react/types.js +1228 -0
  20. package/dist/commands/create/templates/react/ui.js +528 -0
  21. package/dist/commands/create/templates/react.js +1888 -0
  22. package/dist/commands/dev.js +141 -0
  23. package/dist/commands/pack.js +160 -0
  24. package/dist/commands/resume.js +97 -0
  25. package/dist/commands/test-ui.js +50 -0
  26. package/dist/index.js +71 -0
  27. package/dist/services/ai/PLUGIN_API.md +1102 -0
  28. package/dist/services/ai/PLUGIN_DEVELOP_PROMPT.md +1164 -0
  29. package/dist/services/ai/context-manager.js +639 -0
  30. package/dist/services/ai/index.js +88 -0
  31. package/dist/services/ai/knowledge.js +52 -0
  32. package/dist/services/ai/prompts.js +114 -0
  33. package/dist/services/ai/providers/base.js +38 -0
  34. package/dist/services/ai/providers/claude.js +284 -0
  35. package/dist/services/ai/providers/deepseek.js +28 -0
  36. package/dist/services/ai/providers/gemini.js +191 -0
  37. package/dist/services/ai/providers/glm.js +31 -0
  38. package/dist/services/ai/providers/minimax.js +27 -0
  39. package/dist/services/ai/providers/openai.js +177 -0
  40. package/dist/services/ai/tools.js +204 -0
  41. package/dist/services/ai-generator.js +968 -0
  42. package/dist/services/config-manager.js +117 -0
  43. package/dist/services/dependency-manager.js +236 -0
  44. package/dist/services/file-writer.js +66 -0
  45. package/dist/services/plan-adapter.js +244 -0
  46. package/dist/services/plan-command-handler.js +172 -0
  47. package/dist/services/plan-manager.js +502 -0
  48. package/dist/services/session-manager.js +113 -0
  49. package/dist/services/task-analyzer.js +136 -0
  50. package/dist/services/tui/index.js +57 -0
  51. package/dist/services/tui/store.js +123 -0
  52. package/dist/types/ai.js +172 -0
  53. package/dist/types/plan.js +2 -0
  54. package/dist/ui/Terminal.js +56 -0
  55. package/dist/ui/components/InputArea.js +176 -0
  56. package/dist/ui/components/LogArea.js +19 -0
  57. package/dist/ui/components/PlanPanel.js +69 -0
  58. package/dist/ui/components/SelectArea.js +13 -0
  59. package/package.json +45 -0
@@ -0,0 +1,1228 @@
1
+ "use strict";
2
+ /**
3
+ * React 插件模板 - 类型定义生成器
4
+ * 包含:mulby.d.ts
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.buildMulbyTypes = buildMulbyTypes;
8
+ /**
9
+ * 生成 mulby.d.ts 类型定义内容
10
+ */
11
+ function buildMulbyTypes() {
12
+ return `// Mulby API 类型定义
13
+
14
+ interface ClipboardFileInfo {
15
+ path: string
16
+ name: string
17
+ size: number
18
+ isDirectory: boolean
19
+ }
20
+
21
+ interface MulbyClipboard {
22
+ readText(): Promise<string>
23
+ writeText(text: string): Promise<void>
24
+ readImage(): Promise<ArrayBuffer | null>
25
+ writeImage(image: string | ArrayBuffer): Promise<void>
26
+ readFiles(): Promise<ClipboardFileInfo[]>
27
+ writeFiles(files: string | string[]): Promise<boolean>
28
+ getFormat(): Promise<'text' | 'image' | 'files' | 'empty'>
29
+ }
30
+
31
+ interface ClipboardHistoryItem {
32
+ id: string
33
+ type: 'text' | 'image' | 'files'
34
+ content: string
35
+ plainText?: string
36
+ files?: string[]
37
+ timestamp: number
38
+ size: number
39
+ favorite: boolean
40
+ tags?: string[]
41
+ }
42
+
43
+ interface ClipboardHistoryStats {
44
+ total: number
45
+ text: number
46
+ image: number
47
+ files: number
48
+ favorite: number
49
+ }
50
+
51
+ interface MulbyClipboardHistory {
52
+ query(options?: {
53
+ type?: 'text' | 'image' | 'files'
54
+ search?: string
55
+ favorite?: boolean
56
+ limit?: number
57
+ offset?: number
58
+ }): Promise<ClipboardHistoryItem[]>
59
+ get(id: string): Promise<ClipboardHistoryItem | null>
60
+ copy(id: string): Promise<{ success: boolean; error?: string }>
61
+ toggleFavorite(id: string): Promise<{ success: boolean }>
62
+ delete(id: string): Promise<{ success: boolean }>
63
+ clear(): Promise<{ success: boolean }>
64
+ stats(): Promise<ClipboardHistoryStats>
65
+ }
66
+
67
+ interface MulbyInput {
68
+ hideMainWindowPasteText(text: string): Promise<boolean>
69
+ hideMainWindowPasteImage(image: string | ArrayBuffer): Promise<boolean>
70
+ hideMainWindowPasteFile(filePaths: string | string[]): Promise<boolean>
71
+ hideMainWindowTypeString(text: string): Promise<boolean>
72
+ restoreWindows(): Promise<boolean>
73
+ simulateKeyboardTap(key: string, ...modifiers: string[]): Promise<boolean>
74
+ simulateMouseMove(x: number, y: number): Promise<boolean>
75
+ simulateMouseClick(x: number, y: number): Promise<boolean>
76
+ simulateMouseDoubleClick(x: number, y: number): Promise<boolean>
77
+ simulateMouseRightClick(x: number, y: number): Promise<boolean>
78
+ }
79
+
80
+ interface MulbyNotification {
81
+ show(message: string, type?: 'info' | 'success' | 'warning' | 'error'): void
82
+ }
83
+
84
+ interface BrowserWindowProxy {
85
+ id: number
86
+ show(): Promise<void>
87
+ hide(): Promise<void>
88
+ close(): Promise<void>
89
+ focus(): Promise<void>
90
+ setTitle(title: string): Promise<void>
91
+ setSize(width: number, height: number): Promise<void>
92
+ setPosition(x: number, y: number): Promise<void>
93
+ postMessage(channel: string, ...args: unknown[]): Promise<void>
94
+ }
95
+
96
+ interface MulbyWindow {
97
+ hide(isRestorePreWindow?: boolean): void
98
+ show(): void
99
+ setSize(width: number, height: number): void
100
+ setExpendHeight(height: number): void
101
+ center(): void
102
+ create(url: string, options?: { width?: number; height?: number; title?: string }): Promise<BrowserWindowProxy | null>
103
+ close(): void
104
+ detach(): void
105
+ setAlwaysOnTop(flag: boolean): void
106
+ getMode(): Promise<'attached' | 'detached'>
107
+ getWindowType(): Promise<'main' | 'detach'>
108
+ minimize(): void
109
+ maximize(): void
110
+ getState(): Promise<{ isMaximized: boolean; isAlwaysOnTop: boolean }>
111
+ reload(): void
112
+ sendToParent(channel: string, ...args: unknown[]): void
113
+ onChildMessage(callback: (channel: string, ...args: unknown[]) => void): void
114
+ findInPage(text: string, options?: { forward?: boolean; findNext?: boolean; matchCase?: boolean }): Promise<number>
115
+ stopFindInPage(action?: 'clearSelection' | 'keepSelection' | 'activateSelection'): void
116
+ startDrag(filePath: string | string[]): void
117
+ }
118
+
119
+ interface MulbySubInput {
120
+ set(placeholder?: string, isFocus?: boolean): Promise<boolean>
121
+ remove(): Promise<boolean>
122
+ setValue(text: string): void
123
+ focus(): void
124
+ blur(): void
125
+ select(): void
126
+ onChange(callback: (data: { text: string }) => void): void
127
+ }
128
+
129
+ interface MulbyTheme {
130
+ get(): Promise<{ mode: 'light' | 'dark' | 'system'; actual: 'light' | 'dark' }>
131
+ set(mode: 'light' | 'dark' | 'system'): Promise<{ mode: 'light' | 'dark' | 'system'; actual: 'light' | 'dark' }>
132
+ getActual(): Promise<'light' | 'dark'>
133
+ }
134
+
135
+ interface PluginInfo {
136
+ id: string
137
+ name: string
138
+ displayName: string
139
+ description?: string
140
+ features: Array<{ code: string; explain?: string }>
141
+ enabled: boolean
142
+ }
143
+
144
+ interface PluginSearchResult {
145
+ pluginId: string
146
+ pluginName: string
147
+ displayName: string
148
+ featureCode: string
149
+ featureExplain?: string
150
+ matchType: 'keyword' | 'regex' | 'prefix' | 'exact' | string
151
+ icon?: string
152
+ }
153
+
154
+ interface BackgroundPluginInfo {
155
+ pluginId: string
156
+ pluginName: string
157
+ displayName: string
158
+ runMode: 'background' | 'active'
159
+ startedAt?: number
160
+ uptime?: number
161
+ memoryUsage?: number
162
+ cpuUsage?: number
163
+ requestCount?: number
164
+ errorCount?: number
165
+ healthy?: boolean
166
+ lastHeartbeat?: number
167
+ missedHeartbeats?: number
168
+ }
169
+
170
+ interface MulbyPlugin {
171
+ getAll(): Promise<PluginInfo[]>
172
+ search(query: string): Promise<PluginSearchResult[]>
173
+ run(name: string, featureCode: string, input?: string): Promise<{ success: boolean; hasUI?: boolean; error?: string }>
174
+ install(filePath: string): Promise<{ success: boolean; pluginName?: string; error?: string }>
175
+ enable(name: string): Promise<{ success: boolean; error?: string }>
176
+ disable(name: string): Promise<{ success: boolean; error?: string }>
177
+ uninstall(name: string): Promise<{ success: boolean; error?: string }>
178
+ getReadme(name: string): Promise<string | null>
179
+ redirect(label: string | [string, string], payload?: unknown): Promise<boolean | { candidates: { name: string; displayName: string }[] }>
180
+ outPlugin(isKill?: boolean): Promise<boolean>
181
+ listBackground(): Promise<BackgroundPluginInfo[]>
182
+ startBackground(pluginId: string): Promise<{ success: boolean; error?: string }>
183
+ stopBackground(pluginId: string): Promise<{ success: boolean }>
184
+ getBackgroundInfo(pluginId: string): Promise<BackgroundPluginInfo>
185
+ stopPlugin(pluginId: string): Promise<void>
186
+ }
187
+
188
+ interface DisplayInfo {
189
+ id: number
190
+ label: string
191
+ bounds: { x: number; y: number; width: number; height: number }
192
+ workArea: { x: number; y: number; width: number; height: number }
193
+ scaleFactor: number
194
+ rotation: number
195
+ isPrimary: boolean
196
+ }
197
+
198
+ interface CaptureSource {
199
+ id: string
200
+ name: string
201
+ thumbnailDataUrl: string
202
+ displayId?: string
203
+ appIconDataUrl?: string
204
+ }
205
+
206
+ interface ColorPickResult {
207
+ hex: string
208
+ rgb: string
209
+ r: number
210
+ g: number
211
+ b: number
212
+ }
213
+
214
+ interface MulbyScreen {
215
+ getAllDisplays(): Promise<DisplayInfo[]>
216
+ getPrimaryDisplay(): Promise<DisplayInfo>
217
+ getDisplayNearestPoint(point: { x: number; y: number }): Promise<DisplayInfo>
218
+ getDisplayMatching(rect: { x: number; y: number; width: number; height: number }): Promise<DisplayInfo>
219
+ getCursorScreenPoint(): Promise<{ x: number; y: number }>
220
+ getSources(options?: { types?: ('screen' | 'window')[]; thumbnailSize?: { width: number; height: number } }): Promise<CaptureSource[]>
221
+ capture(options?: { sourceId?: string; format?: 'png' | 'jpeg'; quality?: number }): Promise<ArrayBuffer>
222
+ captureRegion(region: { x: number; y: number; width: number; height: number }, options?: { format?: 'png' | 'jpeg'; quality?: number }): Promise<ArrayBuffer>
223
+ getMediaStreamConstraints(options: { sourceId: string; audio?: boolean; frameRate?: number }): Promise<object>
224
+ screenCapture(): Promise<string | null>
225
+ colorPick(): Promise<ColorPickResult | null>
226
+ }
227
+
228
+ interface MulbyShell {
229
+ openPath(path: string): Promise<string>
230
+ openExternal(url: string): Promise<void>
231
+ showItemInFolder(path: string): Promise<void>
232
+ openFolder(path: string): Promise<string>
233
+ trashItem(path: string): Promise<void>
234
+ beep(): Promise<void>
235
+ }
236
+
237
+ interface MulbyDialog {
238
+ showOpenDialog(options?: {
239
+ title?: string
240
+ defaultPath?: string
241
+ buttonLabel?: string
242
+ filters?: { name: string; extensions: string[] }[]
243
+ properties?: ('openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles')[]
244
+ }): Promise<string[]>
245
+ showSaveDialog(options?: {
246
+ title?: string
247
+ defaultPath?: string
248
+ buttonLabel?: string
249
+ filters?: { name: string; extensions: string[] }[]
250
+ }): Promise<string | null>
251
+ showMessageBox(options: {
252
+ type?: 'none' | 'info' | 'error' | 'question' | 'warning'
253
+ title?: string
254
+ message: string
255
+ detail?: string
256
+ buttons?: string[]
257
+ defaultId?: number
258
+ cancelId?: number
259
+ }): Promise<{ response: number; checkboxChecked: boolean }>
260
+ showErrorBox(title: string, content: string): Promise<void>
261
+ }
262
+
263
+ interface SystemInfo {
264
+ platform: string
265
+ arch: string
266
+ hostname: string
267
+ username: string
268
+ homedir: string
269
+ tmpdir: string
270
+ cpus: number
271
+ totalmem: number
272
+ freemem: number
273
+ uptime: number
274
+ osVersion: string
275
+ osRelease: string
276
+ }
277
+
278
+ interface AppInfo {
279
+ name: string
280
+ version: string
281
+ locale: string
282
+ isPackaged: boolean
283
+ userDataPath: string
284
+ }
285
+
286
+ interface MulbySystem {
287
+ getSystemInfo(): Promise<SystemInfo>
288
+ getAppInfo(): Promise<AppInfo>
289
+ getPath(name: 'home' | 'appData' | 'userData' | 'temp' | 'exe' | 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos' | 'logs'): Promise<string>
290
+ getEnv(name: string): Promise<string | undefined>
291
+ getIdleTime(): Promise<number>
292
+ getFileIcon(filePath: string): Promise<string>
293
+ getNativeId(): Promise<string>
294
+ isDev(): Promise<boolean>
295
+ isMacOS(): Promise<boolean>
296
+ isWindows(): Promise<boolean>
297
+ isLinux(): Promise<boolean>
298
+ }
299
+
300
+ interface MulbyPermission {
301
+ getStatus(type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar'): Promise<'authorized' | 'granted' | 'denied' | 'not-determined' | 'restricted' | 'limited' | 'unknown'>
302
+ request(type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar'): Promise<'authorized' | 'granted' | 'denied' | 'not-determined' | 'restricted' | 'limited' | 'unknown'>
303
+ canRequest(type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar'): Promise<boolean>
304
+ openSystemSettings(type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar'): Promise<boolean>
305
+ isAccessibilityTrusted(): Promise<boolean>
306
+ }
307
+
308
+ interface MulbyShortcut {
309
+ register(accelerator: string): Promise<boolean>
310
+ unregister(accelerator: string): Promise<void>
311
+ unregisterAll(): Promise<void>
312
+ isRegistered(accelerator: string): Promise<boolean>
313
+ onTriggered(callback: (accelerator: string) => void): void
314
+ }
315
+
316
+ interface MulbySecurity {
317
+ isEncryptionAvailable(): Promise<boolean>
318
+ encryptString(plainText: string): Promise<ArrayBuffer>
319
+ decryptString(encrypted: ArrayBuffer): Promise<string>
320
+ }
321
+
322
+ interface MulbyMedia {
323
+ getAccessStatus(mediaType: 'microphone' | 'camera'): Promise<'not-determined' | 'granted' | 'denied' | 'restricted' | 'unknown'>
324
+ askForAccess(mediaType: 'microphone' | 'camera'): Promise<boolean>
325
+ hasCameraAccess(): Promise<boolean>
326
+ hasMicrophoneAccess(): Promise<boolean>
327
+ }
328
+
329
+ interface MulbyPower {
330
+ getSystemIdleTime(): Promise<number>
331
+ getSystemIdleState(idleThreshold: number): Promise<'active' | 'idle' | 'locked' | 'unknown'>
332
+ isOnBatteryPower(): Promise<boolean>
333
+ getCurrentThermalState(): Promise<'unknown' | 'nominal' | 'fair' | 'serious' | 'critical'>
334
+ onSuspend(callback: () => void): void
335
+ onResume(callback: () => void): void
336
+ onAC(callback: () => void): void
337
+ onBattery(callback: () => void): void
338
+ onLockScreen(callback: () => void): void
339
+ onUnlockScreen(callback: () => void): void
340
+ }
341
+
342
+ interface MulbyTray {
343
+ create(options: { icon: string; tooltip?: string; title?: string }): Promise<boolean>
344
+ destroy(): Promise<void>
345
+ setIcon(icon: string): Promise<void>
346
+ setTooltip(tooltip: string): Promise<void>
347
+ setTitle(title: string): Promise<void>
348
+ exists(): Promise<boolean>
349
+ }
350
+
351
+ interface MulbyNetwork {
352
+ isOnline(): Promise<boolean>
353
+ }
354
+
355
+ interface MulbyMenu {
356
+ showContextMenu(items: {
357
+ label: string
358
+ type?: 'normal' | 'separator' | 'checkbox' | 'radio'
359
+ checked?: boolean
360
+ enabled?: boolean
361
+ id?: string
362
+ submenu?: any[]
363
+ }[]): Promise<string | null>
364
+ }
365
+
366
+ interface MulbyGeolocation {
367
+ getAccessStatus(): Promise<'not-determined' | 'granted' | 'denied' | 'restricted' | 'unknown'>
368
+ requestAccess(): Promise<'not-determined' | 'granted' | 'denied' | 'restricted' | 'unknown'>
369
+ canGetPosition(): Promise<boolean>
370
+ openSettings(): Promise<void>
371
+ getCurrentPosition(): Promise<{
372
+ latitude: number
373
+ longitude: number
374
+ accuracy: number
375
+ altitude?: number | null
376
+ altitudeAccuracy?: number | null
377
+ heading?: number | null
378
+ speed?: number | null
379
+ timestamp: number
380
+ }>
381
+ }
382
+
383
+ interface MulbyTTS {
384
+ speak(text: string, options?: { lang?: string; rate?: number; pitch?: number; volume?: number }): Promise<void>
385
+ stop(): void
386
+ pause(): void
387
+ resume(): void
388
+ getVoices(): { name: string; lang: string; default: boolean; localService: boolean }[]
389
+ isSpeaking(): boolean
390
+ }
391
+
392
+ interface MulbyStorage {
393
+ get(key: string, namespace?: string): Promise<unknown>
394
+ set(key: string, value: unknown, namespace?: string): Promise<void>
395
+ remove(key: string, namespace?: string): Promise<void>
396
+ }
397
+
398
+ interface MulbyMessaging {
399
+ send(targetPluginId: string, type: string, payload: unknown): Promise<void>
400
+ broadcast(type: string, payload: unknown): Promise<void>
401
+ on(handler: (message: {
402
+ id: string
403
+ from: string
404
+ to?: string
405
+ type: string
406
+ payload: unknown
407
+ timestamp: number
408
+ }) => void | Promise<void>): void
409
+ off(handler?: (message: any) => void): void
410
+ }
411
+
412
+ interface MulbyScheduler {
413
+ schedule(task: {
414
+ name: string
415
+ type: 'once' | 'repeat' | 'delay'
416
+ callback: string
417
+ time?: number
418
+ cron?: string
419
+ delay?: number
420
+ payload?: any
421
+ maxRetries?: number
422
+ retryDelay?: number
423
+ timeout?: number
424
+ description?: string
425
+ endTime?: number
426
+ maxExecutions?: number
427
+ }): Promise<any>
428
+ cancelTask(taskId: string): Promise<void>
429
+ pauseTask(taskId: string): Promise<void>
430
+ resumeTask(taskId: string): Promise<void>
431
+ listTasks(filter?: { status?: string; type?: string; limit?: number; offset?: number }): Promise<any[]>
432
+ getTaskCount(filter?: { status?: string; type?: string }): Promise<number>
433
+ getTask(taskId: string): Promise<any>
434
+ deleteTasks(taskIds: string[]): Promise<{ success: boolean; deletedCount: number }>
435
+ cleanupTasks(olderThan?: number): Promise<{ success: boolean; deletedCount: number }>
436
+ getExecutions(taskId: string, limit?: number): Promise<any[]>
437
+ validateCron(expression: string): boolean
438
+ getNextCronTime(expression: string, after?: Date): Date
439
+ describeCron(expression: string): string
440
+ }
441
+
442
+ interface HttpResponse {
443
+ status: number
444
+ statusText: string
445
+ headers: Record<string, string>
446
+ data: string
447
+ }
448
+
449
+ interface MulbyHttp {
450
+ request(options: {
451
+ url: string
452
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD'
453
+ headers?: Record<string, string>
454
+ body?: unknown
455
+ timeout?: number
456
+ }): Promise<HttpResponse>
457
+ get(url: string, headers?: Record<string, string>): Promise<HttpResponse>
458
+ post(url: string, body?: unknown, headers?: Record<string, string>): Promise<HttpResponse>
459
+ put(url: string, body?: unknown, headers?: Record<string, string>): Promise<HttpResponse>
460
+ delete(url: string, headers?: Record<string, string>): Promise<HttpResponse>
461
+ }
462
+
463
+ type AiSkillSource = 'manual' | 'local-dir' | 'zip' | 'json' | 'builtin' | 'system'
464
+ type AiSkillTrustLevel = 'untrusted' | 'reviewed' | 'trusted'
465
+
466
+ type AiMessage = {
467
+ role: 'system' | 'user' | 'assistant'
468
+ content?: string | AiMessageContent[]
469
+ reasoning_content?: string
470
+ chunkType?: 'meta' | 'text' | 'reasoning' | 'tool-call' | 'tool-result' | 'error' | 'end'
471
+ capability_debug?: {
472
+ requested: string[]
473
+ allowed: string[]
474
+ denied: string[]
475
+ reasons: string[]
476
+ selectedSkills?: Array<{ id: string; source: AiSkillSource; trustLevel: AiSkillTrustLevel }>
477
+ }
478
+ policy_debug?: {
479
+ skills: {
480
+ requested?: AiSkillSelection
481
+ selectedSkillIds: string[]
482
+ selectedSkillNames: string[]
483
+ reasons: string[]
484
+ }
485
+ mcp: { requested?: AiMcpSelection; resolved?: AiMcpSelection }
486
+ toolContext: { requested?: AiToolContext; resolved?: AiToolContext }
487
+ capabilities: { requested: string[]; resolved: string[] }
488
+ internalTools: { requested: string[]; resolved: string[] }
489
+ }
490
+ tool_call?: { id: string; name: string; args?: unknown }
491
+ tool_result?: { id: string; name: string; result?: unknown }
492
+ error?: { message: string; code?: string; category?: string; retryable?: boolean; statusCode?: number }
493
+ usage?: AiTokenBreakdown
494
+ }
495
+ type AiMessageContent =
496
+ | { type: 'text'; text: string }
497
+ | { type: 'image'; attachmentId: string; mimeType?: string }
498
+ | { type: 'file'; attachmentId: string; mimeType?: string; filename?: string }
499
+ type AiTool = {
500
+ type: 'function'
501
+ function?: {
502
+ name: string
503
+ description: string
504
+ parameters: {
505
+ type: 'object'
506
+ properties: Record<string, unknown>
507
+ required?: string[]
508
+ additionalProperties?: boolean
509
+ }
510
+ required?: string[]
511
+ }
512
+ }
513
+ type AiModelParameters = {
514
+ contextWindow?: number
515
+ temperatureEnabled?: boolean
516
+ topPEnabled?: boolean
517
+ maxOutputTokensEnabled?: boolean
518
+ temperature?: number
519
+ topP?: number
520
+ topK?: number
521
+ maxOutputTokens?: number
522
+ presencePenalty?: number
523
+ frequencyPenalty?: number
524
+ stopSequences?: string[]
525
+ seed?: number
526
+ }
527
+ type AiMcpSelection = { mode?: 'off' | 'manual' | 'auto'; serverIds?: string[]; allowedToolIds?: string[] }
528
+ type AiSkillSelection = {
529
+ mode?: 'off' | 'manual' | 'auto'
530
+ skillIds?: string[]
531
+ variables?: Record<string, string>
532
+ }
533
+ type AiOption = {
534
+ model?: string
535
+ messages: AiMessage[]
536
+ tools?: AiTool[]
537
+ capabilities?: string[]
538
+ internalTools?: string[]
539
+ toolingPolicy?: {
540
+ enableInternalTools?: boolean
541
+ capabilityAllowList?: string[]
542
+ capabilityDenyList?: string[]
543
+ }
544
+ mcp?: AiMcpSelection
545
+ skills?: AiSkillSelection
546
+ params?: AiModelParameters
547
+ toolContext?: AiToolContext
548
+ maxToolSteps?: number
549
+ }
550
+ type AiEndpointType = 'openai' | 'openai-response' | 'anthropic' | 'gemini' | 'image-generation' | 'jina-rerank'
551
+ type AiModelType = 'text' | 'vision' | 'embedding' | 'reasoning' | 'function_calling' | 'web_search' | 'rerank'
552
+ type AiModelCapability = { type: AiModelType; isUserSelected?: boolean }
553
+ type AiModel = {
554
+ id: string
555
+ label: string
556
+ description: string
557
+ icon?: string
558
+ providerRef?: string
559
+ providerLabel?: string
560
+ endpointType?: AiEndpointType
561
+ supportedEndpointTypes?: AiEndpointType[]
562
+ params?: AiModelParameters
563
+ capabilities?: AiModelCapability[]
564
+ }
565
+ type AiProviderConfig = {
566
+ id: string
567
+ type?: string
568
+ label?: string
569
+ enabled: boolean
570
+ apiKey?: string
571
+ baseURL?: string
572
+ apiVersion?: string
573
+ anthropicBaseURL?: string
574
+ headers?: Record<string, string>
575
+ defaultModel?: string
576
+ defaultParams?: AiModelParameters
577
+ }
578
+ type AiMcpServer = {
579
+ id: string
580
+ name: string
581
+ type: 'stdio' | 'sse' | 'streamableHttp'
582
+ isActive: boolean
583
+ description?: string
584
+ baseUrl?: string
585
+ command?: string
586
+ args?: string[]
587
+ env?: Record<string, string>
588
+ headers?: Record<string, string>
589
+ timeoutSec?: number
590
+ longRunning?: boolean
591
+ disabledTools?: string[]
592
+ disabledAutoApproveTools?: string[]
593
+ installSource?: 'manual' | 'protocol' | 'builtin'
594
+ isTrusted?: boolean
595
+ trustedAt?: number
596
+ installedAt?: number
597
+ }
598
+ type AiMcpSettings = {
599
+ servers: AiMcpServer[]
600
+ defaults?: { timeoutMs?: number; longRunningMaxMs?: number; approvalMode?: 'always' | 'auto-approved-only' | 'never' }
601
+ }
602
+ type AiMcpTool = {
603
+ id: string
604
+ name: string
605
+ description?: string
606
+ serverId: string
607
+ serverName: string
608
+ inputSchema?: unknown
609
+ outputSchema?: unknown
610
+ }
611
+ type AiMcpServerLogEntry = {
612
+ timestamp: number
613
+ level: 'debug' | 'info' | 'warn' | 'error'
614
+ message: string
615
+ source?: string
616
+ data?: unknown
617
+ }
618
+ type AiSkillMcpPolicy = {
619
+ serverIds?: string[]
620
+ allowedToolIds?: string[]
621
+ blockedToolIds?: string[]
622
+ }
623
+ type AiSkillRecord = {
624
+ id: string
625
+ source: AiSkillSource
626
+ origin?: 'system' | 'app'
627
+ readonly?: boolean
628
+ sourceRef?: string
629
+ installPath?: string
630
+ skillMdPath?: string
631
+ contentHash: string
632
+ enabled: boolean
633
+ trustLevel: AiSkillTrustLevel
634
+ installedAt: number
635
+ updatedAt: number
636
+ descriptor: {
637
+ id: string
638
+ name: string
639
+ description?: string
640
+ version?: string
641
+ author?: string
642
+ tags?: string[]
643
+ triggerPhrases?: string[]
644
+ mode?: 'manual' | 'auto' | 'both'
645
+ promptTemplate?: string
646
+ mcpPolicy?: AiSkillMcpPolicy
647
+ capabilities?: string[]
648
+ internalTools?: string[]
649
+ }
650
+ }
651
+ type AiSkillSettings = {
652
+ enabled: boolean
653
+ activeSkillIds: string[]
654
+ autoSelect?: { enabled?: boolean; maxSkillsPerCall?: number; minScore?: number }
655
+ records: AiSkillRecord[]
656
+ }
657
+ type AiSkillPreview = {
658
+ selected: AiSkillRecord[]
659
+ systemPrompt: string
660
+ mcpImpact: { serverIds?: string[]; allowedToolIds?: string[]; blockedToolIds?: string[] }
661
+ reasons: string[]
662
+ }
663
+ type AiSkillResolveResult = {
664
+ selectedSkillIds: string[]
665
+ selectedSkillNames: string[]
666
+ selectedSkills?: Array<{ id: string; source: AiSkillSource; trustLevel: AiSkillTrustLevel }>
667
+ systemPrompts: string[]
668
+ mergedMcp?: AiMcpSelection
669
+ toolContextPatch?: AiToolContext['mcpScope']
670
+ capabilities?: string[]
671
+ internalTools?: string[]
672
+ reasons?: string[]
673
+ }
674
+ type AiSkillCreateModelOption = {
675
+ id: string
676
+ label: string
677
+ providerRef?: string
678
+ providerLabel?: string
679
+ }
680
+ type AiSkillCreateWithAiInput = {
681
+ requirements: string
682
+ model: string
683
+ previousRawText?: string
684
+ replaceSkillId?: string
685
+ enabled?: boolean
686
+ trustLevel?: AiSkillTrustLevel
687
+ modePreference?: 'manual' | 'auto' | 'both'
688
+ }
689
+ type AiSkillCreateWithAiResult = {
690
+ record: AiSkillRecord
691
+ generation: { model: string; rawText: string; notes?: string[] }
692
+ }
693
+ type AiSkillCreateProgressChunk = {
694
+ type: 'status' | 'content' | 'reasoning'
695
+ text: string
696
+ stage?: 'generating' | 'parsing' | 'validating' | 'writing' | 'completed'
697
+ stageStatus?: 'start' | 'done' | 'error'
698
+ }
699
+ type AiToolContext = {
700
+ pluginName?: string
701
+ internalTag?: string
702
+ mcpScope?: { allowedServerIds?: string[]; allowedToolIds?: string[] }
703
+ }
704
+ type AiSettings = {
705
+ providers: AiProviderConfig[]
706
+ models?: AiModel[]
707
+ defaultModel?: string
708
+ defaultParams?: AiModelParameters
709
+ mcp?: AiMcpSettings
710
+ skills?: AiSkillSettings
711
+ }
712
+ type AiAttachmentRef = { attachmentId: string; mimeType: string; size: number; filename?: string; expiresAt?: string; purpose?: string }
713
+ type AiTokenBreakdown = { inputTokens: number; outputTokens: number }
714
+ type AiImageGenerateProgressChunk = {
715
+ type: 'status' | 'preview'
716
+ stage?: 'start' | 'partial' | 'finalizing' | 'completed' | 'fallback'
717
+ message?: string
718
+ image?: string
719
+ index?: number
720
+ received?: number
721
+ total?: number
722
+ }
723
+ type AiPromiseLike<T> = Promise<T> & { abort: () => void }
724
+
725
+ interface MulbyAi {
726
+ call(option: AiOption, onChunk?: (chunk: AiMessage) => void): AiPromiseLike<AiMessage>
727
+ allModels(): Promise<AiModel[]>
728
+ abort(requestId: string): Promise<void>
729
+ skills: {
730
+ list(): Promise<AiSkillRecord[]>
731
+ refresh(): Promise<AiSkillRecord[]>
732
+ listEnabled(): Promise<AiSkillRecord[]>
733
+ get(skillId: string): Promise<AiSkillRecord | null>
734
+ listCreateModels(): Promise<AiSkillCreateModelOption[]>
735
+ createWithAi(input: AiSkillCreateWithAiInput): Promise<AiSkillCreateWithAiResult>
736
+ createWithAiStream(
737
+ input: AiSkillCreateWithAiInput,
738
+ onChunk: (chunk: AiSkillCreateProgressChunk) => void
739
+ ): AiPromiseLike<AiSkillCreateWithAiResult>
740
+ create(input: {
741
+ id?: string
742
+ name: string
743
+ description?: string
744
+ promptTemplate?: string
745
+ tags?: string[]
746
+ triggerPhrases?: string[]
747
+ mode?: 'manual' | 'auto' | 'both'
748
+ capabilities?: string[]
749
+ internalTools?: string[]
750
+ enabled?: boolean
751
+ trustLevel?: AiSkillTrustLevel
752
+ mcpPolicy?: AiSkillMcpPolicy
753
+ }): Promise<AiSkillRecord>
754
+ install(input: { source: 'local-dir' | 'zip'; ref: string; trustLevel?: AiSkillTrustLevel; enabled?: boolean }): Promise<AiSkillRecord[]>
755
+ importFromJson(input: { json: string; trustLevel?: AiSkillTrustLevel; enabled?: boolean }): Promise<AiSkillRecord[]>
756
+ update(skillId: string, patch: Partial<AiSkillRecord>): Promise<AiSkillRecord>
757
+ remove(skillId: string): Promise<void>
758
+ enable(skillId: string): Promise<AiSkillRecord>
759
+ disable(skillId: string): Promise<AiSkillRecord>
760
+ preview(input: { option?: Partial<AiOption>; skillIds?: string[]; prompt?: string }): Promise<AiSkillPreview>
761
+ resolve(option: AiOption): Promise<AiSkillResolveResult>
762
+ }
763
+ tokens: {
764
+ estimate(input: { model?: string; messages: AiMessage[]; outputText?: string }): Promise<AiTokenBreakdown>
765
+ }
766
+ attachments: {
767
+ upload(input: { filePath?: string; buffer?: ArrayBuffer; mimeType: string; purpose?: string }): Promise<AiAttachmentRef>
768
+ get(attachmentId: string): Promise<AiAttachmentRef | null>
769
+ delete(attachmentId: string): Promise<void>
770
+ uploadToProvider(input: {
771
+ attachmentId: string
772
+ model?: string
773
+ providerId?: string
774
+ purpose?: string
775
+ }): Promise<{ providerId: string; fileId: string; uri?: string }>
776
+ }
777
+ images: {
778
+ generate(input: { model: string; prompt: string; size?: string; count?: number }): Promise<{ images: string[]; tokens: AiTokenBreakdown }>
779
+ generateStream(
780
+ input: { model: string; prompt: string; size?: string; count?: number },
781
+ onChunk: (chunk: AiImageGenerateProgressChunk) => void
782
+ ): AiPromiseLike<{ images: string[]; tokens: AiTokenBreakdown }>
783
+ edit(input: { model: string; imageAttachmentId: string; prompt: string }): Promise<{ images: string[]; tokens: AiTokenBreakdown }>
784
+ }
785
+ models: {
786
+ fetch(input: { providerId: string; baseURL?: string; apiKey?: string }): Promise<{ models: AiModel[]; message?: string }>
787
+ }
788
+ testConnection(input?: { providerId?: string; model?: string; baseURL?: string; apiKey?: string }): Promise<{ success: boolean; message?: string }>
789
+ testConnectionStream(
790
+ input: { providerId?: string; model?: string; baseURL?: string; apiKey?: string },
791
+ onChunk: (chunk: { type: 'reasoning' | 'content'; text: string }) => void
792
+ ): AiPromiseLike<{ success: boolean; message?: string; reasoning?: string }>
793
+ settings: {
794
+ get(): Promise<AiSettings>
795
+ update(next: Partial<AiSettings>): Promise<AiSettings>
796
+ }
797
+ mcp?: {
798
+ listServers(): Promise<AiMcpServer[]>
799
+ getServer(serverId: string): Promise<AiMcpServer | null>
800
+ upsertServer(server: AiMcpServer): Promise<AiMcpServer>
801
+ removeServer(serverId: string): Promise<void>
802
+ activateServer(serverId: string): Promise<AiMcpServer>
803
+ deactivateServer(serverId: string): Promise<AiMcpServer>
804
+ restartServer(serverId: string): Promise<AiMcpServer>
805
+ checkServer(serverId: string): Promise<{ ok: boolean; message?: string }>
806
+ listTools(serverId: string): Promise<AiMcpTool[]>
807
+ abort(callId: string): Promise<boolean>
808
+ getLogs(serverId: string): Promise<AiMcpServerLogEntry[]>
809
+ }
810
+ }
811
+
812
+ interface FileStat {
813
+ name: string
814
+ path: string
815
+ size: number
816
+ isFile: boolean
817
+ isDirectory: boolean
818
+ createdAt: number
819
+ modifiedAt: number
820
+ }
821
+
822
+ interface MulbyFilesystem {
823
+ readFile(path: string, encoding?: 'utf-8' | 'base64'): Promise<string | ArrayBuffer>
824
+ writeFile(path: string, data: string | ArrayBuffer, encoding?: 'utf-8' | 'base64'): Promise<void>
825
+ exists(path: string): Promise<boolean>
826
+ unlink(path: string): Promise<void>
827
+ readdir(path: string): Promise<string[]>
828
+ mkdir(path: string): Promise<void>
829
+ stat(path: string): Promise<FileStat | null>
830
+ copy(src: string, dest: string): Promise<void>
831
+ move(src: string, dest: string): Promise<void>
832
+ }
833
+
834
+ interface MulbyHost {
835
+ invoke(pluginName: string, method: string, ...args: unknown[]): Promise<unknown>
836
+ call(pluginName: string, method: string, ...args: unknown[]): Promise<{ data: any }>
837
+ status(pluginName: string): Promise<{ ready: boolean; active: boolean }>
838
+ restart(pluginName: string): Promise<boolean>
839
+ }
840
+
841
+ interface FFmpegRunProgress {
842
+ bitrate: string
843
+ fps: number
844
+ frame: number
845
+ percent?: number
846
+ q: number | string
847
+ size: string
848
+ speed: string
849
+ time: string
850
+ }
851
+
852
+ interface FFmpegDownloadProgress {
853
+ phase: 'downloading' | 'extracting' | 'done'
854
+ percent: number
855
+ downloaded?: number
856
+ total?: number
857
+ }
858
+
859
+ interface FFmpegTask {
860
+ promise: Promise<void>
861
+ kill(): void
862
+ quit(): void
863
+ }
864
+
865
+ interface MulbyFFmpeg {
866
+ isAvailable(): Promise<boolean>
867
+ getVersion(): Promise<string | null>
868
+ getPath(): Promise<string | null>
869
+ download(onProgress?: (progress: FFmpegDownloadProgress) => void): Promise<{ success: boolean; error?: string }>
870
+ run(args: string[], onProgress?: (progress: FFmpegRunProgress) => void): FFmpegTask
871
+ }
872
+
873
+ interface Attachment {
874
+ id: string
875
+ name: string
876
+ size: number
877
+ kind: 'file' | 'image'
878
+ mime?: string
879
+ ext?: string
880
+ path?: string
881
+ dataUrl?: string
882
+ }
883
+
884
+ interface PluginInitData {
885
+ pluginName: string
886
+ featureCode: string
887
+ feature?: string
888
+ input: string
889
+ mode?: string
890
+ route?: string
891
+ attachments?: Attachment[]
892
+ }
893
+
894
+ interface MulbyAPI {
895
+ clipboard: MulbyClipboard
896
+ clipboardHistory: MulbyClipboardHistory
897
+ input: MulbyInput
898
+ notification: MulbyNotification
899
+ window: MulbyWindow
900
+ subInput: MulbySubInput
901
+ plugin: MulbyPlugin
902
+ theme?: MulbyTheme
903
+ ai: MulbyAi
904
+ screen: MulbyScreen
905
+ shell: MulbyShell
906
+ dialog: MulbyDialog
907
+ system: MulbySystem
908
+ permission: MulbyPermission
909
+ shortcut: MulbyShortcut
910
+ security: MulbySecurity
911
+ media: MulbyMedia
912
+ power: MulbyPower
913
+ tray: MulbyTray
914
+ network: MulbyNetwork
915
+ menu: MulbyMenu
916
+ geolocation: MulbyGeolocation
917
+ tts: MulbyTTS
918
+ storage: MulbyStorage
919
+ http: MulbyHttp
920
+ filesystem: MulbyFilesystem
921
+ messaging: MulbyMessaging
922
+ scheduler: MulbyScheduler
923
+ host?: MulbyHost
924
+ onPluginInit(callback: (data: PluginInitData) => void): void
925
+ onPluginAttach?(callback: (data: { pluginName: string; displayName: string; featureCode: string; input: string; uiPath: string; preloadPath: string }) => void): void
926
+ onPluginDetached?(callback: () => void): void
927
+ onThemeChange?(callback: (theme: 'light' | 'dark') => void): void
928
+ onWindowStateChange?(callback: (state: { isMaximized: boolean }) => void): void
929
+ inbrowser: {
930
+ goto: (url: string, headers?: Record<string, string>, timeout?: number) => any
931
+ useragent: (ua: string) => any
932
+ device: (name: string) => any
933
+ viewport: (width: number, height: number) => any
934
+ show: () => any
935
+ hide: () => any
936
+ evaluate: (func: string | Function, ...params: any[]) => any
937
+ wait: (msOrSelector: number | string) => any
938
+ click: (selector: string) => any
939
+ mousedown: (selector: string) => any
940
+ mouseup: (selector: string) => any
941
+ scroll: (selector: string | number, y?: number) => any
942
+ devTools: (mode?: 'right' | 'bottom' | 'undocked' | 'detach') => any
943
+ paste: (text: string) => any
944
+ file: (selector: string, payload: string | string[]) => any
945
+ end: () => any
946
+ type: (selector: string, text: string) => any
947
+ press: (key: string, modifiers?: string[]) => any
948
+ check: (selector: string, checked: boolean) => any
949
+ value: (selector: string, val: string) => any
950
+ focus: (selector: string) => any
951
+ when: (selector: string | Function, ...params: any[]) => any
952
+ css: (css: string) => any
953
+ pdf: (options?: any, savePath?: string) => any
954
+ cookies: (nameOrFilter?: string | any) => any
955
+ clearCookies: (url?: string) => any
956
+ input: (selectorOrText: string, text?: string) => any
957
+ dblclick: (selector: string) => any
958
+ hover: (selector: string) => any
959
+ screenshot: (target?: any, savePath?: string) => any
960
+ drop: (selector: string, payload: any) => any
961
+ download: (urlOrFunc: string | Function, savePath?: string, ...params: any[]) => any
962
+ removeCookies: (name: string) => any
963
+ setCookies: (nameOrCookies: any, value?: string) => any
964
+ markdown: (selector?: string) => any
965
+ getIdleInBrowsers: () => Promise<any[]>
966
+ setInBrowserProxy: (config: any) => Promise<boolean>
967
+ clearInBrowserCache: () => Promise<boolean>
968
+ run: (idOrOptions?: number | any, options?: any) => Promise<any[]>
969
+ }
970
+ sharp: MulbySharpFunction
971
+ getSharpVersion: () => Promise<{ sharp: Record<string, string>; format: Record<string, any> }>
972
+ ffmpeg: MulbyFFmpeg
973
+ }
974
+
975
+ type BackendPermissionType = 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar'
976
+
977
+ interface BackendScheduler {
978
+ schedule(task: {
979
+ name: string
980
+ type: 'once' | 'repeat' | 'delay'
981
+ callback: string
982
+ time?: number
983
+ cron?: string
984
+ delay?: number
985
+ payload?: any
986
+ maxRetries?: number
987
+ retryDelay?: number
988
+ timeout?: number
989
+ description?: string
990
+ endTime?: number
991
+ maxExecutions?: number
992
+ }): Promise<any>
993
+ cancel(taskId: string): Promise<void>
994
+ pause(taskId: string): Promise<void>
995
+ resume(taskId: string): Promise<void>
996
+ get(taskId: string): Promise<any>
997
+ list(filter?: { status?: string; type?: string; limit?: number }): Promise<any[]>
998
+ getExecutions(taskId: string, limit?: number): Promise<any[]>
999
+ validateCron(expression: string): boolean
1000
+ getNextCronTime(expression: string, after?: Date): Date
1001
+ describeCron(expression: string): string
1002
+ }
1003
+
1004
+ interface BackendMulbyAi {
1005
+ call(option: AiOption, onChunk?: (chunk: AiMessage) => void): AiPromiseLike<AiMessage>
1006
+ allModels(): Promise<AiModel[]>
1007
+ abort(requestId: string): void
1008
+ skills: {
1009
+ listEnabled(): Promise<AiSkillRecord[]>
1010
+ previewForCall(input: { option?: Partial<AiOption>; skillIds?: string[]; prompt?: string }): Promise<AiSkillPreview>
1011
+ }
1012
+ attachments: {
1013
+ upload(input: { filePath?: string; buffer?: ArrayBuffer; mimeType: string; purpose?: string }): Promise<AiAttachmentRef>
1014
+ get(attachmentId: string): Promise<AiAttachmentRef | null>
1015
+ delete(attachmentId: string): Promise<void>
1016
+ uploadToProvider(input: { attachmentId: string; model?: string; providerId?: string; purpose?: string }): Promise<{ providerId: string; fileId: string; uri?: string }>
1017
+ }
1018
+ tokens: {
1019
+ estimate(input: { model?: string; messages: AiMessage[]; outputText?: string }): Promise<AiTokenBreakdown>
1020
+ }
1021
+ images: {
1022
+ generate(input: { prompt: string; model: string; size?: string; count?: number }): Promise<{ images: string[]; tokens: AiTokenBreakdown }>
1023
+ generateStream(
1024
+ input: { prompt: string; model: string; size?: string; count?: number },
1025
+ onChunk: (chunk: AiImageGenerateProgressChunk) => void
1026
+ ): AiPromiseLike<{ images: string[]; tokens: AiTokenBreakdown }>
1027
+ edit(input: { imageAttachmentId: string; prompt: string; model: string }): Promise<{ images: string[]; tokens: AiTokenBreakdown }>
1028
+ }
1029
+ }
1030
+
1031
+ interface BackendPluginAPI {
1032
+ clipboard: {
1033
+ readText(): string
1034
+ writeText(text: string): Promise<void>
1035
+ readImage(): Uint8Array | null
1036
+ writeImage(buffer: Uint8Array): void
1037
+ readFiles(): Array<{ path: string; name: string; size: number; isDirectory: boolean }>
1038
+ getFormat(): 'text' | 'image' | 'files' | 'empty'
1039
+ }
1040
+ clipboardHistory: MulbyClipboardHistory
1041
+ notification: MulbyNotification
1042
+ storage: {
1043
+ get(key: string): unknown
1044
+ set(key: string, value: unknown): unknown
1045
+ remove(key: string): unknown
1046
+ clear(): unknown
1047
+ keys(): string[]
1048
+ }
1049
+ filesystem: {
1050
+ readFile(path: string, encoding?: 'utf-8' | 'base64'): Promise<string | Uint8Array>
1051
+ writeFile(path: string, data: string | Uint8Array, encoding?: 'utf-8' | 'base64'): Promise<void>
1052
+ exists(path: string): Promise<boolean>
1053
+ unlink(path: string): Promise<void>
1054
+ readdir(path: string): Promise<string[]>
1055
+ mkdir(path: string): Promise<void>
1056
+ stat(path: string): Promise<any>
1057
+ copy(src: string, dest: string): Promise<void>
1058
+ move(src: string, dest: string): Promise<void>
1059
+ extname(path: string): string
1060
+ join(...paths: string[]): string
1061
+ dirname(path: string): string
1062
+ basename(path: string, ext?: string): string
1063
+ }
1064
+ http: MulbyHttp
1065
+ screen: {
1066
+ getAllDisplays(): Promise<any[]>
1067
+ getPrimaryDisplay(): Promise<any>
1068
+ getDisplayNearestPoint(point: { x: number; y: number }): Promise<any>
1069
+ getCursorScreenPoint(): Promise<{ x: number; y: number }>
1070
+ getSources(options?: any): Promise<any[]>
1071
+ capture(options?: any): Promise<Uint8Array>
1072
+ captureRegion(region: { x: number; y: number; width: number; height: number }, options?: any): Promise<Uint8Array>
1073
+ getMediaStreamConstraints(options: any): Promise<any>
1074
+ }
1075
+ shell: {
1076
+ openPath(path: string): Promise<string>
1077
+ openExternal(url: string): Promise<void>
1078
+ showItemInFolder(path: string): void
1079
+ openFolder(path: string): Promise<string>
1080
+ trashItem(path: string): Promise<void>
1081
+ beep(): void
1082
+ runCommand(input: {
1083
+ command: string
1084
+ args?: string[]
1085
+ cwd?: string
1086
+ env?: Record<string, string>
1087
+ timeoutMs?: number
1088
+ shell?: boolean
1089
+ }): Promise<any>
1090
+ getRunCommandPolicy(): Promise<{
1091
+ enabled: boolean
1092
+ requireConsent: boolean
1093
+ allowShell: boolean
1094
+ allowList?: string[]
1095
+ denyList?: string[]
1096
+ }>
1097
+ listRunCommandAudit(limit?: number): Promise<any[]>
1098
+ }
1099
+ dialog: MulbyDialog
1100
+ system: {
1101
+ getSystemInfo(): Promise<any>
1102
+ getAppInfo(): Promise<any>
1103
+ getPath(name: 'home' | 'appData' | 'userData' | 'temp' | 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos'): Promise<string>
1104
+ getEnv(name: string): Promise<string>
1105
+ getIdleTime(): Promise<number>
1106
+ }
1107
+ shortcut: {
1108
+ register(accelerator: string, callback: () => void): boolean
1109
+ unregister(accelerator: string): void
1110
+ unregisterAll(): void
1111
+ isRegistered(accelerator: string): boolean
1112
+ }
1113
+ security: {
1114
+ isEncryptionAvailable(): boolean
1115
+ encryptString(plainText: string): Uint8Array
1116
+ decryptString(encrypted: Uint8Array | ArrayBuffer): string
1117
+ }
1118
+ media: {
1119
+ getAccessStatus(mediaType: 'microphone' | 'camera'): 'not-determined' | 'granted' | 'denied' | 'restricted' | 'unknown'
1120
+ askForAccess(mediaType: 'microphone' | 'camera'): Promise<boolean>
1121
+ hasCameraAccess(): Promise<boolean>
1122
+ hasMicrophoneAccess(): Promise<boolean>
1123
+ }
1124
+ power: {
1125
+ getSystemIdleTime(): number
1126
+ getSystemIdleState(idleThreshold: number): 'active' | 'idle' | 'locked' | 'unknown'
1127
+ isOnBatteryPower(): boolean
1128
+ getCurrentThermalState(): 'unknown' | 'nominal' | 'fair' | 'serious' | 'critical'
1129
+ }
1130
+ tray: {
1131
+ create(options: { icon: string; tooltip?: string; title?: string }): boolean
1132
+ destroy(): void
1133
+ setIcon(icon: string): void
1134
+ setTooltip(tooltip: string): void
1135
+ setTitle(title: string): void
1136
+ exists(): boolean
1137
+ }
1138
+ network: {
1139
+ isOnline(): boolean
1140
+ }
1141
+ input: Record<string, (...args: any[]) => any>
1142
+ permission: {
1143
+ getStatus(type: BackendPermissionType): any
1144
+ request(type: BackendPermissionType): Promise<any>
1145
+ canRequest(type: BackendPermissionType): any
1146
+ openSystemSettings(type: BackendPermissionType): Promise<any>
1147
+ isAccessibilityTrusted(): boolean
1148
+ }
1149
+ features: {
1150
+ getFeatures(codes?: string[]): Array<{ code: string }>
1151
+ setFeature(feature: {
1152
+ code: string
1153
+ explain?: string
1154
+ icon?: string
1155
+ platform?: string | string[]
1156
+ mode?: 'ui' | 'silent' | 'detached'
1157
+ route?: string
1158
+ mainHide?: boolean
1159
+ mainPush?: boolean
1160
+ cmds: Array<
1161
+ | string
1162
+ | { type: 'keyword'; value: string; explain?: string }
1163
+ | { type: 'regex'; match: string; explain?: string; label?: string; minLength?: number; maxLength?: number }
1164
+ | { type: 'files'; exts?: string[]; fileType?: 'file' | 'directory' | 'any'; match?: string; minLength?: number; maxLength?: number }
1165
+ | { type: 'img'; exts?: string[] }
1166
+ | { type: 'over'; label?: string; exclude?: string; minLength?: number; maxLength?: number }
1167
+ >
1168
+ }): void
1169
+ removeFeature(code: string): boolean
1170
+ redirectHotKeySetting(cmdLabel: string, autocopy?: boolean): void
1171
+ redirectAiModelsSetting(): void
1172
+ }
1173
+ messaging: MulbyMessaging
1174
+ ai: BackendMulbyAi
1175
+ scheduler: BackendScheduler
1176
+ }
1177
+
1178
+ interface BackendPluginContext {
1179
+ api: BackendPluginAPI
1180
+ featureCode?: string
1181
+ input?: string
1182
+ attachments?: Attachment[]
1183
+ }
1184
+
1185
+ interface MulbySharpProxy {
1186
+ resize(width?: number, height?: number, options?: object): MulbySharpProxy
1187
+ extend(options: object): MulbySharpProxy
1188
+ extract(options: { left: number; top: number; width: number; height: number }): MulbySharpProxy
1189
+ trim(options?: object): MulbySharpProxy
1190
+ rotate(angle?: number, options?: object): MulbySharpProxy
1191
+ flip(): MulbySharpProxy
1192
+ flop(): MulbySharpProxy
1193
+ blur(sigma?: number): MulbySharpProxy
1194
+ sharpen(options?: object): MulbySharpProxy
1195
+ flatten(options?: object): MulbySharpProxy
1196
+ gamma(gamma?: number): MulbySharpProxy
1197
+ negate(options?: object): MulbySharpProxy
1198
+ normalize(options?: object): MulbySharpProxy
1199
+ threshold(threshold?: number, options?: object): MulbySharpProxy
1200
+ modulate(options?: object): MulbySharpProxy
1201
+ tint(color: string | object): MulbySharpProxy
1202
+ greyscale(greyscale?: boolean): MulbySharpProxy
1203
+ grayscale(grayscale?: boolean): MulbySharpProxy
1204
+ composite(images: object[]): MulbySharpProxy
1205
+ png(options?: object): MulbySharpProxy
1206
+ jpeg(options?: object): MulbySharpProxy
1207
+ webp(options?: object): MulbySharpProxy
1208
+ gif(options?: object): MulbySharpProxy
1209
+ tiff(options?: object): MulbySharpProxy
1210
+ avif(options?: object): MulbySharpProxy
1211
+ withMetadata(options?: object): MulbySharpProxy
1212
+ clone(): MulbySharpProxy
1213
+ toBuffer(options?: object): Promise<ArrayBuffer>
1214
+ toFile(fileOut: string): Promise<{ format: string; width: number; height: number; channels: number; size: number }>
1215
+ metadata(): Promise<{ format?: string; width?: number; height?: number; channels?: number; space?: string; depth?: string; density?: number; hasAlpha?: boolean; orientation?: number }>
1216
+ stats(): Promise<object>
1217
+ }
1218
+
1219
+ type MulbySharpFunction = (
1220
+ input?: string | ArrayBuffer | Uint8Array | object | any[],
1221
+ options?: object
1222
+ ) => MulbySharpProxy
1223
+
1224
+ interface Window {
1225
+ mulby: MulbyAPI
1226
+ }
1227
+ `;
1228
+ }