@mearl/client 2.20.5 → 2.21.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 +122 -2
- package/dist/cli.js +10 -5
- package/dist/commands.d.ts +14 -5
- package/dist/commands.js +21 -2
- package/dist/generated-app-profile-definition.js +20 -10
- package/dist/generated-app-profile-runtime-types.d.ts +4 -0
- package/dist/generated-browser-action-protocol.d.ts +11 -1
- package/dist/generated-browser-action-protocol.js +3 -0
- package/dist/generated-plugin-diagnostics.d.ts +110 -0
- package/dist/generated-plugin-diagnostics.js +1 -0
- package/dist/generated-plugin-execution.d.ts +27 -0
- package/dist/generated-plugin-execution.js +1 -0
- package/dist/generated-plugin-models.d.ts +64 -0
- package/dist/generated-plugin-models.js +1 -0
- package/dist/generated-plugin-pages.d.ts +76 -0
- package/dist/generated-plugin-pages.js +59 -0
- package/dist/generated-plugin-recovery.d.ts +32 -0
- package/dist/generated-plugin-recovery.js +1 -0
- package/dist/generated-plugin-state.d.ts +50 -0
- package/dist/generated-plugin-state.js +1 -0
- package/dist/generated-plugin-tasks.d.ts +74 -0
- package/dist/generated-plugin-tasks.js +7 -0
- package/dist/generated-toolbox-icon.d.ts +10 -0
- package/dist/generated-toolbox-icon.js +37 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +6 -0
- package/dist/plugin-task-host.d.ts +1 -0
- package/dist/plugin-task-host.js +14 -0
- package/dist/plugin-worker.d.ts +1 -0
- package/dist/plugin-worker.js +17 -0
- package/dist/plugin.d.ts +57 -4
- package/dist/plugin.js +296 -15
- package/dist/pluginCliOutput.d.ts +2 -0
- package/dist/pluginCliOutput.js +7 -0
- package/dist/pluginCommandWorker.d.ts +2 -0
- package/dist/pluginCommandWorker.js +174 -0
- package/dist/pluginDiagnostics.d.ts +26 -0
- package/dist/pluginDiagnostics.js +309 -0
- package/dist/pluginExecution.d.ts +21 -0
- package/dist/pluginExecution.js +43 -0
- package/dist/pluginExecutor.d.ts +29 -0
- package/dist/pluginExecutor.js +223 -0
- package/dist/pluginExecutorProtocol.d.ts +55 -0
- package/dist/pluginExecutorProtocol.js +47 -0
- package/dist/pluginExecutorSupervisor.d.ts +4 -0
- package/dist/pluginExecutorSupervisor.js +63 -0
- package/dist/pluginHost.d.ts +20 -0
- package/dist/pluginHost.js +53 -0
- package/dist/pluginHostConnection.d.ts +35 -0
- package/dist/pluginHostConnection.js +257 -0
- package/dist/pluginHostFiles.d.ts +1 -0
- package/dist/pluginHostFiles.js +21 -0
- package/dist/pluginHostPaths.d.ts +11 -0
- package/dist/pluginHostPaths.js +22 -0
- package/dist/pluginHostServer.d.ts +7 -0
- package/dist/pluginHostServer.js +252 -0
- package/dist/pluginModelCatalog.d.ts +14 -0
- package/dist/pluginModelCatalog.js +51 -0
- package/dist/pluginModelDefinition.d.ts +6 -0
- package/dist/pluginModelDefinition.js +75 -0
- package/dist/pluginModelSessionWorker.d.ts +23 -0
- package/dist/pluginModelSessionWorker.js +60 -0
- package/dist/pluginModelSessions.d.ts +16 -0
- package/dist/pluginModelSessions.js +234 -0
- package/dist/pluginModels.d.ts +17 -0
- package/dist/pluginModels.js +47 -0
- package/dist/pluginPageBundle.js +74 -17
- package/dist/pluginPageDefinition.d.ts +3 -0
- package/dist/pluginPageDefinition.js +62 -0
- package/dist/pluginPageManager.d.ts +57 -0
- package/dist/pluginPageManager.js +877 -0
- package/dist/pluginPages.d.ts +21 -0
- package/dist/pluginPages.js +46 -0
- package/dist/pluginProcessTree.d.ts +2 -0
- package/dist/pluginProcessTree.js +31 -0
- package/dist/pluginRecoveryDefinition.d.ts +3 -0
- package/dist/pluginRecoveryDefinition.js +56 -0
- package/dist/pluginRegistry.d.ts +2 -3
- package/dist/pluginRegistry.js +14 -13
- package/dist/pluginRevision.d.ts +14 -0
- package/dist/pluginRevision.js +227 -0
- package/dist/pluginRuntimeCleanup.d.ts +2 -0
- package/dist/pluginRuntimeCleanup.js +55 -0
- package/dist/pluginState.d.ts +26 -0
- package/dist/pluginState.js +28 -0
- package/dist/pluginStateDefinition.d.ts +4 -0
- package/dist/pluginStateDefinition.js +68 -0
- package/dist/pluginStateManager.d.ts +24 -0
- package/dist/pluginStateManager.js +132 -0
- package/dist/pluginStateStore.d.ts +57 -0
- package/dist/pluginStateStore.js +396 -0
- package/dist/pluginTaskManager.d.ts +92 -0
- package/dist/pluginTaskManager.js +1080 -0
- package/dist/pluginTaskProtocol.d.ts +47 -0
- package/dist/pluginTaskProtocol.js +1 -0
- package/dist/pluginTaskStore.d.ts +53 -0
- package/dist/pluginTaskStore.js +319 -0
- package/dist/pluginTaskWire.d.ts +4 -0
- package/dist/pluginTaskWire.js +42 -0
- package/dist/pluginTasks.d.ts +51 -0
- package/dist/pluginTasks.js +181 -0
- package/dist/pythonPlugin.d.ts +13 -2
- package/dist/pythonPlugin.js +235 -30
- package/dist/socket.js +5 -2
- package/dist/unified.d.ts +1 -0
- package/dist/unified.js +81 -0
- package/package.json +7 -3
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type PluginModelMode = 'generate' | 'agent';
|
|
2
|
+
export interface PluginModelRequest {
|
|
3
|
+
provider: string;
|
|
4
|
+
mode: PluginModelMode;
|
|
5
|
+
prompt: string;
|
|
6
|
+
instructions?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
reasoningEffort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
9
|
+
outputSchema?: Record<string, unknown>;
|
|
10
|
+
/** Opt-in conversation scoped to the bound document or calling command execution. */
|
|
11
|
+
conversation?: string;
|
|
12
|
+
/** Required for an agent task; never inferred from a pure-generation request. */
|
|
13
|
+
permissions?: 'read-only';
|
|
14
|
+
}
|
|
15
|
+
export interface PluginModelCapability {
|
|
16
|
+
provider: string;
|
|
17
|
+
modes: PluginModelMode[];
|
|
18
|
+
permissions: Array<'read-only'>;
|
|
19
|
+
structuredOutput: boolean;
|
|
20
|
+
streaming: boolean;
|
|
21
|
+
cancellation: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface PluginModelOption {
|
|
24
|
+
id: string;
|
|
25
|
+
displayName: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
isDefault?: boolean;
|
|
28
|
+
reasoningEfforts?: NonNullable<PluginModelRequest['reasoningEffort']>[];
|
|
29
|
+
defaultReasoningEffort?: PluginModelRequest['reasoningEffort'];
|
|
30
|
+
}
|
|
31
|
+
export interface PluginModelList {
|
|
32
|
+
provider: string;
|
|
33
|
+
models: PluginModelOption[];
|
|
34
|
+
}
|
|
35
|
+
export interface PluginModelResult {
|
|
36
|
+
text: string;
|
|
37
|
+
output?: unknown;
|
|
38
|
+
provider: string;
|
|
39
|
+
mode: PluginModelMode;
|
|
40
|
+
model?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Execution observations contain no prompts, account identities or credential values. */
|
|
43
|
+
export interface PluginModelDiagnostic {
|
|
44
|
+
requestedModel?: string;
|
|
45
|
+
selectedModel?: string;
|
|
46
|
+
activeModel?: string;
|
|
47
|
+
runtime?: {
|
|
48
|
+
executable?: string;
|
|
49
|
+
version?: string;
|
|
50
|
+
selection: 'explicit' | 'automatic';
|
|
51
|
+
started?: boolean;
|
|
52
|
+
};
|
|
53
|
+
configuration?: {
|
|
54
|
+
source: 'default' | 'environment';
|
|
55
|
+
home?: string;
|
|
56
|
+
filePresent: boolean;
|
|
57
|
+
baseProvider?: string;
|
|
58
|
+
credentialStore?: 'file' | 'keyring' | 'auto' | 'ephemeral' | 'unknown';
|
|
59
|
+
};
|
|
60
|
+
authentication?: 'apikey' | 'chatgpt' | 'chatgptAuthTokens' | 'unknown';
|
|
61
|
+
threadRestrictionsAccepted?: boolean;
|
|
62
|
+
turnRestrictionsAccepted?: boolean;
|
|
63
|
+
retryCount?: number;
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { PluginExecutionError, PluginExecutionHost } from './generated-plugin-execution.js';
|
|
2
|
+
export declare const PLUGIN_PAGE_LEASE_MS = 30000;
|
|
3
|
+
/** Document or access-scope invalidation can cross transports that preserve only a message. */
|
|
4
|
+
export declare function isPluginPageInvalidation(error: unknown): boolean;
|
|
5
|
+
export declare function isPluginPageUnavailable(error: unknown): boolean;
|
|
6
|
+
export declare function pluginPageUnavailable(error: unknown): Error;
|
|
7
|
+
/** main/business selectors, Chrome numeric frame IDs, or CDP opaque frame IDs. */
|
|
8
|
+
export type PluginPageFrame = string | number;
|
|
9
|
+
export type PluginPageOperation = 'attach' | 'get' | 'list' | 'send' | 'detach' | 'events' | 'activation';
|
|
10
|
+
export interface PluginPageEventBinding {
|
|
11
|
+
command: string;
|
|
12
|
+
schema: Record<string, unknown>;
|
|
13
|
+
policy?: 'serial' | 'latest' | 'parallel';
|
|
14
|
+
concurrency?: number;
|
|
15
|
+
maxPending?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface PluginPageRuntime {
|
|
18
|
+
version: 1;
|
|
19
|
+
matches: string[];
|
|
20
|
+
/** Self-contained function expression receiving {input, signal, emit, identity}. */
|
|
21
|
+
code: string;
|
|
22
|
+
initialize?: string;
|
|
23
|
+
events?: Record<string, PluginPageEventBinding>;
|
|
24
|
+
}
|
|
25
|
+
export interface PluginPageTarget {
|
|
26
|
+
browserSessionId: string;
|
|
27
|
+
tabId: number;
|
|
28
|
+
frameId: string | number;
|
|
29
|
+
documentId: string;
|
|
30
|
+
url: string;
|
|
31
|
+
}
|
|
32
|
+
export interface PluginPageInstance {
|
|
33
|
+
instanceId: string;
|
|
34
|
+
plugin: string;
|
|
35
|
+
installationId: string;
|
|
36
|
+
revision: string;
|
|
37
|
+
host: PluginExecutionHost;
|
|
38
|
+
target: PluginPageTarget;
|
|
39
|
+
state: 'active' | 'detached' | 'invalidated';
|
|
40
|
+
sequence: number;
|
|
41
|
+
createdAt: number;
|
|
42
|
+
error?: PluginExecutionError;
|
|
43
|
+
}
|
|
44
|
+
export interface PluginPageEvent {
|
|
45
|
+
sequence: number;
|
|
46
|
+
time: number;
|
|
47
|
+
type: 'received' | 'running' | 'success' | 'error' | 'superseded' | 'navigation' | 'invalidated';
|
|
48
|
+
eventSequence?: number;
|
|
49
|
+
name?: string;
|
|
50
|
+
payload?: unknown;
|
|
51
|
+
taskId?: string;
|
|
52
|
+
error?: PluginExecutionError;
|
|
53
|
+
}
|
|
54
|
+
export interface PluginPageEvents {
|
|
55
|
+
instance: PluginPageInstance;
|
|
56
|
+
events: PluginPageEvent[];
|
|
57
|
+
nextCursor: number;
|
|
58
|
+
firstAvailableSequence: number;
|
|
59
|
+
gap: boolean;
|
|
60
|
+
}
|
|
61
|
+
export interface PluginPageActivation {
|
|
62
|
+
plugin: string;
|
|
63
|
+
installationId: string;
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
matches: string[];
|
|
66
|
+
persistence: 'session' | 'persistent';
|
|
67
|
+
frame: PluginPageFrame;
|
|
68
|
+
input: Record<string, unknown>;
|
|
69
|
+
}
|
|
70
|
+
export interface PluginPageBinding {
|
|
71
|
+
instanceId: string;
|
|
72
|
+
target: PluginPageTarget;
|
|
73
|
+
}
|
|
74
|
+
export declare function isPluginPageMatchPattern(value: unknown): value is string;
|
|
75
|
+
export declare function matchesPluginPageURL(matches: readonly string[], value: string): boolean;
|
|
76
|
+
export declare function isPluginPageInstanceId(value: unknown): value is string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export const PLUGIN_PAGE_LEASE_MS = 30000;
|
|
2
|
+
/** Document or access-scope invalidation can cross transports that preserve only a message. */
|
|
3
|
+
export function isPluginPageInvalidation(error) {
|
|
4
|
+
const value = error;
|
|
5
|
+
const codes = [
|
|
6
|
+
'PLUGIN_PAGE_INVALIDATED',
|
|
7
|
+
'PLUGIN_PAGE_NOT_FOUND',
|
|
8
|
+
'PLUGIN_PAGE_TARGET_CHANGED',
|
|
9
|
+
'DOMAIN_PERMISSION_REQUIRED',
|
|
10
|
+
];
|
|
11
|
+
const message = typeof value?.message === 'string' ? value.message : '';
|
|
12
|
+
return codes.includes(String(value?.code)) || codes.some(code => message.startsWith(`${code}:`));
|
|
13
|
+
}
|
|
14
|
+
export function isPluginPageUnavailable(error) {
|
|
15
|
+
return error?.code === 'PLUGIN_PAGE_UNAVAILABLE';
|
|
16
|
+
}
|
|
17
|
+
export function pluginPageUnavailable(error) {
|
|
18
|
+
return Object.assign(new Error('Plugin page host is temporarily unavailable', { cause: error }), {
|
|
19
|
+
code: 'PLUGIN_PAGE_UNAVAILABLE',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const pattern = /^(https?|\*):\/\/(\*|\*\.[a-z0-9.-]+|[a-z0-9.-]+|localhost)(:\d+)?(\/[^#]*)$/i;
|
|
23
|
+
export function isPluginPageMatchPattern(value) {
|
|
24
|
+
return typeof value === 'string' && value.length <= 2048 && pattern.test(value);
|
|
25
|
+
}
|
|
26
|
+
export function matchesPluginPageURL(matches, value) {
|
|
27
|
+
let url;
|
|
28
|
+
try {
|
|
29
|
+
url = new URL(value);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (!['http:', 'https:'].includes(url.protocol))
|
|
35
|
+
return false;
|
|
36
|
+
return matches.some(item => {
|
|
37
|
+
const match = item.match(pattern);
|
|
38
|
+
if (!match || (match[1] !== '*' && match[1].toLowerCase() + ':' !== url.protocol))
|
|
39
|
+
return false;
|
|
40
|
+
const host = match[2].toLowerCase();
|
|
41
|
+
if (host !== '*' &&
|
|
42
|
+
host !== url.hostname &&
|
|
43
|
+
!(host.startsWith('*.') &&
|
|
44
|
+
(url.hostname === host.slice(2) || url.hostname.endsWith(host.slice(1)))))
|
|
45
|
+
return false;
|
|
46
|
+
if (match[3] && match[3].slice(1) !== (url.port || (url.protocol === 'https:' ? '443' : '80')))
|
|
47
|
+
return false;
|
|
48
|
+
const expression = '^' +
|
|
49
|
+
match[4]
|
|
50
|
+
.split('*')
|
|
51
|
+
.map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
52
|
+
.join('.*') +
|
|
53
|
+
'$';
|
|
54
|
+
return new RegExp(expression).test(url.pathname + url.search);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export function isPluginPageInstanceId(value) {
|
|
58
|
+
return typeof value === 'string' && /^pi_[0-9a-f-]{36}$/i.test(value);
|
|
59
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface PluginTaskRecoveryDeclaration {
|
|
2
|
+
version: 1;
|
|
3
|
+
commands: Record<string, {
|
|
4
|
+
checkpointVersion: number;
|
|
5
|
+
schema: Record<string, unknown>;
|
|
6
|
+
migrateFrom?: Array<{
|
|
7
|
+
version: number;
|
|
8
|
+
schema: Record<string, unknown>;
|
|
9
|
+
}>;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export interface PluginTaskCheckpointReference {
|
|
13
|
+
sequence: number;
|
|
14
|
+
version: number;
|
|
15
|
+
schemaHash: string;
|
|
16
|
+
updatedAt: number;
|
|
17
|
+
}
|
|
18
|
+
export interface PluginTaskCheckpoint extends PluginTaskCheckpointReference {
|
|
19
|
+
data: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface PluginTaskRecoveryContext {
|
|
22
|
+
fromTaskId: string;
|
|
23
|
+
fromRevision: string;
|
|
24
|
+
declarationHash: string;
|
|
25
|
+
sourceCheckpoint: PluginTaskCheckpointReference;
|
|
26
|
+
checkpoint: PluginTaskCheckpoint;
|
|
27
|
+
}
|
|
28
|
+
export interface PluginCheckpointMigrationInput {
|
|
29
|
+
checkpoint: PluginTaskCheckpoint;
|
|
30
|
+
fromRevision: string;
|
|
31
|
+
toRevision: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type PluginStateScope = 'installation' | 'host' | 'browser-session' | 'instance';
|
|
2
|
+
export interface PluginStateCollection {
|
|
3
|
+
scope: PluginStateScope;
|
|
4
|
+
storage: 'persistent' | 'cache' | 'memory';
|
|
5
|
+
schemaVersion: number;
|
|
6
|
+
schema: Record<string, unknown>;
|
|
7
|
+
maxEntries?: number;
|
|
8
|
+
maxBytes?: number;
|
|
9
|
+
ttlMs?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface PluginStateDeclaration {
|
|
12
|
+
version: 1;
|
|
13
|
+
collections: Record<string, PluginStateCollection>;
|
|
14
|
+
}
|
|
15
|
+
export interface PluginStateEntry {
|
|
16
|
+
key: string;
|
|
17
|
+
exists: boolean;
|
|
18
|
+
/** Live entry revision, or the collection revision for absence; opaque to callers. */
|
|
19
|
+
version: string;
|
|
20
|
+
value?: unknown;
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface PluginStateSnapshot extends PluginStateEntry {
|
|
24
|
+
revision: number;
|
|
25
|
+
schemaVersion: number;
|
|
26
|
+
}
|
|
27
|
+
export interface PluginStateList {
|
|
28
|
+
entries: PluginStateEntry[];
|
|
29
|
+
revision: number;
|
|
30
|
+
schemaVersion: number;
|
|
31
|
+
nextCursor?: string;
|
|
32
|
+
}
|
|
33
|
+
export type PluginStateMutation = {
|
|
34
|
+
type: 'put';
|
|
35
|
+
key: string;
|
|
36
|
+
expectedVersion: string;
|
|
37
|
+
value: unknown;
|
|
38
|
+
ttlMs?: number;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'delete';
|
|
41
|
+
key: string;
|
|
42
|
+
expectedVersion: string;
|
|
43
|
+
};
|
|
44
|
+
export interface PluginStateTransaction {
|
|
45
|
+
operations: PluginStateMutation[];
|
|
46
|
+
expectedRevision?: number;
|
|
47
|
+
migrateFromVersion?: number;
|
|
48
|
+
idempotencyKey?: string;
|
|
49
|
+
}
|
|
50
|
+
export type PluginStateOperation = 'get' | 'get-many' | 'list' | 'transact';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { PluginExecutionError, PluginExecutionHost, PluginInvocationSource } from './generated-plugin-execution.js';
|
|
2
|
+
import type { PluginTaskCheckpointReference } from './generated-plugin-recovery.js';
|
|
3
|
+
export declare const PLUGIN_TASK_PROTOCOL_VERSION = 5;
|
|
4
|
+
export type PluginTaskState = 'queued' | 'running' | 'cancelling' | 'success' | 'error' | 'cancelled' | 'interrupted';
|
|
5
|
+
export interface PluginTaskResultReference {
|
|
6
|
+
bytes: number;
|
|
7
|
+
sha256: string;
|
|
8
|
+
chunks: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PluginTask {
|
|
11
|
+
taskId: string;
|
|
12
|
+
host: PluginExecutionHost;
|
|
13
|
+
plugin: string;
|
|
14
|
+
installationId: string;
|
|
15
|
+
revision: string;
|
|
16
|
+
command: string;
|
|
17
|
+
kind?: 'command' | 'model';
|
|
18
|
+
parentTaskId?: string;
|
|
19
|
+
resumedFrom?: {
|
|
20
|
+
taskId: string;
|
|
21
|
+
revision: string;
|
|
22
|
+
checkpointSequence: number;
|
|
23
|
+
checkpointVersion: number;
|
|
24
|
+
};
|
|
25
|
+
checkpoint?: PluginTaskCheckpointReference;
|
|
26
|
+
input: Record<string, unknown>;
|
|
27
|
+
source: PluginInvocationSource;
|
|
28
|
+
cwd: string;
|
|
29
|
+
state: PluginTaskState;
|
|
30
|
+
sequence: number;
|
|
31
|
+
createdAt: number;
|
|
32
|
+
updatedAt: number;
|
|
33
|
+
progress?: string | {
|
|
34
|
+
message: string;
|
|
35
|
+
data?: Record<string, unknown>;
|
|
36
|
+
};
|
|
37
|
+
result?: PluginTaskResultReference;
|
|
38
|
+
error?: PluginExecutionError;
|
|
39
|
+
}
|
|
40
|
+
export interface PluginTaskEvent {
|
|
41
|
+
sequence: number;
|
|
42
|
+
time: number;
|
|
43
|
+
type: 'state' | 'progress' | 'checkpoint' | 'diagnostic';
|
|
44
|
+
checkpoint?: PluginTaskCheckpointReference;
|
|
45
|
+
state: PluginTaskState;
|
|
46
|
+
progress?: PluginTask['progress'];
|
|
47
|
+
}
|
|
48
|
+
export interface PluginTaskEvents {
|
|
49
|
+
task: PluginTask;
|
|
50
|
+
events: PluginTaskEvent[];
|
|
51
|
+
firstAvailableSequence: number;
|
|
52
|
+
nextCursor: number;
|
|
53
|
+
gap: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface PluginTaskStartResult {
|
|
56
|
+
taskId: string;
|
|
57
|
+
state: PluginTaskState;
|
|
58
|
+
host: PluginExecutionHost;
|
|
59
|
+
reused?: true;
|
|
60
|
+
}
|
|
61
|
+
export interface PluginTaskListResult {
|
|
62
|
+
tasks: PluginTask[];
|
|
63
|
+
nextCursor?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface PluginTaskResultChunk {
|
|
66
|
+
taskId: string;
|
|
67
|
+
index: number;
|
|
68
|
+
data: string;
|
|
69
|
+
bytes: number;
|
|
70
|
+
sha256: string;
|
|
71
|
+
chunks: number;
|
|
72
|
+
}
|
|
73
|
+
export declare function isPluginTaskActive(state: PluginTaskState): boolean;
|
|
74
|
+
export declare function isPluginTaskId(value: unknown): value is string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const PLUGIN_TASK_PROTOCOL_VERSION = 5;
|
|
2
|
+
export function isPluginTaskActive(state) {
|
|
3
|
+
return state === 'queued' || state === 'running' || state === 'cancelling';
|
|
4
|
+
}
|
|
5
|
+
export function isPluginTaskId(value) {
|
|
6
|
+
return typeof value === 'string' && /^pt_[0-9a-f-]{36}_[0-9a-f-]{36}$/i.test(value);
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ParsedToolboxIcon = {
|
|
2
|
+
kind: 'name';
|
|
3
|
+
name: string;
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'image';
|
|
6
|
+
src: string;
|
|
7
|
+
monochrome?: true;
|
|
8
|
+
};
|
|
9
|
+
/** SVG is an image source so its markup never becomes executable extension DOM. */
|
|
10
|
+
export declare function parseToolboxIcon(value: unknown): ParsedToolboxIcon | undefined;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** SVG is an image source so its markup never becomes executable extension DOM. */
|
|
2
|
+
export function parseToolboxIcon(value) {
|
|
3
|
+
if (typeof value !== 'string')
|
|
4
|
+
return;
|
|
5
|
+
const icon = value.trim();
|
|
6
|
+
if (!icon || icon.length > 32 * 1024)
|
|
7
|
+
return;
|
|
8
|
+
if (/^[a-z][a-z0-9-]{0,39}$/.test(icon))
|
|
9
|
+
return { kind: 'name', name: icon };
|
|
10
|
+
if (/^(?:<\?xml\s[^>]*\?>\s*)?<svg\b[^>]*(?:\/>|>[\s\S]*<\/svg\s*>)$/i.test(icon)) {
|
|
11
|
+
const svg = /<svg\b[^>]*\sxmlns\s*=/i.test(icon)
|
|
12
|
+
? icon
|
|
13
|
+
: icon.replace(/<svg\b/i, '<svg xmlns="http://www.w3.org/2000/svg"');
|
|
14
|
+
try {
|
|
15
|
+
return {
|
|
16
|
+
kind: 'image',
|
|
17
|
+
src: `data:image/svg+xml,${encodeURIComponent(svg)}`,
|
|
18
|
+
...(/\bcurrentColor\b/i.test(svg) ? { monochrome: true } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const dataHeader = /^data:image\/(?:svg\+xml|png|jpeg|gif|webp|avif)(?:;charset=utf-8|;utf8)?(?:;base64)?,/i.exec(icon);
|
|
26
|
+
if (dataHeader && icon.length > dataHeader[0].length)
|
|
27
|
+
return { kind: 'image', src: icon };
|
|
28
|
+
try {
|
|
29
|
+
const url = new URL(icon);
|
|
30
|
+
if (['http:', 'https:'].includes(url.protocol) && !url.username && !url.password) {
|
|
31
|
+
return { kind: 'image', src: url.href };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
/* Non-URL values cannot be image sources. */
|
|
36
|
+
}
|
|
37
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
export { PluginHostConnection, type PluginHostConnectionOptions, type PluginHostClientOptions, } from './pluginHostConnection.js';
|
|
1
2
|
/**
|
|
2
3
|
* @mearl/client — unified Mearl browser client
|
|
3
4
|
*
|
|
4
5
|
* Discovers browser targets on this machine and every configured cloud connector,
|
|
5
6
|
* then routes actions using the global browser ids returned by browser_list.
|
|
6
7
|
*/
|
|
8
|
+
export { PluginTaskClient, type PluginTaskStartOptions, type PluginTaskWaitOptions, type PluginTaskClientOptions, type PluginTask, type PluginTaskEvents, type PluginTaskListResult, type PluginTaskStartResult, } from './pluginTasks.js';
|
|
9
|
+
export { PluginPageClient } from './pluginPages.js';
|
|
10
|
+
export type { PluginPageInstance, PluginPageEvents, PluginPageRuntime, PluginPageActivation, PluginPageTarget, PluginPageOperation, } from './pluginPages.js';
|
|
11
|
+
export { executeRegisteredPlugin, type PluginExecutorOptions, type PluginExecutorDependencies, type PluginCommandContext, type PluginExecutionHost, type PluginInvocationIdentity, type PluginInvocationSource, } from './plugin.js';
|
|
7
12
|
export { UnifiedClient, UnifiedClient as MearlClient, decodeBrowserTarget, invoke, invokePlugin, listCloudConnectors, } from './unified.js';
|
|
8
13
|
export type { UnifiedClientOptions, UnifiedInvokeOptions, UnifiedInvokeOptions as InvokeOptions, } from './unified.js';
|
|
9
14
|
export type { PluginInvocation, PluginInvokeOptions, PluginProgress, StructuredPluginProgress, } from './plugin.js';
|
|
@@ -61,3 +66,9 @@ export declare function saveArtifact(artifact: Protocol.BrowserArtifact & {
|
|
|
61
66
|
outputPath: string;
|
|
62
67
|
bytes: number;
|
|
63
68
|
}>;
|
|
69
|
+
export { PluginStateClient } from './pluginState.js';
|
|
70
|
+
export { PluginModelClient } from './pluginModels.js';
|
|
71
|
+
export type * from './generated-plugin-state.js';
|
|
72
|
+
export type * from './generated-plugin-models.js';
|
|
73
|
+
export type * from './generated-plugin-recovery.js';
|
|
74
|
+
export type * from './generated-plugin-diagnostics.js';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
export { PluginHostConnection, } from './pluginHostConnection.js';
|
|
1
2
|
/**
|
|
2
3
|
* @mearl/client — unified Mearl browser client
|
|
3
4
|
*
|
|
4
5
|
* Discovers browser targets on this machine and every configured cloud connector,
|
|
5
6
|
* then routes actions using the global browser ids returned by browser_list.
|
|
6
7
|
*/
|
|
8
|
+
export { PluginTaskClient, } from './pluginTasks.js';
|
|
9
|
+
export { PluginPageClient } from './pluginPages.js';
|
|
10
|
+
export { executeRegisteredPlugin, } from './plugin.js';
|
|
7
11
|
export { UnifiedClient, UnifiedClient as MearlClient, decodeBrowserTarget, invoke, invokePlugin, listCloudConnectors, } from './unified.js';
|
|
8
12
|
export { APP_PROFILE_NAMES, BROWSER_DEVICE_PRESET_NAMES, BROWSER_ACTIONS, BROWSER_CAPABILITY_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCapabilityAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
|
|
9
13
|
import { invoke } from './unified.js';
|
|
@@ -140,3 +144,5 @@ export async function saveArtifact(artifact, outputPath, options = {}) {
|
|
|
140
144
|
const { exportArtifact } = await import('./artifacts.js');
|
|
141
145
|
return exportArtifact({ invoke }, artifact, outputPath, options);
|
|
142
146
|
}
|
|
147
|
+
export { PluginStateClient } from './pluginState.js';
|
|
148
|
+
export { PluginModelClient } from './pluginModels.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { startPluginHostServer } from './pluginHostServer.js';
|
|
2
|
+
try {
|
|
3
|
+
const server = await startPluginHostServer();
|
|
4
|
+
const close = () => {
|
|
5
|
+
void server.close().then(() => process.exit(0));
|
|
6
|
+
};
|
|
7
|
+
process.once('SIGTERM', close);
|
|
8
|
+
process.once('SIGINT', close);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
if (error.code !== 'PLUGIN_TASK_HOST_OWNED')
|
|
12
|
+
process.stderr.write(`${error instanceof Error ? error.stack : String(error)}\n`);
|
|
13
|
+
process.exitCode = error.code === 'PLUGIN_TASK_HOST_OWNED' ? 0 : 1;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { supervisePluginExecutor } from './pluginExecutorSupervisor.js';
|
|
2
|
+
if (process.argv[2] === '--command') {
|
|
3
|
+
let command;
|
|
4
|
+
// Register IPC before loading command code so startup messages retain their order.
|
|
5
|
+
process.on('message', (message) => {
|
|
6
|
+
void (command ??= import('./pluginCommandWorker.js'))
|
|
7
|
+
.then(worker => worker.handlePluginWorkerMessage(message))
|
|
8
|
+
.catch(error => {
|
|
9
|
+
process.stderr.write(String(error));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
process.on('disconnect', () => process.exit(1));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
supervisePluginExecutor(import.meta.url);
|
|
17
|
+
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
import type { PluginTaskRecoveryDeclaration, PluginTaskCheckpoint, PluginCheckpointMigrationInput } from './generated-plugin-recovery.js';
|
|
2
|
+
import type { PluginStateDeclaration } from './generated-plugin-state.js';
|
|
3
|
+
import type { PluginModelRequest, PluginModelResult } from './generated-plugin-models.js';
|
|
4
|
+
import type { PluginPageRuntime } from './generated-plugin-pages.js';
|
|
1
5
|
import type { AppProfileContribution } from './generated-app-profile-definition.js';
|
|
2
6
|
export type { AppProfileContribution, AppProfileDefinition, } from './generated-app-profile-definition.js';
|
|
3
7
|
export { invokePageEvalWithArgs } from './pageEvalArguments.js';
|
|
4
8
|
import { type OfficialPluginInstaller } from './officialPluginInstaller.js';
|
|
5
9
|
import { type PluginToolboxContribution, type PluginRegistration } from './pluginRegistry.js';
|
|
10
|
+
import { type PluginCommandContext, type PluginInvocationIdentity, type PluginInvocationSource } from './pluginExecution.js';
|
|
6
11
|
import type { UnifiedInvokeOptions } from './unified.js';
|
|
7
|
-
export
|
|
12
|
+
export type { PluginCommandContext, PluginExecutionHost, PluginInvocationIdentity, PluginInvocationSource, } from './pluginExecution.js';
|
|
13
|
+
export { executeRegisteredPlugin, type PluginExecutorOptions, type PluginExecutorDependencies, } from './pluginExecutor.js';
|
|
14
|
+
export { PluginTaskClient } from './pluginTasks.js';
|
|
15
|
+
export { cleanupPluginRuntime } from './pluginRuntimeCleanup.js';
|
|
16
|
+
export { PluginPageClient } from './pluginPages.js';
|
|
17
|
+
export { assertPluginName, findPluginDirectoryEntry, findPluginEntry, findPluginRegistration, listPluginNames, pluginDirectory, registerPlugin, resolvePluginEntry, unregisterPlugin, PluginError, readPluginPageBundleChunk, type PluginRegistration, type PluginRegistrationOptions, type PluginToolboxAgentConfig, type PluginPageBundleRegistration, type PluginToolboxContribution, type PluginToolboxLocale, type PluginToolboxSandboxPage, } from './pluginRegistry.js';
|
|
8
18
|
export { findOfficialPlugin, listOfficialPluginNames, OFFICIAL_PLUGIN_MANAGER, OFFICIAL_PLUGINS, type OfficialPluginDefinition, type OfficialPluginName, } from './officialPluginCatalog.js';
|
|
9
19
|
export type PluginOptions = UnifiedInvokeOptions;
|
|
10
20
|
export interface StructuredPluginProgress {
|
|
@@ -18,48 +28,91 @@ export interface PluginInvocation {
|
|
|
18
28
|
}
|
|
19
29
|
export interface PluginInvokeOptions extends UnifiedInvokeOptions {
|
|
20
30
|
onProgress?: (progress: PluginProgress) => void;
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
/** Audit label supplied by the entry point, never an authorization decision. */
|
|
33
|
+
source?: PluginInvocationSource;
|
|
21
34
|
}
|
|
22
35
|
export interface PluginExecutionContext {
|
|
36
|
+
runModel?(plugin: string, request: PluginModelRequest, options: Pick<PluginInvokeOptions, 'signal' | 'onProgress'>): Promise<PluginModelResult>;
|
|
23
37
|
ensurePlugin?: OfficialPluginInstaller;
|
|
24
|
-
|
|
38
|
+
source?: PluginInvocationSource;
|
|
39
|
+
parentInvocation?: PluginInvocationIdentity;
|
|
40
|
+
invocation?: PluginInvocationIdentity;
|
|
41
|
+
resolveRegistration?: (name: string) => PluginRegistration | undefined;
|
|
42
|
+
invoke(action: string, payload?: Record<string, any>, options?: UnifiedInvokeOptions, onProgress?: PluginInvokeOptions['onProgress']): Promise<any>;
|
|
25
43
|
}
|
|
26
44
|
export interface PluginApp {
|
|
27
45
|
readonly options: Readonly<PluginOptions>;
|
|
28
46
|
/** Examples omit the `mearl <plugin>` prefix, which help adds when displayed. */
|
|
29
47
|
command(signature: string, handler: PluginHandler, description?: string, examples?: string[]): void;
|
|
30
48
|
/** Registers a page-only command, also declared in toolbox.page.commands. */
|
|
49
|
+
state(collection: string, operation: string, input?: Record<string, unknown>): Promise<any>;
|
|
50
|
+
model(request: PluginModelRequest, options?: Pick<PluginInvokeOptions, 'onProgress'>): Promise<PluginModelResult>;
|
|
51
|
+
runtimeCommand(signature: string, handler: PluginHandler, description?: string, examples?: string[]): void;
|
|
52
|
+
recoveryCommand(command: string, handler: PluginHandler): void;
|
|
53
|
+
checkpointMigration(command: string, handler: (input: PluginCheckpointMigrationInput, context: PluginCommandContext) => unknown | Promise<unknown>): void;
|
|
54
|
+
checkpoint(data: unknown, expectedSequence: number): Promise<PluginTaskCheckpoint>;
|
|
55
|
+
page(operation: string, input?: Record<string, unknown>): Promise<any>;
|
|
31
56
|
toolboxCommand(signature: string, handler: PluginHandler, description?: string, examples?: string[]): void;
|
|
32
57
|
invoke(action: string, payload?: Record<string, any>, options?: UnifiedInvokeOptions): Promise<any>;
|
|
33
58
|
progress(progress: PluginProgress): void;
|
|
34
59
|
}
|
|
35
|
-
export type PluginHandler = (input: Record<string, any
|
|
60
|
+
export type PluginHandler = (input: Record<string, any>, context: PluginCommandContext) => unknown | Promise<unknown>;
|
|
36
61
|
/** 工具列表仅检查入口;页面资源只在打开对应工具时检查。 */
|
|
37
62
|
export declare function refreshRegisteredPlugin(name: string, includePage?: boolean): Promise<PluginRegistration | undefined>;
|
|
38
63
|
/** 注册和执行复用同一宿主能力边界;仅 handler 执行期间开放浏览器调用。 */
|
|
39
|
-
export declare function loadPlugin(entry: string, context: Pick<PluginApp, '
|
|
64
|
+
export declare function loadPlugin(entry: string, context: Pick<PluginApp, 'options' | 'progress'> & {
|
|
65
|
+
invoke: PluginExecutionContext['invoke'];
|
|
66
|
+
source?: PluginInvocationSource;
|
|
67
|
+
parentInvocation?: PluginInvocationIdentity;
|
|
68
|
+
invocation?: PluginInvocationIdentity;
|
|
69
|
+
signal?: AbortSignal;
|
|
70
|
+
runModel?: PluginExecutionContext['runModel'];
|
|
71
|
+
onInvocation?: (identity: PluginInvocationIdentity | undefined) => void;
|
|
72
|
+
}, pluginName?: string): Promise<{
|
|
40
73
|
name: string | undefined;
|
|
41
74
|
description: string | undefined;
|
|
42
75
|
toolbox: PluginToolboxContribution | undefined;
|
|
76
|
+
pageRuntime: PluginPageRuntime | undefined;
|
|
77
|
+
stateStorage: PluginStateDeclaration | undefined;
|
|
78
|
+
taskRecovery: PluginTaskRecoveryDeclaration | undefined;
|
|
43
79
|
appProfiles: AppProfileContribution | undefined;
|
|
44
80
|
profileSources: Record<string, string> | undefined;
|
|
45
81
|
version: string | undefined;
|
|
46
82
|
commandHelp(namespace: string): string;
|
|
47
83
|
help(namespace: string, name?: string): string;
|
|
48
84
|
run(positionals: string[], payload?: unknown, namedInput?: Record<string, unknown>): Promise<unknown>;
|
|
85
|
+
runRuntime(invocation: PluginInvocation): Promise<unknown>;
|
|
86
|
+
runRecovery(invocation: PluginInvocation): Promise<unknown>;
|
|
87
|
+
runMigration(invocation: PluginInvocation): Promise<unknown>;
|
|
49
88
|
runToolbox(invocation: PluginInvocation): Promise<unknown>;
|
|
50
89
|
}>;
|
|
51
90
|
export declare function loadRegisteredPlugin(name: string, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<{
|
|
52
91
|
name: string | undefined;
|
|
53
92
|
description: string | undefined;
|
|
54
93
|
toolbox: PluginToolboxContribution | undefined;
|
|
94
|
+
pageRuntime: PluginPageRuntime | undefined;
|
|
95
|
+
stateStorage: PluginStateDeclaration | undefined;
|
|
96
|
+
taskRecovery: PluginTaskRecoveryDeclaration | undefined;
|
|
55
97
|
appProfiles: AppProfileContribution | undefined;
|
|
56
98
|
profileSources: Record<string, string> | undefined;
|
|
57
99
|
version: string | undefined;
|
|
58
100
|
commandHelp(namespace: string): string;
|
|
59
101
|
help(namespace: string, name?: string): string;
|
|
60
102
|
run(positionals: string[], payload?: unknown, namedInput?: Record<string, unknown>): Promise<unknown>;
|
|
103
|
+
runRuntime(invocation: PluginInvocation): Promise<unknown>;
|
|
104
|
+
runRecovery(invocation: PluginInvocation): Promise<unknown>;
|
|
105
|
+
runMigration(invocation: PluginInvocation): Promise<unknown>;
|
|
61
106
|
runToolbox(invocation: PluginInvocation): Promise<unknown>;
|
|
62
107
|
}>;
|
|
63
108
|
export declare function invokeRegisteredPlugin(name: string, invocation: PluginInvocation, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<unknown>;
|
|
64
109
|
/** Entry point for the native toolbox service; nested plugin calls retain public-command access. */
|
|
65
110
|
export declare function invokeRegisteredToolboxPlugin(name: string, invocation: PluginInvocation, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<unknown>;
|
|
111
|
+
export declare function invokeRegisteredRuntimePlugin(name: string, invocation: PluginInvocation, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<unknown>;
|
|
112
|
+
export declare function invokeRegisteredRecoveryPlugin(name: string, invocation: PluginInvocation, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<unknown>;
|
|
113
|
+
export { PluginStateClient } from './pluginState.js';
|
|
114
|
+
export { PluginModelClient } from './pluginModels.js';
|
|
115
|
+
export type * from './generated-plugin-state.js';
|
|
116
|
+
export type * from './generated-plugin-models.js';
|
|
117
|
+
export type * from './generated-plugin-recovery.js';
|
|
118
|
+
export type * from './generated-plugin-diagnostics.js';
|