@medeo-plugin/sdk 0.0.0-stage → 0.7.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 +27 -2
- package/dist/generated.d.ts +497 -0
- package/dist/generated.js +1 -0
- package/dist/index.d.ts +875 -0
- package/dist/index.js +309 -0
- package/dist/registry.d.ts +1132 -0
- package/dist/registry.js +172 -0
- package/package.json +38 -4
- package/src/generated.ts +158 -0
- package/src/index.ts +393 -0
- package/src/registry.ts +173 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import type {JsonValue} from './generated.ts';
|
|
2
|
+
import type {MethodName} from './registry.ts';
|
|
3
|
+
export {METHODS, LIMITS, type MethodName} from './registry.ts';
|
|
4
|
+
/** One SDK for both runtimes: a sandboxed worker/window, and a `runtime: "node"`
|
|
5
|
+
* plugin, whose bootstrap installs the same `medeoPlugin` surface. The SDK itself
|
|
6
|
+
* imports nothing from Node and asserts no identity of its own. */
|
|
7
|
+
export type { Manifest, PluginCommand, Permission, CapabilityDescriptor } from './generated.ts';
|
|
8
|
+
/** The `api_version` this SDK targets; `spec/api-v1.json` carries the same number. */
|
|
9
|
+
export const API_VERSION = 1;
|
|
10
|
+
export interface PluginAPI {
|
|
11
|
+
onLocaleChanged(callback:(state:PluginLocaleState)=>void):()=>void;
|
|
12
|
+
onEvent(callback:(event:PlatformEvent)=>void):()=>void;
|
|
13
|
+
post(message:unknown):Promise<void>;
|
|
14
|
+
onMessage(callback:(message:unknown)=>void):()=>void;
|
|
15
|
+
invoke(method: MethodName, args?: Record<string, unknown>): Promise<unknown>;
|
|
16
|
+
run(command: string): Promise<unknown>;
|
|
17
|
+
}
|
|
18
|
+
declare global { var medeoPlugin: PluginAPI; interface Window { medeoPlugin: PluginAPI } }
|
|
19
|
+
|
|
20
|
+
/** Pushed by the Host: an operation changed status (or streamed progress), or a
|
|
21
|
+
* plugin-owned queue has entries to pull. Events carry no payload data. */
|
|
22
|
+
export type PlatformEvent =
|
|
23
|
+
| {type:'operation';id:string;method:string;status:string;revision?:number}
|
|
24
|
+
| {type:'signal';channel:'files.watch'|'server'|'input_method'|'background'|'permissions'|'config'|'shortcuts'|'tray'};
|
|
25
|
+
/** Messages between this plugin's background worker and its own windows
|
|
26
|
+
* (64 KiB each, JSON). A worker message reaches every open window; a window
|
|
27
|
+
* message reaches the worker. Nothing is persisted or sent elsewhere. */
|
|
28
|
+
export const channel = {
|
|
29
|
+
post:(message:unknown)=>globalThis.medeoPlugin.post(message),
|
|
30
|
+
onMessage:<T=unknown>(callback:(message:T)=>void)=>globalThis.medeoPlugin.onMessage(m=>callback(m as T)),
|
|
31
|
+
};
|
|
32
|
+
export const events = {
|
|
33
|
+
on:(callback:(event:PlatformEvent)=>void)=>globalThis.medeoPlugin.onEvent(callback),
|
|
34
|
+
/** Call `pull` now and again whenever the channel signals new entries. A
|
|
35
|
+
* failed pull (e.g. a permission withdrawn meanwhile) waits for the next signal. */
|
|
36
|
+
onSignal(channel:Extract<PlatformEvent,{type:'signal'}>['channel'],pull:()=>unknown){
|
|
37
|
+
const run=()=>{void Promise.resolve().then(pull).catch(()=>{})};
|
|
38
|
+
const off=globalThis.medeoPlugin.onEvent(event=>{if(event.type==='signal'&&event.channel===channel)run()});
|
|
39
|
+
run();return off;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
/** Resolves on the next event for `id`, or after `fallbackMs` as a safety net. */
|
|
43
|
+
function nextChange(id:string,fallbackMs:number):{promise:Promise<void>;off:()=>void}{
|
|
44
|
+
let off=()=>{};
|
|
45
|
+
const promise=new Promise<void>(resolve=>{
|
|
46
|
+
const timer=setTimeout(resolve,fallbackMs);
|
|
47
|
+
const stop=globalThis.medeoPlugin.onEvent(event=>{if(event.type==='operation'&&event.id===id){clearTimeout(timer);resolve()}});
|
|
48
|
+
off=()=>{clearTimeout(timer);stop()};
|
|
49
|
+
});
|
|
50
|
+
return {promise,off};
|
|
51
|
+
}
|
|
52
|
+
export const storage = {
|
|
53
|
+
get: <T = unknown>(key: string) => globalThis.medeoPlugin.invoke('storage.get', { key }) as Promise<T | null>,
|
|
54
|
+
remove: (key:string) => globalThis.medeoPlugin.invoke('storage.remove',{key}),
|
|
55
|
+
set: (key: string, value: unknown) => globalThis.medeoPlugin.invoke('storage.set', { key, value }),
|
|
56
|
+
};
|
|
57
|
+
export const creation = { open: () => globalThis.medeoPlugin.invoke('creation.open') };
|
|
58
|
+
export const commands = { run: (command: string) => globalThis.medeoPlugin.run(command) };
|
|
59
|
+
export interface Disposable { dispose(): unknown }
|
|
60
|
+
/** Passed to `activate` (VS Code style), in both runtimes. */
|
|
61
|
+
export interface PluginContext {
|
|
62
|
+
/** Disposed, in reverse order, when the plugin stops. */
|
|
63
|
+
subscriptions: Disposable[];
|
|
64
|
+
/** Register a handler for each command the manifest declares; all must be registered when `activate` returns. */
|
|
65
|
+
commands: { register(id: string, handler: () => unknown | Promise<unknown>): Disposable };
|
|
66
|
+
/** `runtime: "node"` only: the installed, verified package directory (read-only). */
|
|
67
|
+
extensionPath?: string;
|
|
68
|
+
/** `runtime: "node"` only: a private writable directory that survives updates. */
|
|
69
|
+
storagePath?: string;
|
|
70
|
+
}
|
|
71
|
+
/** A plugin's background entry: export the result, e.g.
|
|
72
|
+
* `export const { activate, deactivate } = definePlugin({ activate(context) { … } })`. */
|
|
73
|
+
export interface PluginDefinition {
|
|
74
|
+
activate(context: PluginContext): unknown | Promise<unknown>;
|
|
75
|
+
deactivate?(): unknown | Promise<unknown>;
|
|
76
|
+
}
|
|
77
|
+
export function definePlugin(definition: PluginDefinition): Required<PluginDefinition> {
|
|
78
|
+
return { deactivate: () => undefined, ...definition };
|
|
79
|
+
}
|
|
80
|
+
/** Settings declared under `contributes.configuration`; the user edits them in the plugin center. */
|
|
81
|
+
export const config = {
|
|
82
|
+
get: <T = unknown>(key: string) => globalThis.medeoPlugin.invoke('config.get', { key }) as Promise<T>,
|
|
83
|
+
all: () => globalThis.medeoPlugin.invoke('config.get') as Promise<Record<string, unknown>>,
|
|
84
|
+
set: (key: string, value: unknown) => globalThis.medeoPlugin.invoke('config.set', { key, value }),
|
|
85
|
+
/** Calls `listener` with all values after each change, from the user or the plugin. */
|
|
86
|
+
onDidChange(listener: (values: Record<string, unknown>) => void): () => void {
|
|
87
|
+
return globalThis.medeoPlugin.onEvent(event => {
|
|
88
|
+
if (event.type === 'signal' && event.channel === 'config') void config.all().then(listener).catch(() => {});
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Native providers return quickly; subscribe to progress instead of holding a command open. */
|
|
94
|
+
export interface Provider { id: string; version: number; available: boolean; capabilities: string[] }
|
|
95
|
+
/** `full`: the user approved full access (view and direct Trash) for this directory. */
|
|
96
|
+
export interface Resource { id: string; name: string; available: boolean; full?: boolean }
|
|
97
|
+
/** Ask for full access (requires the `file_full_access` permission). */
|
|
98
|
+
export interface DirectoryAccess { full?: boolean }
|
|
99
|
+
export const providers = {
|
|
100
|
+
list: () => globalThis.medeoPlugin.invoke('providers.list') as Promise<Provider[]>,
|
|
101
|
+
require: async (id: string, version = 1) => {
|
|
102
|
+
const provider = (await providers.list()).find(p => p.id === id && p.version === version && p.available);
|
|
103
|
+
if (!provider) throw new Error('provider_unavailable');
|
|
104
|
+
return provider;
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
export const resources = {
|
|
108
|
+
chooseDirectories: (access: DirectoryAccess = {}) => globalThis.medeoPlugin.invoke('resources.choose_directories', access.full ? { full: true } : {}) as Promise<Resource[]>,
|
|
109
|
+
list: () => globalThis.medeoPlugin.invoke('resources.list') as Promise<Resource[]>,
|
|
110
|
+
revoke: (id: string) => globalThis.medeoPlugin.invoke('resources.revoke', { id }) as Promise<Resource[]>,
|
|
111
|
+
requestDirectory: (path: string, reason: string, access: DirectoryAccess = {}) => globalThis.medeoPlugin.invoke('resources.request_directory', { path, reason, ...(access.full ? { full: true } : {}) }) as Promise<Resource[]>,
|
|
112
|
+
};
|
|
113
|
+
/** Generic registered-provider entry point; the Host remains the authority. */
|
|
114
|
+
export const capabilities = {
|
|
115
|
+
list: () => globalThis.medeoPlugin.invoke('capabilities.list') as Promise<import('./generated').CapabilityDescriptor[]>,
|
|
116
|
+
labels: () => globalThis.medeoPlugin.invoke('capabilities.labels') as Promise<Record<string,string>>,
|
|
117
|
+
invoke: <T=unknown>(method:string,args:Record<string,unknown>={}) => globalThis.medeoPlugin.invoke(method as MethodName,args) as Promise<T>,
|
|
118
|
+
};
|
|
119
|
+
export const clipboard = {read:()=>globalThis.medeoPlugin.invoke('clipboard.read') as Promise<{text:string}>,write:(text:string)=>globalThis.medeoPlugin.invoke('clipboard.write',{text})};
|
|
120
|
+
/** `running` reports, per rule, whether a matching process exists; it never
|
|
121
|
+
* returns the process list. Rules match an exact executable name or a path fragment. */
|
|
122
|
+
export interface ProcessRule {name?:string;path_contains?:string}
|
|
123
|
+
export interface SystemInfo {platform:string;architecture:string;release:string;locale:string;/** The Medeo running the plugin (0.1.23+; absent on older Medeo). */medeo?:{version:string;channel:'stg'|'prd'};displays:{id:string;bounds:{x:number;y:number;width:number;height:number};scale:number}[]}
|
|
124
|
+
export const system = {info:()=>globalThis.medeoPlugin.invoke('system.info') as Promise<SystemInfo>,running:(rules:ProcessRule[])=>capabilities.invoke<NativeOperation<boolean[]>>('system.running',{rules})};
|
|
125
|
+
/** One outcome per path of `trash`, in the order given. */
|
|
126
|
+
export interface TrashResult {path:string;trashed:boolean;error?:string}
|
|
127
|
+
/** `runtime: "node"` plugins only (the `node` permission): moves up to 256 absolute
|
|
128
|
+
* paths to the OS Trash, the one thing Node cannot do itself. A failure does not stop the rest. */
|
|
129
|
+
export const trash = (paths:string[]) => globalThis.medeoPlugin.invoke('system.trash',{paths}) as Promise<TrashResult[]>;
|
|
130
|
+
export const notifications = {show:(id:string,title:string,body:string)=>globalThis.medeoPlugin.invoke('notifications.show',{id,title,body}),close:(id:string)=>globalThis.medeoPlugin.invoke('notifications.close',{id})};
|
|
131
|
+
export const power = {start:(type:'prevent-app-suspension'|'prevent-display-sleep')=>globalThis.medeoPlugin.invoke('power.start',{type}) as Promise<{id:string}>,stop:(id:string)=>globalThis.medeoPlugin.invoke('power.stop',{id}),state:()=>globalThis.medeoPlugin.invoke('power.state')};
|
|
132
|
+
export const shortcuts = {list:()=>globalThis.medeoPlugin.invoke('shortcuts.list') as Promise<{id:string;accelerator:string;open_ui:boolean}[]>,register:(id:string,accelerator:string,openUI=false)=>globalThis.medeoPlugin.invoke('shortcuts.register',{id,accelerator,open_ui:openUI}),unregister:(id:string)=>globalThis.medeoPlugin.invoke('shortcuts.unregister',{id}),events:()=>globalThis.medeoPlugin.invoke('shortcuts.events')};
|
|
133
|
+
/** `panel: true` (macOS): a frameless window floating over every app and Space that does not
|
|
134
|
+
* activate Medeo — the app the user was in keeps focus — opened at the pointer and hidden (not
|
|
135
|
+
* closed) when it loses focus; opening it again moves it to the pointer. `hide` keeps a window
|
|
136
|
+
* and its page alive for the next `open`/`focus`. */
|
|
137
|
+
export const appWindows = {open:(options:{id:string;entry:string;title:string;width:number;height:number;panel?:boolean})=>globalThis.medeoPlugin.invoke('windows.open',options),close:(id:string)=>globalThis.medeoPlugin.invoke('windows.close',{id}),focus:(id:string)=>globalThis.medeoPlugin.invoke('windows.focus',{id}),hide:(id:string)=>globalThis.medeoPlugin.invoke('windows.hide',{id}),list:()=>globalThis.medeoPlugin.invoke('windows.list') as Promise<{id:string;title:string;visible:boolean}[]>};
|
|
138
|
+
/** A menu entry, a checkmarked toggle, or a divider. */
|
|
139
|
+
export type TrayItem = {id:string;title:string;checked?:boolean}|{separator:true};
|
|
140
|
+
/** `icon`: a PNG in the package drawn as a menu-bar template (black + alpha, about 36 px tall);
|
|
141
|
+
* `click`: an id reported on a left click, which then leaves the menu to a right click. */
|
|
142
|
+
export interface TrayOptions {icon?:string;click?:string}
|
|
143
|
+
export const tray = {set:(title:string,items:TrayItem[],options:TrayOptions={})=>globalThis.medeoPlugin.invoke('tray.set',{title,items,...options}),remove:()=>globalThis.medeoPlugin.invoke('tray.remove'),events:()=>globalThis.medeoPlugin.invoke('tray.events')};
|
|
144
|
+
export const external = {open:(url:string)=>globalThis.medeoPlugin.invoke('external.open',{url})};
|
|
145
|
+
|
|
146
|
+
/** `scope` says how long an approval lasts: `always` (stored), `run` (until the plugin stops),
|
|
147
|
+
* `never` (refused with "don't ask again"). `remembered`: refused earlier, no dialog was shown. */
|
|
148
|
+
export interface PermissionAnswer { granted: boolean; scope?: 'always' | 'run' | 'never' | 'none'; remembered?: boolean }
|
|
149
|
+
export const permissions = {request:(permission:string,reason:string)=>globalThis.medeoPlugin.invoke('permissions.request',{permission,reason}) as Promise<PermissionAnswer>};
|
|
150
|
+
|
|
151
|
+
/** One of the plugin's own actions for the user to approve (`approvals` permission; `action` must be declared).
|
|
152
|
+
* `rule_key` identifies it (`bash:git status`); `rule_pattern` (a prefix of it ending in `*`) is what
|
|
153
|
+
* "always" remembers instead. Medeo draws the dialog and keeps the rules. In a Node plugin nothing
|
|
154
|
+
* forces you to ask: it is up to the plugin to call this before acting. */
|
|
155
|
+
export interface ApprovalRequest {
|
|
156
|
+
action: string; title: string; detail?: string;
|
|
157
|
+
preview?: { kind: 'text' | 'command' | 'diff'; text: string };
|
|
158
|
+
rule_key: string; rule_pattern?: string;
|
|
159
|
+
}
|
|
160
|
+
/** `scope`: `once`, `run`, `always`, or `rule` when a remembered answer decided without a dialog. */
|
|
161
|
+
export interface ApprovalAnswer { decision: 'allow' | 'deny'; scope: 'once' | 'run' | 'always' | 'rule'; rule?: string }
|
|
162
|
+
export interface ApprovalRule { action: string; pattern: string; allow: boolean; scope: 'run' | 'always' }
|
|
163
|
+
export const approvals = {
|
|
164
|
+
request:(request:ApprovalRequest)=>globalThis.medeoPlugin.invoke('approvals.request',{...request}) as Promise<ApprovalAnswer>,
|
|
165
|
+
rules:()=>globalThis.medeoPlugin.invoke('approvals.rules') as Promise<ApprovalRule[]>,
|
|
166
|
+
forget:(action:string,pattern:string)=>globalThis.medeoPlugin.invoke('approvals.forget',{action,pattern}) as Promise<ApprovalRule[]>,
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
// Text content stays in Host memory. Closing a window does not cancel jobs;
|
|
171
|
+
// state() without an id lists jobs owned by this active plugin instance.
|
|
172
|
+
export interface AgentJob {
|
|
173
|
+
id: string; status: 'running' | 'completed' | 'failed' | 'cancelled';
|
|
174
|
+
text?: string; models?: string[]; error?: string | null;
|
|
175
|
+
}
|
|
176
|
+
export const agent = {
|
|
177
|
+
models: () => capabilities.invoke<AgentJob>('agent.models', {}),
|
|
178
|
+
start: (messages: {role:'system'|'user'|'assistant';content:string}[], model?:string) =>
|
|
179
|
+
capabilities.invoke<AgentJob>('agent.start', {messages, ...(model ? {model} : {})}),
|
|
180
|
+
state: (id:string) => operations.state(id) as Promise<AgentJob>,
|
|
181
|
+
cancel: (id:string) => operations.cancel(id) as Promise<AgentJob>,
|
|
182
|
+
release: (id:string) => operations.release(id),
|
|
183
|
+
/** Calls `onText` as the reply streams in; resolves with the final job. */
|
|
184
|
+
async follow(id:string,onText:(job:AgentJob)=>void):Promise<AgentJob>{
|
|
185
|
+
for(;;){const change=nextChange(id,2000);const job=await agent.state(id);onText(job);if(job.status!=='running'){change.off();return job}await change.promise;change.off()}
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export interface ApplicationEntry { id:string;title:string;path:string;bundle_id:string }
|
|
190
|
+
export interface ApplicationList { status:string;error:string|null;incomplete:boolean;total:number;entries:ApplicationEntry[] }
|
|
191
|
+
export interface ApplicationState { status:string;error:string|null;launch:{id:string;status:string;error:string|null;pid?:number}|null }
|
|
192
|
+
export const applications = {
|
|
193
|
+
/** The whole inventory; plugins rank and filter it themselves. */
|
|
194
|
+
list: (refresh=false) => capabilities.invoke<ApplicationList>('applications.list',{refresh}),
|
|
195
|
+
launch: (id:string) => capabilities.invoke<{id:string;status:string}>('applications.launch',{id}),
|
|
196
|
+
state: () => capabilities.invoke<ApplicationState>('applications.state',{}),
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export interface CaptureSource {id:string;title:string;width:number;height:number}
|
|
200
|
+
export interface CaptureRecord {id:string;source_title:string;status:string;active:boolean;can_stop:boolean;can_recover:boolean;error?:string|null;playable:boolean;duration_ms:number;bytes:number;microphone:boolean;system_audio:boolean;audio_tracks?:number}
|
|
201
|
+
export const capture = {
|
|
202
|
+
status:(refresh=true)=>capabilities.invoke<{status:string;os:Record<string,string>}>('capture.status',{refresh}),
|
|
203
|
+
sources:(refresh=false,requestPermission=false)=>capabilities.invoke<{status:string;error?:string;os:Record<string,string>;sources:CaptureSource[]}>('capture.sources',{refresh,request_permission:requestPermission}),
|
|
204
|
+
start:(source:string,options:{microphone?:boolean;systemAudio?:boolean}={})=>capabilities.invoke<{id?:string;cancelled?:boolean}>('capture.start',{source,microphone:options.microphone??false,system_audio:options.systemAudio??false}),
|
|
205
|
+
state:()=>capabilities.invoke<{records:CaptureRecord[];os:Record<string,string>}>('capture.state',{}),
|
|
206
|
+
stop:(id:string)=>capabilities.invoke('capture.stop',{id}),
|
|
207
|
+
cancel:(id:string)=>capabilities.invoke('capture.cancel',{id}),
|
|
208
|
+
recover:(id:string)=>capabilities.invoke('capture.recover',{id}),
|
|
209
|
+
open:(id:string,mode:'play'|'reveal'='play')=>capabilities.invoke('capture.open',{id,mode}),
|
|
210
|
+
previewURL:(id:string)=>location.origin+'/_capture/'+encodeURIComponent(id)+'.mp4',
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export interface InputMethodState {enabled:boolean;provider_ready:boolean;configured_name:string;occupied:boolean;system_source:string}
|
|
214
|
+
export interface InputSourceState {status:string;state_key:string;can_setup:boolean;can_remove:boolean;installed?:boolean;registered?:boolean;enabled?:boolean;selected?:boolean;update_available?:boolean;error?:string;last_operation?:{id:string;status:string;error?:string};task?:string}
|
|
215
|
+
export const inputMethod={
|
|
216
|
+
system:(refresh=false)=>capabilities.invoke<InputSourceState>('input_method.system',{refresh}),
|
|
217
|
+
setup:()=>capabilities.invoke<{task?:string;cancelled?:boolean}>('input_method.setup'),
|
|
218
|
+
remove:()=>capabilities.invoke<{task?:string;cancelled?:boolean}>('input_method.remove'),
|
|
219
|
+
settings:()=>capabilities.invoke<{task:string}>('input_method.settings'),
|
|
220
|
+
status:()=>capabilities.invoke<InputMethodState>('input_method.status'),
|
|
221
|
+
configure:(name:string)=>capabilities.invoke('input_method.configure',{name}),
|
|
222
|
+
enable:()=>capabilities.invoke<InputMethodState>('input_method.enable'),
|
|
223
|
+
disable:()=>capabilities.invoke('input_method.disable'),
|
|
224
|
+
events:()=>capabilities.invoke<{id:string;text:string}[]>('input_method.events'),
|
|
225
|
+
respond:(id:string,candidates:string[])=>capabilities.invoke('input_method.respond',{id,candidates}),
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/** HTTP uses only approved origins; no redirects, browser cookies, or Medeo credentials.
|
|
229
|
+
* Closing UI preserves jobs; disable/revoke cancels. Mutations are never replayed.
|
|
230
|
+
* Release completed results to return the per-instance memory quota.
|
|
231
|
+
*/
|
|
232
|
+
export interface NetworkRequest {url:string;method?:'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'DELETE'|'OPTIONS';headers?:Record<string,string>;body?:string;body_base64?:string;timeout_ms?:number}
|
|
233
|
+
export interface NetworkJob {id:string;status:'running'|'completed'|'failed'|'cancelled';received?:number;http_status?:number|null;headers?:[string,string][];error?:string|null}
|
|
234
|
+
export interface NetworkChunk {data_base64:string;next_offset:number;eof:boolean}
|
|
235
|
+
export interface NetworkOrigin {origin:string;declared:boolean;allowed:boolean}
|
|
236
|
+
export const network = {
|
|
237
|
+
origins:()=>capabilities.invoke<NetworkOrigin[]>('network.origins'),
|
|
238
|
+
requestOrigin:(origin:string,reason:string)=>capabilities.invoke<{origin:string;granted:boolean}>('network.request_origin',{origin,reason}),
|
|
239
|
+
revokeOrigin:(origin:string)=>capabilities.invoke<NetworkOrigin[]>('network.revoke_origin',{origin}),
|
|
240
|
+
request:(request:NetworkRequest)=>capabilities.invoke<NetworkJob>('network.request',{...request}),
|
|
241
|
+
state:(id:string)=>operations.state(id) as Promise<NetworkJob>,
|
|
242
|
+
read:(id:string,offset=0,length=32768)=>capabilities.invoke<NetworkChunk>('network.read',{id,offset,length}),
|
|
243
|
+
cancel:(id:string)=>operations.cancel(id) as Promise<NetworkJob>,
|
|
244
|
+
release:(id:string)=>operations.release(id) as Promise<{released:boolean}>,
|
|
245
|
+
/** Resolves once the response has fully arrived; the job stays readable until released. */
|
|
246
|
+
async settled(id:string):Promise<NetworkJob>{for(;;){const change=nextChange(id,2000);const state=await network.state(id);if(state.status!=='running'){change.off();return state}await change.promise;change.off()}},
|
|
247
|
+
async text(id:string):Promise<string>{
|
|
248
|
+
const decoder=new TextDecoder();let offset=0,text='';
|
|
249
|
+
for(;;){const part=await network.read(id,offset);const bytes=Uint8Array.from(atob(part.data_base64),c=>c.charCodeAt(0));text+=decoder.decode(bytes,{stream:!part.eof});if(part.eof)return text;offset=part.next_offset;}
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
/** Workspace operations use current directory references and asynchronous jobs. */
|
|
254
|
+
export interface FileRoot {id:string|null;name:string;available:boolean;error?:string}
|
|
255
|
+
export interface FileEntry {path:string;name:string;kind:'file'|'directory'|'blocked';size:number;revision:string;accessible:boolean}
|
|
256
|
+
export interface FileRecord {id:string;operation:string;source:string;destination:string;status:string;has_original:boolean;in_trash?:boolean|null;created_ms:number|null;retention:"workspace"|"trash"|"none"|"unknown"}
|
|
257
|
+
export interface FileJob<T=unknown> {id:string;status:'running'|'completed'|'failed'|'cancelled';result:T|null;error:string|null;method?:string}
|
|
258
|
+
export interface FileWatch {id:string;status:'starting'|'watching'|'stopped'|'failed';cursor?:number;error?:string|null}
|
|
259
|
+
export interface FileWatchEvents extends FileWatch {cursor:number;rescan_required:boolean;events:{cursor:number;kind:'ready'|'created'|'changed'|'removed'|'rescan_required';path:string|null}[]}
|
|
260
|
+
export interface FilePreview {id:string;path:string;bytes:number;count:number;revision:string|null;purpose:string;record:string|null}
|
|
261
|
+
export interface FileHistoryPage {items:FileRecord[];next_cursor:string|null;total:number}
|
|
262
|
+
export const files = {
|
|
263
|
+
backupPreview:(root:string,record:string)=>capabilities.invoke<FileJob<FilePreview>>('files.backup_preview',{root,record}),
|
|
264
|
+
archiveBackup:(preview:string)=>capabilities.invoke<FileJob<FileRecord>>('files.archive_backup',{preview}),
|
|
265
|
+
forgetPreview:(root:string,record:string)=>capabilities.invoke<FileJob<FilePreview>>('files.forget_preview',{root,record}),
|
|
266
|
+
forgetRecord:(preview:string)=>capabilities.invoke<FileJob<{forgotten:string}>>('files.forget_record',{preview}),
|
|
267
|
+
historyPage:(root:string,cursor?:string,limit=50)=>capabilities.invoke<FileJob<FileHistoryPage>>('files.history_page',{root,...(cursor?{cursor}:{}),limit}),
|
|
268
|
+
trashPreview:(root:string,path:string)=>capabilities.invoke<FileJob<FilePreview>>('files.trash_preview',{root,path}),
|
|
269
|
+
discardPreview:(preview:string)=>capabilities.invoke<{discarded:boolean}>('files.discard_preview',{preview}),
|
|
270
|
+
trash:(preview:string)=>capabilities.invoke<FileJob<FileRecord>>('files.trash',{preview}),
|
|
271
|
+
/** Breadth-first listings of a whole tree in one call. Hidden and `skip`
|
|
272
|
+
* directories are listed by their parent but not entered. */
|
|
273
|
+
listTree:(root:string,path='',options:{depth?:number;skip?:string[];hidden?:boolean;limit?:number}={})=>capabilities.invoke<FileJob<{directories:{path:string;entries?:FileEntry[];error?:string}[];truncated:boolean}>>('files.list_tree',{root,path,...options}),
|
|
274
|
+
/** Full-access roots only: move entries to the Trash without a Host confirmation.
|
|
275
|
+
* `stamp` is what `files.measure` returned; a changed entry is refused, not moved. */
|
|
276
|
+
trashDirect:(items:{root:string;path:string;stamp:{revision:string;digest:string;bytes:number;count:number}}[])=>capabilities.invoke<FileJob<{path:string;record?:FileRecord;error?:string}[]>>('files.trash_direct',{items}),
|
|
277
|
+
watch:(root:string,path='',recursive=false)=>capabilities.invoke<FileWatch>('files.watch',{root,path,recursive}),
|
|
278
|
+
watches:()=>capabilities.invoke<FileWatch[]>('files.watches'),
|
|
279
|
+
events:(id:string,after=0)=>capabilities.invoke<FileWatchEvents>('files.events',{id,after}),
|
|
280
|
+
unwatch:(id:string)=>capabilities.invoke<{stopped:boolean}>('files.unwatch',{id}),
|
|
281
|
+
roots:()=>capabilities.invoke<FileJob<FileRoot[]>>('files.roots'),
|
|
282
|
+
list:(root:string,path='')=>capabilities.invoke<FileJob<FileEntry[]>>('files.list',{root,path}),
|
|
283
|
+
stat:(root:string,path='')=>capabilities.invoke<FileJob<FileEntry>>('files.stat',{root,path}),
|
|
284
|
+
readText:(root:string,path:string,revision?:string)=>capabilities.invoke<FileJob<{text:string;entry:FileEntry}>>('files.read_text',{root,path,...(revision?{revision}:{})}),
|
|
285
|
+
writeText:(root:string,path:string,text:string,revision:string)=>capabilities.invoke<FileJob<{record:FileRecord;entry:FileEntry|null}>>('files.write_text',{root,path,text,revision}),
|
|
286
|
+
mkdir:(root:string,path:string)=>capabilities.invoke<FileJob<FileEntry>>('files.mkdir',{root,path}),
|
|
287
|
+
move:(root:string,path:string,destination:string,revision:string)=>capabilities.invoke<FileJob<FileRecord>>('files.move',{root,path,destination,revision}),
|
|
288
|
+
history:(root:string)=>capabilities.invoke<FileJob<FileRecord[]>>('files.history',{root}),
|
|
289
|
+
restore:(root:string,record:string)=>capabilities.invoke<FileJob<FileRecord>>('files.restore',{root,record}),
|
|
290
|
+
state:<T=unknown>(id:string)=>operations.state<T>(id) as Promise<FileJob<T>>,
|
|
291
|
+
cancel:(id:string)=>operations.cancel(id),
|
|
292
|
+
release:(id:string)=>operations.release(id),
|
|
293
|
+
result:<T>(job:FileJob<T>):Promise<T>=>operations.wait<T>(job),
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/** Plugin-owned credentials. Values are returned only to this granted plugin;
|
|
297
|
+
* Agent/Medeo credentials are never part of this vault. No automatic retry. */
|
|
298
|
+
export interface SecretOperation { id:string; status:'running'|'completed'|'failed'; value?:string|null; error?:string }
|
|
299
|
+
async function secretOperation(method:'get'|'set'|'remove',args:Record<string,unknown>):Promise<string|null>{
|
|
300
|
+
const job=await capabilities.invoke<SecretOperation>('secrets.'+method,args);
|
|
301
|
+
const deadline=Date.now()+30000;
|
|
302
|
+
for(;;){
|
|
303
|
+
const change=nextChange(job.id,1000);
|
|
304
|
+
const result=await capabilities.invoke<SecretOperation>('secrets.result',{id:job.id});
|
|
305
|
+
if(result.status!=='running')change.off();
|
|
306
|
+
if(result.status==='completed')return result.value??null;
|
|
307
|
+
if(result.status==='failed')throw Error(result.error??'secrets_storage_failed');
|
|
308
|
+
if(Date.now()>=deadline){change.off();throw Error('secrets_outcome_unknown')}
|
|
309
|
+
await change.promise;change.off();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
export const secrets={
|
|
313
|
+
get:(key:string)=>secretOperation('get',{key}),
|
|
314
|
+
set:async(key:string,value:string)=>{await secretOperation('set',{key,value})},
|
|
315
|
+
remove:async(key:string)=>{await secretOperation('remove',{key})},
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
export interface LocalServerOptions { port?:number; routes:{method:'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'DELETE';path:string}[]; origins?:string[]; timeout_ms?:number }
|
|
319
|
+
export interface LocalServerState { id:string; status:'starting'|'running'|'stopping'|'stopped'|'failed'; origin:string|null; error:string|null; pending:number; accepted:number }
|
|
320
|
+
export interface LocalRequest { id:string; method:string; path:string; query:string; headers:Record<string,string>; body_base64:string }
|
|
321
|
+
/** A loopback server is instance-owned and never survives Host restart. Keep the
|
|
322
|
+
* start token in private memory and serve requests in a worker for background use. */
|
|
323
|
+
export const server={
|
|
324
|
+
start:(options:LocalServerOptions)=>capabilities.invoke<{id:string;status:'starting';access_token:string}>('server.start',{...options}),
|
|
325
|
+
state:(id:string)=>capabilities.invoke<LocalServerState>('server.state',{id}),
|
|
326
|
+
list:()=>capabilities.invoke<LocalServerState[]>('server.state'),
|
|
327
|
+
events:(id:string,limit=8)=>capabilities.invoke<{requests:LocalRequest[]}>('server.events',{id,limit}),
|
|
328
|
+
respond:(id:string,request:string,response:{status?:number;body_base64?:string;content_type?:string})=>capabilities.invoke<{responded:boolean}>('server.respond',{id,request,...response}),
|
|
329
|
+
stop:(id:string)=>capabilities.invoke<LocalServerState>('server.stop',{id}),
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
export interface PluginLocaleState {preference:string;locale:string;system_locale:string;direction:'ltr';supported_locales:string[];catalog_locales:string[];catalog_locale:string|null;fallback_locale:string|null;name:string;commands:Record<string,string>}
|
|
334
|
+
/** Text is formatted in Rust from the signed package. Render with textContent,
|
|
335
|
+
* never innerHTML. Register listeners before initial state fetch to avoid races. */
|
|
336
|
+
export const i18n={
|
|
337
|
+
state:()=>capabilities.invoke<PluginLocaleState>('i18n.state'),
|
|
338
|
+
setLocale:(preference:string)=>capabilities.invoke<PluginLocaleState>('i18n.setLocale',{preference}),
|
|
339
|
+
t:(key:string,params:Record<string,string|number>={})=>capabilities.invoke<string>('i18n.t',{key,params}),
|
|
340
|
+
/** Every message of the effective locale (default-locale fallback merged in). */
|
|
341
|
+
catalog:()=>capabilities.invoke<Record<string,string>>('i18n.catalog'),
|
|
342
|
+
onDidChangeLocale:(callback:(state:PluginLocaleState)=>void)=>globalThis.medeoPlugin.onLocaleChanged(callback),
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
/** Every asynchronous call returns an owned operation handle. Status changes
|
|
346
|
+
* are pushed; `wait` resolves on them and releases the result. */
|
|
347
|
+
export interface NativeOperation<T=unknown>{id:string;status:'running'|'completed'|'failed'|'cancelled'|'interrupted';result:T|null;error:string|null}
|
|
348
|
+
export const operations={
|
|
349
|
+
state:<T=unknown>(id:string)=>capabilities.invoke<NativeOperation<T>>('operations.state',{id}),
|
|
350
|
+
list:()=>capabilities.invoke<{id:string;method:string;status:string}[]>('operations.list'),
|
|
351
|
+
cancel:(id:string)=>capabilities.invoke('operations.cancel',{id}),
|
|
352
|
+
release:(id:string)=>capabilities.invoke('operations.release',{id}),
|
|
353
|
+
async wait<T>(operation:{id:string;status:string},signal?:AbortSignal):Promise<T>{
|
|
354
|
+
let value=operation as NativeOperation<T>;
|
|
355
|
+
while(value.status==='running'){
|
|
356
|
+
if(signal?.aborted){await operations.cancel(value.id);throw Error('cancelled')}
|
|
357
|
+
const change=nextChange(value.id,2000);
|
|
358
|
+
value=await operations.state<T>(value.id);
|
|
359
|
+
if(value.status==='running')await change.promise;
|
|
360
|
+
change.off();
|
|
361
|
+
}
|
|
362
|
+
// Quick reads may come back settled and already released by the Host.
|
|
363
|
+
if(!(value as {released?:boolean}).released)await operations.release(value.id);
|
|
364
|
+
if(value.status!=='completed')throw Error(value.error??value.status);
|
|
365
|
+
return value.result as T;
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
const nativeCall=<T=unknown>(method:string,args:Record<string,JsonValue>={})=>capabilities.invoke<NativeOperation<T>>(method,args);
|
|
369
|
+
/** A camera / microphone / system audio recording. `waveform` (240 peaks, 0…1) is in `state(id)` once
|
|
370
|
+
* completed; listings carry a 40-point `waveform_preview` instead. Live fields exist only while recording:
|
|
371
|
+
* `levels` holds the latest input levels (0…1, about 20 a second) and `levels_seq` counts every level so far;
|
|
372
|
+
* `frame` is the camera's latest preview as base64 JPEG. "completed" means `previewURL` can play it. */
|
|
373
|
+
export interface MediaRecord {id:string;kind:'camera'|'microphone'|'system_audio';status:'starting'|'recording'|'stopping'|'completed'|'failed'|'interrupted';error?:string|null;created_ms:number;extension:string;duration_ms?:number;bytes?:number;waveform?:number[];waveform_preview?:number[];elapsed_ms?:number;level?:number;peak?:number;levels?:number[];levels_seq?:number;frame?:string}
|
|
374
|
+
function mediaProvider(kind:'camera'|'microphone'|'system_audio'){return{
|
|
375
|
+
status:()=>nativeCall<{authorization:string}>(kind+'.status'),
|
|
376
|
+
start:(maxSeconds=300)=>nativeCall<{id:string;status:string}>(kind+'.start',{max_seconds:maxSeconds}),
|
|
377
|
+
stop:(id:string)=>nativeCall(kind+'.stop',{id}),
|
|
378
|
+
state:(id?:string)=>nativeCall(kind+'.state',id?{id}:{}),
|
|
379
|
+
read:(id:string,offset=0,length=32768)=>nativeCall<NetworkChunk>(kind+'.read',{id,offset,length}),
|
|
380
|
+
/** Same-origin URL for an `<audio>` / `<video>` element; plays once the record is "completed". */
|
|
381
|
+
previewURL:(record:Pick<MediaRecord,'id'|'extension'>)=>location.origin+'/_media/'+encodeURIComponent(record.id)+(record.extension==='m4a'?'.m4a':'.mp4'),
|
|
382
|
+
}}
|
|
383
|
+
export const camera=mediaProvider('camera'),microphone=mediaProvider('microphone'),systemAudio=mediaProvider('system_audio');
|
|
384
|
+
export const accessibility={status:()=>nativeCall('accessibility.status'),request:()=>nativeCall('accessibility.request'),windows:()=>nativeCall<{id:string;title:string;application:string}[]>('accessibility.windows'),focus:(id:string)=>nativeCall('accessibility.focus',{id}),selectedText:(id:string)=>nativeCall<{id:string;text:string}>('accessibility.selected_text',{id}),insertText:(focus:string,text:string)=>nativeCall('accessibility.insert_text',{id:focus,text})};
|
|
385
|
+
export const browserView={open:(id:string,url:string,width=1000,height=720)=>capabilities.invoke('browser.open',{id,url,width,height}),state:(id:string)=>capabilities.invoke('browser.state',{id}),close:(id:string)=>capabilities.invoke('browser.close',{id})};
|
|
386
|
+
export const printing={print:(text:string)=>capabilities.invoke('printing.print',{text})};
|
|
387
|
+
export const processes={start:(executable:string,args:string[]=[],timeoutMs=60000)=>nativeCall<{id:string;status:string}>('process.start',{executable,arguments:args,timeout_ms:timeoutMs}),state:(id:string)=>nativeCall<{status:string;exit_code:number|null;stdout:string;stderr:string;truncated:boolean}>('process.state',{id}),write:(id:string,text:string)=>nativeCall<{written:number}>('process.write',{id,text}),stop:(id:string)=>nativeCall('process.stop',{id})};
|
|
388
|
+
export interface BackgroundEvent{id:string;schedule:string;due_ms:number;payload:JsonValue}
|
|
389
|
+
export const background={schedule:(id:string,delayMs:number,payload:JsonValue=null,intervalMs=0)=>capabilities.invoke('background.schedule',{id,delay_ms:delayMs,interval_ms:intervalMs,payload}),list:()=>capabilities.invoke('background.list'),cancel:(id:string)=>capabilities.invoke('background.cancel',{id}),events:()=>capabilities.invoke<BackgroundEvent[]>('background.events')};
|
|
390
|
+
export const contacts={status:()=>nativeCall('contacts.status'),request:()=>nativeCall('contacts.request'),list:(query='',limit=50)=>nativeCall('contacts.list',{query,limit}),save:(contact:{given_name:string;family_name:string;email:string;phone:string})=>nativeCall<{id:string;created:boolean}>('contacts.save',contact)};
|
|
391
|
+
export const calendar={status:()=>nativeCall('calendar.status'),request:()=>nativeCall('calendar.request'),list:(startMs:number,endMs:number,limit=50)=>nativeCall('calendar.list',{start_ms:startMs,end_ms:endMs,limit}),save:(event:{title:string;notes:string;start_ms:number;end_ms:number})=>nativeCall<{id:string;created:boolean}>('calendar.save',event)};
|
|
392
|
+
export const deviceLocation={status:()=>nativeCall('location.status'),request:()=>nativeCall('location.request'),current:()=>nativeCall<{latitude:number;longitude:number;accuracy_m:number;timestamp_ms:number}>('location.current')};
|
|
393
|
+
export const devices={choose:(transport:'serial'|'hid'|'ble')=>nativeCall('devices.choose',{transport}),open:(id:string,baudRate=115200)=>nativeCall('devices.open',{id,baud_rate:baudRate}),list:()=>nativeCall('devices.list'),read:(id:string,length=4096)=>nativeCall<{data_base64:string;bytes:number}>('devices.read',{id,length}),write:(id:string,dataBase64:string)=>nativeCall<{written:number}>('devices.write',{id,data_base64:dataBase64}),close:(id:string)=>nativeCall('devices.close',{id})};
|
package/src/registry.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Generated by platform-core from the capability registry; do not edit.
|
|
2
|
+
export const METHODS = {
|
|
3
|
+
"capabilities.list": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
4
|
+
"capabilities.labels": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
5
|
+
"providers.list": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
6
|
+
"permissions.request": { permission: null, provider: null, ui: true, confirm: true, adapter: "host" },
|
|
7
|
+
"i18n.state": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
8
|
+
"i18n.setLocale": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
9
|
+
"i18n.t": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
10
|
+
"i18n.catalog": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
11
|
+
"operations.state": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
12
|
+
"operations.list": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
13
|
+
"operations.cancel": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
14
|
+
"operations.release": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
15
|
+
"config.get": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
16
|
+
"config.set": { permission: null, provider: null, ui: false, confirm: false, adapter: "host" },
|
|
17
|
+
"storage.get": { permission: "storage", provider: "medeo.storage", ui: false, confirm: false, adapter: "host" },
|
|
18
|
+
"storage.set": { permission: "storage", provider: "medeo.storage", ui: false, confirm: false, adapter: "host" },
|
|
19
|
+
"storage.remove": { permission: "storage", provider: "medeo.storage", ui: false, confirm: false, adapter: "host" },
|
|
20
|
+
"creation.open": { permission: "creation_open", provider: "medeo.creation", ui: false, confirm: false, adapter: "host" },
|
|
21
|
+
"resources.choose_directories": { permission: "file_access", provider: "medeo.workspace", ui: true, confirm: false, adapter: "host" },
|
|
22
|
+
"resources.request_directory": { permission: "file_access", provider: "medeo.workspace", ui: true, confirm: true, adapter: "host" },
|
|
23
|
+
"resources.list": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
24
|
+
"resources.revoke": { permission: "file_access", provider: "medeo.workspace", ui: true, confirm: false, adapter: "host" },
|
|
25
|
+
"files.roots": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
26
|
+
"files.mkdir": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
27
|
+
"files.history": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
28
|
+
"files.history_page": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
29
|
+
"files.backup_preview": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
30
|
+
"files.archive_backup": { permission: "file_access", provider: "medeo.workspace", ui: true, confirm: true, adapter: "host" },
|
|
31
|
+
"files.forget_preview": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
32
|
+
"files.forget_record": { permission: "file_access", provider: "medeo.workspace", ui: true, confirm: true, adapter: "host" },
|
|
33
|
+
"files.restore": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
34
|
+
"files.list": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
35
|
+
"files.stat": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
36
|
+
"files.read_text": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
37
|
+
"files.write_text": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
38
|
+
"files.move": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
39
|
+
"files.trash": { permission: "file_access", provider: "medeo.workspace", ui: true, confirm: true, adapter: "host" },
|
|
40
|
+
"files.trash_preview": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
41
|
+
"files.discard_preview": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
42
|
+
"files.watch": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
43
|
+
"files.events": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
44
|
+
"files.watches": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
45
|
+
"files.unwatch": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
46
|
+
"files.read_link": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
47
|
+
"files.measure": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
48
|
+
"files.list_tree": { permission: "file_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
49
|
+
"files.trash_direct": { permission: "file_full_access", provider: "medeo.workspace", ui: false, confirm: false, adapter: "host" },
|
|
50
|
+
"network.request": { permission: "network", provider: "medeo.network", ui: false, confirm: false, adapter: "host" },
|
|
51
|
+
"network.read": { permission: "network", provider: "medeo.network", ui: false, confirm: false, adapter: "host" },
|
|
52
|
+
"network.origins": { permission: "network", provider: "medeo.network", ui: false, confirm: false, adapter: "host" },
|
|
53
|
+
"network.request_origin": { permission: "network", provider: "medeo.network", ui: true, confirm: true, adapter: "host" },
|
|
54
|
+
"network.revoke_origin": { permission: "network", provider: "medeo.network", ui: true, confirm: false, adapter: "host" },
|
|
55
|
+
"agent.models": { permission: "agent_api", provider: "medeo.agent", ui: false, confirm: false, adapter: "host" },
|
|
56
|
+
"agent.start": { permission: "agent_api", provider: "medeo.agent", ui: false, confirm: false, adapter: "host" },
|
|
57
|
+
"clipboard.read": { permission: "clipboard_read", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
58
|
+
"clipboard.write": { permission: "clipboard_write", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
59
|
+
"capture.status": { permission: "screen_capture", provider: "medeo.capture", ui: false, confirm: false, adapter: "host" },
|
|
60
|
+
"capture.sources": { permission: "screen_capture", provider: "medeo.capture", ui: true, confirm: false, adapter: "host" },
|
|
61
|
+
"capture.start": { permission: "screen_capture", provider: "medeo.capture", ui: true, confirm: true, adapter: "host" },
|
|
62
|
+
"capture.state": { permission: "screen_capture", provider: "medeo.capture", ui: false, confirm: false, adapter: "host" },
|
|
63
|
+
"capture.stop": { permission: "screen_capture", provider: "medeo.capture", ui: false, confirm: false, adapter: "host" },
|
|
64
|
+
"capture.cancel": { permission: "screen_capture", provider: "medeo.capture", ui: false, confirm: false, adapter: "host" },
|
|
65
|
+
"capture.open": { permission: "screen_capture", provider: "medeo.capture", ui: true, confirm: false, adapter: "electron" },
|
|
66
|
+
"capture.recover": { permission: "screen_capture", provider: "medeo.capture", ui: true, confirm: false, adapter: "host" },
|
|
67
|
+
"camera.status": { permission: "camera", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
68
|
+
"camera.start": { permission: "camera", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
69
|
+
"camera.stop": { permission: "camera", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
70
|
+
"camera.state": { permission: "camera", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
71
|
+
"camera.read": { permission: "camera", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
72
|
+
"microphone.status": { permission: "microphone", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
73
|
+
"microphone.start": { permission: "microphone", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
74
|
+
"microphone.stop": { permission: "microphone", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
75
|
+
"microphone.state": { permission: "microphone", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
76
|
+
"microphone.read": { permission: "microphone", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
77
|
+
"system_audio.status": { permission: "system_audio", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
78
|
+
"system_audio.start": { permission: "system_audio", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
79
|
+
"system_audio.stop": { permission: "system_audio", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
80
|
+
"system_audio.state": { permission: "system_audio", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
81
|
+
"system_audio.read": { permission: "system_audio", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
82
|
+
"applications.list": { permission: "applications", provider: "medeo.applications", ui: false, confirm: false, adapter: "host" },
|
|
83
|
+
"applications.launch": { permission: "applications", provider: "medeo.applications", ui: false, confirm: false, adapter: "host" },
|
|
84
|
+
"applications.state": { permission: "applications", provider: "medeo.applications", ui: false, confirm: false, adapter: "host" },
|
|
85
|
+
"shortcuts.register": { permission: "global_shortcuts", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
86
|
+
"shortcuts.unregister": { permission: "global_shortcuts", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
87
|
+
"shortcuts.events": { permission: "global_shortcuts", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
88
|
+
"shortcuts.list": { permission: "global_shortcuts", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
89
|
+
"notifications.show": { permission: "notifications", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
90
|
+
"notifications.close": { permission: "notifications", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
91
|
+
"tray.set": { permission: "tray", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
92
|
+
"tray.remove": { permission: "tray", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
93
|
+
"tray.events": { permission: "tray", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
94
|
+
"windows.open": { permission: "app_windows", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
95
|
+
"windows.close": { permission: "app_windows", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
96
|
+
"windows.focus": { permission: "app_windows", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
97
|
+
"windows.hide": { permission: "app_windows", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
98
|
+
"windows.list": { permission: "app_windows", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
99
|
+
"accessibility.status": { permission: "accessibility", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
100
|
+
"accessibility.request": { permission: "accessibility", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
101
|
+
"accessibility.windows": { permission: "accessibility", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
102
|
+
"accessibility.focus": { permission: "accessibility", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
103
|
+
"accessibility.selected_text": { permission: "accessibility", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
104
|
+
"accessibility.insert_text": { permission: "accessibility", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
105
|
+
"input_method.status": { permission: "input_method", provider: "medeo.input-method", ui: false, confirm: false, adapter: "host" },
|
|
106
|
+
"input_method.configure": { permission: "input_method", provider: "medeo.input-method", ui: false, confirm: false, adapter: "host" },
|
|
107
|
+
"input_method.enable": { permission: "input_method", provider: "medeo.input-method", ui: true, confirm: false, adapter: "host" },
|
|
108
|
+
"input_method.disable": { permission: "input_method", provider: "medeo.input-method", ui: false, confirm: false, adapter: "host" },
|
|
109
|
+
"input_method.events": { permission: "input_method", provider: "medeo.input-method", ui: false, confirm: false, adapter: "host" },
|
|
110
|
+
"input_method.respond": { permission: "input_method", provider: "medeo.input-method", ui: false, confirm: false, adapter: "host" },
|
|
111
|
+
"input_method.system": { permission: "input_method", provider: "medeo.input-method", ui: false, confirm: false, adapter: "host" },
|
|
112
|
+
"input_method.setup": { permission: "input_method", provider: "medeo.input-method", ui: true, confirm: true, adapter: "host" },
|
|
113
|
+
"input_method.remove": { permission: "input_method", provider: "medeo.input-method", ui: true, confirm: true, adapter: "host" },
|
|
114
|
+
"input_method.settings": { permission: "input_method", provider: "medeo.input-method", ui: true, confirm: false, adapter: "host" },
|
|
115
|
+
"external.open": { permission: "external_open", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
116
|
+
"browser.open": { permission: "browser_view", provider: "medeo.desktop", ui: true, confirm: false, adapter: "electron" },
|
|
117
|
+
"browser.close": { permission: "browser_view", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
118
|
+
"browser.state": { permission: "browser_view", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
119
|
+
"system.info": { permission: "system_info", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
120
|
+
"system.running": { permission: "system_info", provider: "medeo.desktop", ui: false, confirm: false, adapter: "host" },
|
|
121
|
+
"secrets.get": { permission: "secrets", provider: "medeo.secrets", ui: false, confirm: false, adapter: "host" },
|
|
122
|
+
"secrets.set": { permission: "secrets", provider: "medeo.secrets", ui: false, confirm: false, adapter: "host" },
|
|
123
|
+
"secrets.remove": { permission: "secrets", provider: "medeo.secrets", ui: false, confirm: false, adapter: "host" },
|
|
124
|
+
"secrets.result": { permission: "secrets", provider: "medeo.secrets", ui: false, confirm: false, adapter: "host" },
|
|
125
|
+
"background.schedule": { permission: "background_tasks", provider: "medeo.background", ui: false, confirm: false, adapter: "host" },
|
|
126
|
+
"background.list": { permission: "background_tasks", provider: "medeo.background", ui: false, confirm: false, adapter: "host" },
|
|
127
|
+
"background.cancel": { permission: "background_tasks", provider: "medeo.background", ui: false, confirm: false, adapter: "host" },
|
|
128
|
+
"background.events": { permission: "background_tasks", provider: "medeo.background", ui: false, confirm: false, adapter: "host" },
|
|
129
|
+
"power.start": { permission: "power", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
130
|
+
"power.stop": { permission: "power", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
131
|
+
"power.state": { permission: "power", provider: "medeo.desktop", ui: false, confirm: false, adapter: "electron" },
|
|
132
|
+
"process.start": { permission: "process_spawn", provider: "medeo.process", ui: false, confirm: false, adapter: "host" },
|
|
133
|
+
"process.state": { permission: "process_spawn", provider: "medeo.process", ui: false, confirm: false, adapter: "host" },
|
|
134
|
+
"process.write": { permission: "process_spawn", provider: "medeo.process", ui: false, confirm: false, adapter: "host" },
|
|
135
|
+
"process.stop": { permission: "process_spawn", provider: "medeo.process", ui: false, confirm: false, adapter: "host" },
|
|
136
|
+
"system.trash": { permission: "node", provider: "medeo.node", ui: false, confirm: false, adapter: "electron" },
|
|
137
|
+
"approvals.request": { permission: "approvals", provider: "medeo.approvals", ui: true, confirm: true, adapter: "host" },
|
|
138
|
+
"approvals.rules": { permission: "approvals", provider: "medeo.approvals", ui: false, confirm: false, adapter: "host" },
|
|
139
|
+
"approvals.forget": { permission: "approvals", provider: "medeo.approvals", ui: false, confirm: false, adapter: "host" },
|
|
140
|
+
"server.start": { permission: "local_server", provider: "medeo.local-server", ui: false, confirm: false, adapter: "host" },
|
|
141
|
+
"server.state": { permission: "local_server", provider: "medeo.local-server", ui: false, confirm: false, adapter: "host" },
|
|
142
|
+
"server.stop": { permission: "local_server", provider: "medeo.local-server", ui: false, confirm: false, adapter: "host" },
|
|
143
|
+
"server.events": { permission: "local_server", provider: "medeo.local-server", ui: false, confirm: false, adapter: "host" },
|
|
144
|
+
"server.respond": { permission: "local_server", provider: "medeo.local-server", ui: false, confirm: false, adapter: "host" },
|
|
145
|
+
"printing.print": { permission: "printing", provider: "medeo.desktop", ui: true, confirm: false, adapter: "electron" },
|
|
146
|
+
"contacts.status": { permission: "contacts", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
147
|
+
"contacts.request": { permission: "contacts", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
148
|
+
"contacts.list": { permission: "contacts", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
149
|
+
"contacts.save": { permission: "contacts", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
150
|
+
"calendar.status": { permission: "calendar", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
151
|
+
"calendar.request": { permission: "calendar", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
152
|
+
"calendar.list": { permission: "calendar", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
153
|
+
"calendar.save": { permission: "calendar", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
154
|
+
"location.status": { permission: "location", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
155
|
+
"location.request": { permission: "location", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
156
|
+
"location.current": { permission: "location", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
157
|
+
"devices.choose": { permission: "device_access", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
158
|
+
"devices.open": { permission: "device_access", provider: "medeo.system-services", ui: true, confirm: false, adapter: "host" },
|
|
159
|
+
"devices.read": { permission: "device_access", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
160
|
+
"devices.write": { permission: "device_access", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
161
|
+
"devices.close": { permission: "device_access", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
162
|
+
"devices.list": { permission: "device_access", provider: "medeo.system-services", ui: false, confirm: false, adapter: "host" },
|
|
163
|
+
} as const;
|
|
164
|
+
export type MethodName = keyof typeof METHODS;
|
|
165
|
+
export const LIMITS = {
|
|
166
|
+
notifications: 16,
|
|
167
|
+
power: 8,
|
|
168
|
+
shortcuts: 16,
|
|
169
|
+
windows: 8,
|
|
170
|
+
browser_windows: 4,
|
|
171
|
+
media_streams: 4,
|
|
172
|
+
queued_events: 64,
|
|
173
|
+
} as const;
|