@mearl/client 2.21.0 → 3.0.0-beta.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/LICENSE +201 -0
- package/README.md +57 -27
- package/dist/actionTimeouts.js +1 -1
- package/dist/artifacts.d.ts +1 -1
- package/dist/autoUpdate.js +1 -2
- package/dist/browserRegistry.d.ts +1 -1
- package/dist/check.d.ts +1 -1
- package/dist/check.js +4 -3
- package/dist/cli.js +4 -3
- package/dist/commands.d.ts +20 -20
- package/dist/commands.js +17 -15
- package/dist/index.d.ts +12 -15
- package/dist/index.js +7 -7
- package/dist/local.d.ts +3 -1
- package/dist/local.js +2 -1
- package/dist/pageEvalArguments.d.ts +1 -1
- package/dist/pageEvalArguments.js +1 -1
- package/dist/plugin-task-host.js +1 -1
- package/dist/plugin-worker.js +2 -2
- package/dist/plugin.d.ts +2 -118
- package/dist/plugin.js +2 -672
- package/dist/pluginModelSessionWorker.d.ts +2 -2
- package/dist/pluginModelSessionWorker.js +4 -4
- package/dist/{pluginHostConnection.d.ts → plugins/clients/pluginHostConnection.d.ts} +2 -2
- package/dist/{pluginHostConnection.js → plugins/clients/pluginHostConnection.js} +6 -7
- package/dist/{pluginModels.d.ts → plugins/clients/pluginModels.d.ts} +3 -3
- package/dist/{pluginPages.d.ts → plugins/clients/pluginPages.d.ts} +3 -3
- package/dist/{pluginPages.js → plugins/clients/pluginPages.js} +1 -1
- package/dist/{pluginState.d.ts → plugins/clients/pluginState.d.ts} +3 -3
- package/dist/{pluginTasks.d.ts → plugins/clients/pluginTasks.d.ts} +4 -4
- package/dist/{pluginTasks.js → plugins/clients/pluginTasks.js} +4 -4
- package/dist/plugins/officialPluginCatalog.d.ts +25 -0
- package/dist/plugins/officialPluginCatalog.js +125 -0
- package/dist/{officialPluginInstaller.js → plugins/officialPluginInstaller.js} +7 -4
- package/dist/{pluginRegistry.d.ts → plugins/pluginRegistry.d.ts} +1 -1
- package/dist/{pluginRegistry.js → plugins/pluginRegistry.js} +3 -3
- package/dist/{pluginTaskProtocol.d.ts → plugins/pluginTaskProtocol.d.ts} +2 -2
- package/dist/{pluginCommandWorker.js → plugins/runtime/pluginCommandWorker.js} +3 -3
- package/dist/{pluginDiagnostics.d.ts → plugins/runtime/pluginDiagnostics.d.ts} +4 -4
- package/dist/{pluginDiagnostics.js → plugins/runtime/pluginDiagnostics.js} +2 -2
- package/dist/{pluginExecution.d.ts → plugins/runtime/pluginExecution.d.ts} +3 -3
- package/dist/{pluginExecution.js → plugins/runtime/pluginExecution.js} +1 -1
- package/dist/{pluginExecutor.d.ts → plugins/runtime/pluginExecutor.d.ts} +3 -3
- package/dist/{pluginExecutor.js → plugins/runtime/pluginExecutor.js} +4 -4
- package/dist/{pluginExecutorProtocol.d.ts → plugins/runtime/pluginExecutorProtocol.d.ts} +4 -4
- package/dist/{pluginHost.d.ts → plugins/runtime/pluginHost.d.ts} +3 -3
- package/dist/{pluginHostPaths.js → plugins/runtime/pluginHostPaths.js} +1 -1
- package/dist/{pluginHostServer.js → plugins/runtime/pluginHostServer.js} +3 -3
- package/dist/{pluginModelCatalog.d.ts → plugins/runtime/pluginModelCatalog.d.ts} +1 -1
- package/dist/{pluginModelSessions.js → plugins/runtime/pluginModelSessions.js} +3 -3
- package/dist/{pluginPageManager.d.ts → plugins/runtime/pluginPageManager.d.ts} +4 -4
- package/dist/{pluginPageManager.js → plugins/runtime/pluginPageManager.js} +5 -5
- package/dist/{pluginRevision.d.ts → plugins/runtime/pluginRevision.d.ts} +1 -1
- package/dist/{pluginRevision.js → plugins/runtime/pluginRevision.js} +3 -2
- package/dist/{pluginRuntimeCleanup.js → plugins/runtime/pluginRuntimeCleanup.js} +2 -2
- package/dist/{pluginStateManager.d.ts → plugins/runtime/pluginStateManager.d.ts} +2 -2
- package/dist/{pluginStateManager.js → plugins/runtime/pluginStateManager.js} +2 -2
- package/dist/{pluginStateStore.d.ts → plugins/runtime/pluginStateStore.d.ts} +1 -1
- package/dist/{pluginStateStore.js → plugins/runtime/pluginStateStore.js} +1 -1
- package/dist/{pluginTaskManager.d.ts → plugins/runtime/pluginTaskManager.d.ts} +12 -12
- package/dist/{pluginTaskManager.js → plugins/runtime/pluginTaskManager.js} +6 -6
- package/dist/{pluginTaskStore.d.ts → plugins/runtime/pluginTaskStore.d.ts} +4 -4
- package/dist/{pluginTaskStore.js → plugins/runtime/pluginTaskStore.js} +1 -1
- package/dist/{pythonPlugin.d.ts → plugins/runtime/pythonPlugin.d.ts} +2 -2
- package/dist/{pythonPlugin.js → plugins/runtime/pythonPlugin.js} +2 -2
- package/dist/plugins/sdk/plugin.d.ts +115 -0
- package/dist/plugins/sdk/plugin.js +669 -0
- package/dist/{pluginAppProfiles.d.ts → plugins/sdk/pluginAppProfiles.d.ts} +1 -1
- package/dist/{pluginAppProfiles.js → plugins/sdk/pluginAppProfiles.js} +2 -2
- package/dist/{pluginModelDefinition.d.ts → plugins/sdk/pluginModelDefinition.d.ts} +1 -1
- package/dist/{pluginPageDefinition.d.ts → plugins/sdk/pluginPageDefinition.d.ts} +1 -1
- package/dist/{pluginPageDefinition.js → plugins/sdk/pluginPageDefinition.js} +1 -1
- package/dist/{pluginRecoveryDefinition.d.ts → plugins/sdk/pluginRecoveryDefinition.d.ts} +1 -1
- package/dist/{pluginStateDefinition.d.ts → plugins/sdk/pluginStateDefinition.d.ts} +2 -2
- package/dist/plugins/skillManifest.d.ts +10 -0
- package/dist/plugins/skillManifest.js +56 -0
- package/dist/runtimePaths.d.ts +4 -0
- package/dist/runtimePaths.js +8 -0
- package/dist/socket.d.ts +4 -2
- package/dist/socket.js +17 -6
- package/dist/unified.d.ts +2 -2
- package/dist/unified.js +7 -7
- package/package.json +9 -8
- package/dist/generated-app-profile-definition.d.ts +0 -130
- package/dist/generated-app-profile-definition.js +0 -458
- package/dist/generated-app-profile-runtime-types.d.ts +0 -213
- package/dist/generated-app-profile-runtime-types.js +0 -1
- package/dist/generated-browser-action-protocol.d.ts +0 -1147
- package/dist/generated-browser-action-protocol.js +0 -283
- package/dist/generated-plugin-diagnostics.d.ts +0 -110
- package/dist/generated-plugin-diagnostics.js +0 -1
- package/dist/generated-plugin-execution.d.ts +0 -27
- package/dist/generated-plugin-execution.js +0 -1
- package/dist/generated-plugin-models.d.ts +0 -64
- package/dist/generated-plugin-models.js +0 -1
- package/dist/generated-plugin-pages.d.ts +0 -76
- package/dist/generated-plugin-pages.js +0 -59
- package/dist/generated-plugin-recovery.d.ts +0 -32
- package/dist/generated-plugin-recovery.js +0 -1
- package/dist/generated-plugin-state.d.ts +0 -50
- package/dist/generated-plugin-state.js +0 -1
- package/dist/generated-plugin-tasks.d.ts +0 -74
- package/dist/generated-plugin-tasks.js +0 -7
- package/dist/generated-toolbox-icon.d.ts +0 -10
- package/dist/generated-toolbox-icon.js +0 -37
- package/dist/officialPluginCatalog.d.ts +0 -28
- package/dist/officialPluginCatalog.js +0 -29
- /package/dist/{pluginModels.js → plugins/clients/pluginModels.js} +0 -0
- /package/dist/{pluginState.js → plugins/clients/pluginState.js} +0 -0
- /package/dist/{officialPluginInstaller.d.ts → plugins/officialPluginInstaller.d.ts} +0 -0
- /package/dist/{pluginPageBundle.d.ts → plugins/pluginPageBundle.d.ts} +0 -0
- /package/dist/{pluginPageBundle.js → plugins/pluginPageBundle.js} +0 -0
- /package/dist/{pluginSource.d.ts → plugins/pluginSource.d.ts} +0 -0
- /package/dist/{pluginSource.js → plugins/pluginSource.js} +0 -0
- /package/dist/{pluginTaskProtocol.js → plugins/pluginTaskProtocol.js} +0 -0
- /package/dist/{pluginTaskWire.d.ts → plugins/pluginTaskWire.d.ts} +0 -0
- /package/dist/{pluginTaskWire.js → plugins/pluginTaskWire.js} +0 -0
- /package/dist/{pluginCommandWorker.d.ts → plugins/runtime/pluginCommandWorker.d.ts} +0 -0
- /package/dist/{pluginExecutorProtocol.js → plugins/runtime/pluginExecutorProtocol.js} +0 -0
- /package/dist/{pluginExecutorSupervisor.d.ts → plugins/runtime/pluginExecutorSupervisor.d.ts} +0 -0
- /package/dist/{pluginExecutorSupervisor.js → plugins/runtime/pluginExecutorSupervisor.js} +0 -0
- /package/dist/{pluginHost.js → plugins/runtime/pluginHost.js} +0 -0
- /package/dist/{pluginHostFiles.d.ts → plugins/runtime/pluginHostFiles.d.ts} +0 -0
- /package/dist/{pluginHostFiles.js → plugins/runtime/pluginHostFiles.js} +0 -0
- /package/dist/{pluginHostPaths.d.ts → plugins/runtime/pluginHostPaths.d.ts} +0 -0
- /package/dist/{pluginHostServer.d.ts → plugins/runtime/pluginHostServer.d.ts} +0 -0
- /package/dist/{pluginModelCatalog.js → plugins/runtime/pluginModelCatalog.js} +0 -0
- /package/dist/{pluginModelSessions.d.ts → plugins/runtime/pluginModelSessions.d.ts} +0 -0
- /package/dist/{pluginProcessTree.d.ts → plugins/runtime/pluginProcessTree.d.ts} +0 -0
- /package/dist/{pluginProcessTree.js → plugins/runtime/pluginProcessTree.js} +0 -0
- /package/dist/{pluginRuntimeCleanup.d.ts → plugins/runtime/pluginRuntimeCleanup.d.ts} +0 -0
- /package/dist/{pluginModelDefinition.js → plugins/sdk/pluginModelDefinition.js} +0 -0
- /package/dist/{pluginRecoveryDefinition.js → plugins/sdk/pluginRecoveryDefinition.js} +0 -0
- /package/dist/{pluginStateDefinition.js → plugins/sdk/pluginStateDefinition.js} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { serializePluginExecutionError } from './pluginExecutorProtocol.js';
|
|
3
|
-
import { supervisePluginExecutor } from './pluginExecutorSupervisor.js';
|
|
1
|
+
import { CLIENT_VERSION } from './runtimePaths.js';
|
|
2
|
+
import { serializePluginExecutionError } from './plugins/runtime/pluginExecutorProtocol.js';
|
|
3
|
+
import { supervisePluginExecutor } from './plugins/runtime/pluginExecutorSupervisor.js';
|
|
4
4
|
if (process.argv[2] !== '--command') {
|
|
5
5
|
supervisePluginExecutor(import.meta.url);
|
|
6
6
|
}
|
|
7
7
|
else {
|
|
8
8
|
const ready = import('@mearl/agent-runtime/codex').then(runtime => ({
|
|
9
9
|
runtime,
|
|
10
|
-
provider: new runtime.CodexAgentProvider(() => { },
|
|
10
|
+
provider: new runtime.CodexAgentProvider(() => { }, CLIENT_VERSION),
|
|
11
11
|
}));
|
|
12
12
|
const conversation = {};
|
|
13
13
|
let busy = false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PluginInvocationSource, PluginExecutionHost } from '
|
|
2
|
-
import type { PluginExecutionContext } from '
|
|
1
|
+
import type { PluginInvocationSource, PluginExecutionHost } from '@mearl/browser-core';
|
|
2
|
+
import type { PluginExecutionContext } from '../sdk/plugin.js';
|
|
3
3
|
export interface PluginHostConnectionOptions {
|
|
4
4
|
source?: PluginInvocationSource;
|
|
5
5
|
plugin?: string;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { closeSync, mkdirSync, openSync } from 'node:fs';
|
|
3
3
|
import { createConnection } from 'node:net';
|
|
4
|
-
import {
|
|
4
|
+
import { PLUGIN_TASK_HOST_PATH } from '../../runtimePaths.js';
|
|
5
5
|
import { claimRecord, isProcessOwnerAlive, processIdentity, readRecord, removeInvalidRecord, removeRecordIfPid, rotateLogIfNeeded, } from '@mearl/daemon-core';
|
|
6
|
-
import { pluginHostPaths } from '
|
|
7
|
-
import { PLUGIN_TASK_PROTOCOL_VERSION } from '
|
|
8
|
-
import { readPluginTaskMessages, writePluginTaskMessage } from '
|
|
9
|
-
import { pluginExecutionError, serializePluginExecutionError } from '
|
|
6
|
+
import { pluginHostPaths } from '../runtime/pluginHostPaths.js';
|
|
7
|
+
import { PLUGIN_TASK_PROTOCOL_VERSION } from '@mearl/browser-core';
|
|
8
|
+
import { readPluginTaskMessages, writePluginTaskMessage } from '../pluginTaskWire.js';
|
|
9
|
+
import { pluginExecutionError, serializePluginExecutionError, } from '../runtime/pluginExecutorProtocol.js';
|
|
10
10
|
const starting = new Map();
|
|
11
11
|
async function ensureHost(runtimePath) {
|
|
12
12
|
const paths = pluginHostPaths();
|
|
@@ -112,8 +112,7 @@ export class PluginHostConnection {
|
|
|
112
112
|
if (!['ENOENT', 'ECONNREFUSED', 'PLUGIN_TASK_CONNECTION_LOST'].includes(code ?? ''))
|
|
113
113
|
throw error;
|
|
114
114
|
}
|
|
115
|
-
await ensureHost(this.configuration.runtimePath ??
|
|
116
|
-
fileURLToPath(new URL('./plugin-task-host.js', import.meta.url)));
|
|
115
|
+
await ensureHost(this.configuration.runtimePath ?? PLUGIN_TASK_HOST_PATH);
|
|
117
116
|
const deadline = Date.now() + 10000;
|
|
118
117
|
let failure;
|
|
119
118
|
do {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { PluginHostClientOptions } from './pluginHostConnection.js';
|
|
2
2
|
import { PluginTaskClient } from './pluginTasks.js';
|
|
3
3
|
import type { PluginTaskStartOptions, PluginTaskWaitOptions } from './pluginTasks.js';
|
|
4
|
-
import type { PluginModelRequest, PluginModelResult, PluginModelCapability, PluginModelList } from '
|
|
5
|
-
import type { PluginTaskStartResult } from '
|
|
6
|
-
export type * from '
|
|
4
|
+
import type { PluginModelRequest, PluginModelResult, PluginModelCapability, PluginModelList } from '@mearl/browser-core';
|
|
5
|
+
import type { PluginTaskStartResult } from '@mearl/browser-core';
|
|
6
|
+
export type * from '@mearl/browser-core';
|
|
7
7
|
export declare class PluginModelClient {
|
|
8
8
|
readonly tasks: PluginTaskClient;
|
|
9
9
|
constructor(options?: PluginHostClientOptions);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PluginHostConnection } from './pluginHostConnection.js';
|
|
2
|
-
import type { UnifiedClientOptions, UnifiedInvokeOptions } from '
|
|
3
|
-
import type { PluginPageInstance, PluginPageEvents, PluginPageOperation } from '
|
|
4
|
-
export type { PluginPageInstance, PluginPageEvents, PluginPageRuntime, PluginPageActivation, PluginPageTarget, PluginPageOperation, } from '
|
|
2
|
+
import type { UnifiedClientOptions, UnifiedInvokeOptions } from '../../unified.js';
|
|
3
|
+
import type { PluginPageInstance, PluginPageEvents, PluginPageOperation } from '@mearl/browser-core';
|
|
4
|
+
export type { PluginPageInstance, PluginPageEvents, PluginPageRuntime, PluginPageActivation, PluginPageTarget, PluginPageOperation, } from '@mearl/browser-core';
|
|
5
5
|
export declare class PluginPageClient {
|
|
6
6
|
private readonly connection?;
|
|
7
7
|
private readonly client?;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PluginHostConnection } from './pluginHostConnection.js';
|
|
2
2
|
import type { PluginHostClientOptions } from './pluginHostConnection.js';
|
|
3
|
-
import type { PluginOptions } from '
|
|
4
|
-
import type { PluginStateOperation, PluginStateSnapshot, PluginStateList, PluginStateTransaction } from '
|
|
5
|
-
export type * from '
|
|
3
|
+
import type { PluginOptions } from '../sdk/plugin.js';
|
|
4
|
+
import type { PluginStateOperation, PluginStateSnapshot, PluginStateList, PluginStateTransaction } from '@mearl/browser-core';
|
|
5
|
+
export type * from '@mearl/browser-core';
|
|
6
6
|
export declare class PluginStateClient {
|
|
7
7
|
private readonly options;
|
|
8
8
|
readonly connection: PluginHostConnection;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PluginHostConnection } from './pluginHostConnection.js';
|
|
2
2
|
import type { PluginHostClientOptions, HostStatus as PluginHostStatus } from './pluginHostConnection.js';
|
|
3
|
-
import type { PluginTaskCheckpoint } from '
|
|
4
|
-
import type { PluginDiagnosticOptions, PluginDiagnosticReport } from '
|
|
5
|
-
import type { PluginTask, PluginTaskEvents, PluginTaskListResult, PluginTaskResultChunk, PluginTaskStartResult } from '
|
|
6
|
-
import type { PluginInvocation, PluginOptions } from '
|
|
3
|
+
import type { PluginTaskCheckpoint } from '@mearl/browser-core';
|
|
4
|
+
import type { PluginDiagnosticOptions, PluginDiagnosticReport } from '@mearl/browser-core';
|
|
5
|
+
import type { PluginTask, PluginTaskEvents, PluginTaskListResult, PluginTaskResultChunk, PluginTaskStartResult } from '@mearl/browser-core';
|
|
6
|
+
import type { PluginInvocation, PluginOptions } from '../sdk/plugin.js';
|
|
7
7
|
export type { PluginTask, PluginTaskEvents, PluginTaskListResult, PluginTaskStartResult };
|
|
8
8
|
export interface PluginTaskStartOptions extends PluginOptions {
|
|
9
9
|
cwd?: string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PluginHostConnection } from './pluginHostConnection.js';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { isProcessOwnerAlive, readRecord } from '@mearl/daemon-core';
|
|
4
|
-
import { pluginHostPaths } from '
|
|
5
|
-
import { UnifiedClient, decodeBrowserTarget } from '
|
|
6
|
-
import { isPluginTaskActive } from '
|
|
7
|
-
import { pluginExecutionError } from '
|
|
4
|
+
import { pluginHostPaths } from '../runtime/pluginHostPaths.js';
|
|
5
|
+
import { UnifiedClient, decodeBrowserTarget } from '../../unified.js';
|
|
6
|
+
import { isPluginTaskActive } from '@mearl/browser-core';
|
|
7
|
+
import { pluginExecutionError } from '../runtime/pluginExecutorProtocol.js';
|
|
8
8
|
function localWait(promise, signal, timeoutMs = Infinity) {
|
|
9
9
|
return new Promise((resolve, reject) => {
|
|
10
10
|
const abort = () => {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const OFFICIAL_PLUGIN_MANAGER = "@mearl/setup:official";
|
|
2
|
+
export interface OfficialPluginDefinition {
|
|
3
|
+
description: string;
|
|
4
|
+
installArgs: readonly string[];
|
|
5
|
+
setup?: string;
|
|
6
|
+
skill: string;
|
|
7
|
+
}
|
|
8
|
+
export type OfficialPluginName = string;
|
|
9
|
+
export declare const OFFICIAL_PLUGINS: Record<string, OfficialPluginDefinition>;
|
|
10
|
+
export interface PluginCatalogSelection {
|
|
11
|
+
path: string;
|
|
12
|
+
sha256: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PluginCatalog {
|
|
15
|
+
schemaVersion: 1;
|
|
16
|
+
revision: string;
|
|
17
|
+
plugins: Record<string, OfficialPluginDefinition>;
|
|
18
|
+
selection?: PluginCatalogSelection;
|
|
19
|
+
}
|
|
20
|
+
export declare function validateOfficialPluginCatalog(value: unknown): PluginCatalog;
|
|
21
|
+
export declare function readOfficialPluginCatalog(): PluginCatalog | undefined;
|
|
22
|
+
/** Installation hosts persist only the catalog selected by an approved preset. */
|
|
23
|
+
export declare function replaceOfficialPluginCatalog(revision: string, plugins: Record<string, OfficialPluginDefinition>, selection?: PluginCatalogSelection): void;
|
|
24
|
+
export declare function findOfficialPlugin(name: string): OfficialPluginDefinition | undefined;
|
|
25
|
+
export declare function listOfficialPluginNames(setup?: string): string[];
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { constants, closeSync, fstatSync, lstatSync, mkdirSync, openSync, readSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
3
|
+
import { isAbsolute, join } from 'node:path';
|
|
4
|
+
import { assertPluginName, pluginDirectory } from './pluginRegistry.js';
|
|
5
|
+
export const OFFICIAL_PLUGIN_MANAGER = '@mearl/setup:official';
|
|
6
|
+
export const OFFICIAL_PLUGINS = {};
|
|
7
|
+
const MAX_CATALOG_BYTES = 256 * 1024;
|
|
8
|
+
const catalogPath = () => join(pluginDirectory(), '.official-catalog.json');
|
|
9
|
+
export function validateOfficialPluginCatalog(value) {
|
|
10
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
11
|
+
throw new Error('Invalid managed plugin catalog');
|
|
12
|
+
const input = value;
|
|
13
|
+
if (input.schemaVersion !== 1 || typeof input.revision !== 'string' || !/^[a-f0-9]{64}$/.test(input.revision) ||
|
|
14
|
+
!input.plugins || typeof input.plugins !== 'object' || Array.isArray(input.plugins) ||
|
|
15
|
+
Object.keys(input).some(key => !['schemaVersion', 'revision', 'plugins', 'selection'].includes(key)) || Object.keys(input.plugins).length > 200)
|
|
16
|
+
throw new Error('Invalid managed plugin catalog');
|
|
17
|
+
const selection = input.selection;
|
|
18
|
+
if (selection !== undefined && (!selection || typeof selection !== 'object' || Array.isArray(selection) || Object.keys(selection).some(key => !['path', 'sha256'].includes(key)) || typeof selection.path !== 'string' || !isAbsolute(selection.path) || selection.path.length > 4096 || /[\0\r\n]/.test(selection.path) || typeof selection.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(selection.sha256)))
|
|
19
|
+
throw new Error('Invalid plugin catalog selection');
|
|
20
|
+
const plugins = {};
|
|
21
|
+
for (const [name, value] of Object.entries(input.plugins)) {
|
|
22
|
+
assertPluginName(name);
|
|
23
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
24
|
+
throw new Error('Invalid managed plugin declaration');
|
|
25
|
+
const item = value;
|
|
26
|
+
if (Object.keys(item).some(key => !['description', 'installArgs', 'setup', 'skill'].includes(key)) ||
|
|
27
|
+
typeof item.description !== 'string' || item.description.length > 1000 ||
|
|
28
|
+
typeof item.skill !== 'string' || !/^[a-z][a-z0-9-]*$/.test(item.skill) ||
|
|
29
|
+
!Array.isArray(item.installArgs) || item.installArgs.length === 0 || item.installArgs.length > 32 ||
|
|
30
|
+
item.installArgs.some(arg => typeof arg !== 'string' || arg.length > 2048 || /[\0\r\n]/.test(arg)) ||
|
|
31
|
+
(item.setup !== undefined && (typeof item.setup !== 'string' || !/^[a-z][a-z0-9-]*$/.test(item.setup))))
|
|
32
|
+
throw new Error('Invalid managed plugin declaration');
|
|
33
|
+
plugins[name] = { description: item.description, skill: item.skill, installArgs: [...item.installArgs], ...(item.setup !== undefined && { setup: item.setup }) };
|
|
34
|
+
}
|
|
35
|
+
const catalog = { schemaVersion: 1, revision: input.revision, plugins, ...(selection ? { selection: { path: selection.path, sha256: selection.sha256 } } : {}) };
|
|
36
|
+
if (Buffer.byteLength(JSON.stringify(catalog)) > MAX_CATALOG_BYTES)
|
|
37
|
+
throw new Error('Managed plugin catalog exceeds 256 KiB');
|
|
38
|
+
return catalog;
|
|
39
|
+
}
|
|
40
|
+
function selectionMatches(selection) {
|
|
41
|
+
try {
|
|
42
|
+
const before = lstatSync(selection.path);
|
|
43
|
+
if (!before.isFile() || before.isSymbolicLink() || before.size > 1024 * 1024)
|
|
44
|
+
return false;
|
|
45
|
+
const fd = openSync(selection.path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
46
|
+
try {
|
|
47
|
+
const stat = fstatSync(fd);
|
|
48
|
+
if (!stat.isFile() || stat.size > 1024 * 1024)
|
|
49
|
+
return false;
|
|
50
|
+
const bytes = Buffer.alloc(stat.size + 1);
|
|
51
|
+
let size = 0;
|
|
52
|
+
while (size < bytes.length) {
|
|
53
|
+
const count = readSync(fd, bytes, size, bytes.length - size, null);
|
|
54
|
+
if (!count)
|
|
55
|
+
break;
|
|
56
|
+
size += count;
|
|
57
|
+
}
|
|
58
|
+
return size === stat.size && createHash('sha256').update(bytes.subarray(0, size)).digest('hex') === selection.sha256;
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
closeSync(fd);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error.code === 'ENOENT')
|
|
66
|
+
return false;
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function readOfficialPluginCatalog() {
|
|
71
|
+
let source;
|
|
72
|
+
try {
|
|
73
|
+
source = readFileSync(catalogPath(), 'utf8');
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error.code === 'ENOENT')
|
|
77
|
+
return undefined;
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
if (Buffer.byteLength(source) > MAX_CATALOG_BYTES)
|
|
81
|
+
throw new Error('Managed plugin catalog exceeds 256 KiB');
|
|
82
|
+
const catalog = validateOfficialPluginCatalog(JSON.parse(source));
|
|
83
|
+
return catalog.selection && !selectionMatches(catalog.selection) ? undefined : catalog;
|
|
84
|
+
}
|
|
85
|
+
/** Installation hosts persist only the catalog selected by an approved preset. */
|
|
86
|
+
export function replaceOfficialPluginCatalog(revision, plugins, selection) {
|
|
87
|
+
const catalog = validateOfficialPluginCatalog({ schemaVersion: 1, revision, plugins, ...(selection ? { selection } : {}) });
|
|
88
|
+
const content = JSON.stringify(catalog);
|
|
89
|
+
if (Buffer.byteLength(content) > MAX_CATALOG_BYTES)
|
|
90
|
+
throw new Error('Managed plugin catalog exceeds 256 KiB');
|
|
91
|
+
if (catalog.selection && !selectionMatches(catalog.selection))
|
|
92
|
+
throw new Error('PLUGIN_CATALOG_SELECTION_CHANGED');
|
|
93
|
+
mkdirSync(pluginDirectory(), { recursive: true, mode: 0o700 });
|
|
94
|
+
const file = catalogPath();
|
|
95
|
+
const temporary = `${file}.${randomUUID()}.tmp`;
|
|
96
|
+
try {
|
|
97
|
+
writeFileSync(temporary, content, { mode: 0o600, flag: 'wx' });
|
|
98
|
+
if (catalog.selection && !selectionMatches(catalog.selection))
|
|
99
|
+
throw new Error('PLUGIN_CATALOG_SELECTION_CHANGED');
|
|
100
|
+
renameSync(temporary, file);
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
rmSync(temporary, { force: true });
|
|
104
|
+
}
|
|
105
|
+
refreshOfficialPlugins();
|
|
106
|
+
}
|
|
107
|
+
function refreshOfficialPlugins() {
|
|
108
|
+
let plugins = {};
|
|
109
|
+
try {
|
|
110
|
+
plugins = readOfficialPluginCatalog()?.plugins ?? {};
|
|
111
|
+
}
|
|
112
|
+
catch { /* An invalid optional catalog cannot disable registered plugin or browser commands. */ }
|
|
113
|
+
for (const name of Object.keys(OFFICIAL_PLUGINS))
|
|
114
|
+
delete OFFICIAL_PLUGINS[name];
|
|
115
|
+
Object.assign(OFFICIAL_PLUGINS, plugins);
|
|
116
|
+
return OFFICIAL_PLUGINS;
|
|
117
|
+
}
|
|
118
|
+
refreshOfficialPlugins();
|
|
119
|
+
export function findOfficialPlugin(name) {
|
|
120
|
+
const plugins = refreshOfficialPlugins();
|
|
121
|
+
return Object.hasOwn(plugins, name) ? plugins[name] : undefined;
|
|
122
|
+
}
|
|
123
|
+
export function listOfficialPluginNames(setup) {
|
|
124
|
+
return Object.entries(refreshOfficialPlugins()).filter(([, item]) => setup === undefined || item.setup === setup).map(([name]) => name);
|
|
125
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { closeSync, mkdirSync, openSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import {
|
|
2
|
+
import { CLIENT_VERSION } from '../runtimePaths.js';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
-
import { findOfficialPlugin } from './officialPluginCatalog.js';
|
|
5
|
+
import { findOfficialPlugin, readOfficialPluginCatalog } from './officialPluginCatalog.js';
|
|
6
6
|
import { findPluginRegistration, pluginDirectory } from './pluginRegistry.js';
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const CLIENT_VERSION = require('../package.json').version;
|
|
9
7
|
const INSTALL_TIMEOUT_MS = 180_000;
|
|
10
8
|
const INSTALL_LOCK_STALE_MS = 5 * 60_000;
|
|
11
9
|
const MAX_INSTALL_OUTPUT = 1024 * 1024;
|
|
@@ -107,8 +105,13 @@ async function installOfficialPlugin(name, progress) {
|
|
|
107
105
|
try {
|
|
108
106
|
if (findPluginRegistration(name))
|
|
109
107
|
return;
|
|
108
|
+
const accepted = JSON.stringify(readOfficialPluginCatalog());
|
|
109
|
+
if (!findOfficialPlugin(name))
|
|
110
|
+
throw new Error('PLUGIN_CATALOG_SELECTION_CHANGED');
|
|
110
111
|
progress?.(`正在安装官方插件 ${name}...`);
|
|
111
112
|
await installWithSetup(name);
|
|
113
|
+
if (JSON.stringify(readOfficialPluginCatalog()) !== accepted)
|
|
114
|
+
throw new Error('PLUGIN_CATALOG_SELECTION_CHANGED');
|
|
112
115
|
if (!findPluginRegistration(name)) {
|
|
113
116
|
throw new Error(`官方插件 ${name} 安装完成后仍未注册`);
|
|
114
117
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppProfileContribution } from '
|
|
1
|
+
import { type AppProfileContribution } from '@mearl/browser-core';
|
|
2
2
|
export declare class PluginError extends Error {
|
|
3
3
|
readonly code: string;
|
|
4
4
|
constructor(code: string, message: string);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { validateAppProfileContribution, } from '
|
|
1
|
+
import { validateAppProfileContribution, } from '@mearl/browser-core';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { parseToolboxIcon } from '
|
|
3
|
+
import { parseToolboxIcon } from '@mearl/browser-core';
|
|
4
4
|
import { closeSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
7
|
-
import { COMMAND_MAP } from '
|
|
7
|
+
import { COMMAND_MAP } from '../commands.js';
|
|
8
8
|
import { buildPluginPageBundle, PLUGIN_PAGE_CHUNK_BYTES, PLUGIN_PAGE_RUNTIME_HASH, } from './pluginPageBundle.js';
|
|
9
9
|
import { pluginFileVersion } from './pluginSource.js';
|
|
10
10
|
const RESERVED_NAMES = new Set([
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PluginExecutionError, PluginInvocationSource } from '
|
|
2
|
-
import type { PluginOptions } from './plugin.js';
|
|
1
|
+
import type { PluginExecutionError, PluginInvocationSource } from '@mearl/browser-core';
|
|
2
|
+
import type { PluginOptions } from './sdk/plugin.js';
|
|
3
3
|
export interface PluginTaskScope {
|
|
4
4
|
access: 'public' | 'toolbox' | 'runtime';
|
|
5
5
|
plugin?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { pluginRecoverySignature } from '
|
|
2
|
-
import { loadPlugin, findPluginRegistration, invokeRegisteredPlugin, invokeRegisteredToolboxPlugin, invokeRegisteredRuntimePlugin, invokeRegisteredRecoveryPlugin, } from '
|
|
3
|
-
import { pluginFileVersion } from '
|
|
1
|
+
import { pluginRecoverySignature } from '../sdk/pluginRecoveryDefinition.js';
|
|
2
|
+
import { loadPlugin, findPluginRegistration, invokeRegisteredPlugin, invokeRegisteredToolboxPlugin, invokeRegisteredRuntimePlugin, invokeRegisteredRecoveryPlugin, } from '../sdk/plugin.js';
|
|
3
|
+
import { pluginFileVersion } from '../pluginSource.js';
|
|
4
4
|
import { MAX_PLUGIN_RESULT_BYTES, pluginExecutionError, serializePluginExecutionError, } from './pluginExecutorProtocol.js';
|
|
5
5
|
const controller = new AbortController();
|
|
6
6
|
const pending = new Map();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { PluginModelDiagnostic } from '
|
|
2
|
-
import type { PluginDiagnosticFailure, PluginDiagnosticOptions, PluginDiagnosticPage, PluginDiagnosticPageBinding, PluginDiagnosticReport } from '
|
|
1
|
+
import type { PluginModelDiagnostic } from '@mearl/browser-core';
|
|
2
|
+
import type { PluginDiagnosticFailure, PluginDiagnosticOptions, PluginDiagnosticPage, PluginDiagnosticPageBinding, PluginDiagnosticReport } from '@mearl/browser-core';
|
|
3
3
|
import type { PluginTaskRecord } from './pluginTaskStore.js';
|
|
4
|
-
import type { PluginTaskScope } from '
|
|
5
|
-
import type { PluginExecutionHost } from '
|
|
4
|
+
import type { PluginTaskScope } from '../pluginTaskProtocol.js';
|
|
5
|
+
import type { PluginExecutionHost } from '@mearl/browser-core';
|
|
6
6
|
export declare const MAX_PLUGIN_DIAGNOSTIC_BYTES: number;
|
|
7
7
|
export declare function normalizeDiagnosticOptions(value: unknown): PluginDiagnosticOptions;
|
|
8
8
|
export declare function diagnosticFailure(value: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isProcessOwnerAlive } from '@mearl/daemon-core';
|
|
2
2
|
import { basename } from 'node:path';
|
|
3
|
-
import { isPluginTaskId, PLUGIN_TASK_PROTOCOL_VERSION } from '
|
|
4
|
-
import { isPluginPageInstanceId } from '
|
|
3
|
+
import { isPluginTaskId, PLUGIN_TASK_PROTOCOL_VERSION } from '@mearl/browser-core';
|
|
4
|
+
import { isPluginPageInstanceId } from '@mearl/browser-core';
|
|
5
5
|
export const MAX_PLUGIN_DIAGNOSTIC_BYTES = 256 * 1024;
|
|
6
6
|
function text(value, maximum = 256) {
|
|
7
7
|
if (typeof value !== 'string')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { PluginExecutionHost, PluginInvocationIdentity, PluginInvocationSource } from '
|
|
2
|
-
import type { PluginApp } from '
|
|
3
|
-
import type { PluginTaskRecoveryContext } from '
|
|
1
|
+
import type { PluginExecutionHost, PluginInvocationIdentity, PluginInvocationSource } from '@mearl/browser-core';
|
|
2
|
+
import type { PluginApp } from '../sdk/plugin.js';
|
|
3
|
+
import type { PluginTaskRecoveryContext } from '@mearl/browser-core';
|
|
4
4
|
export type { PluginExecutionHost, PluginInvocationIdentity, PluginInvocationSource };
|
|
5
5
|
export interface PluginCommandContext extends Pick<PluginApp, 'invoke' | 'progress'> {
|
|
6
6
|
readonly identity: Readonly<PluginInvocationIdentity>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { linkSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { pluginDirectory } from '
|
|
4
|
+
import { pluginDirectory } from '../pluginRegistry.js';
|
|
5
5
|
const epoch = randomUUID();
|
|
6
6
|
const hostIds = new Map();
|
|
7
7
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { PluginModelDiagnostic, PluginModelRequest } from '
|
|
2
|
-
import { type PluginRegistration } from '
|
|
3
|
-
import type { PluginExecutionContext, PluginInvocation, PluginInvokeOptions } from '
|
|
1
|
+
import type { PluginModelDiagnostic, PluginModelRequest } from '@mearl/browser-core';
|
|
2
|
+
import { type PluginRegistration } from '../pluginRegistry.js';
|
|
3
|
+
import type { PluginExecutionContext, PluginInvocation, PluginInvokeOptions } from '../sdk/plugin.js';
|
|
4
4
|
export interface PluginExecutorDependencies {
|
|
5
5
|
stopProcessTree?: (pid: number) => Promise<void>;
|
|
6
6
|
registration?: PluginRegistration;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fork } from 'node:child_process';
|
|
2
|
-
import {
|
|
3
|
-
import { findPluginRegistration, PluginError } from '
|
|
4
|
-
import { pluginFileVersion } from '
|
|
2
|
+
import { PLUGIN_WORKER_PATH } from '../../runtimePaths.js';
|
|
3
|
+
import { findPluginRegistration, PluginError } from '../pluginRegistry.js';
|
|
4
|
+
import { pluginFileVersion } from '../pluginSource.js';
|
|
5
5
|
import { createPluginInvocationIdentity } from './pluginExecution.js';
|
|
6
6
|
import { pluginExecutionError, serializePluginExecutionError } from './pluginExecutorProtocol.js';
|
|
7
7
|
import { stopPluginProcessTree } from './pluginProcessTree.js';
|
|
@@ -24,7 +24,7 @@ export async function executeRegisteredPlugin(plugin, invocation, context, optio
|
|
|
24
24
|
createPluginInvocationIdentity(plugin, source ?? context.source ?? 'sdk', context.parentInvocation);
|
|
25
25
|
const entryVersion = pluginFileVersion(registration.entry);
|
|
26
26
|
return new Promise((resolve, reject) => {
|
|
27
|
-
const child = fork(workerPath ??
|
|
27
|
+
const child = fork(workerPath ?? PLUGIN_WORKER_PATH, [], {
|
|
28
28
|
stdio: ['ignore', 'ignore', 'pipe', 'ipc'],
|
|
29
29
|
serialization: 'advanced',
|
|
30
30
|
execArgv: [],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { PluginModelDiagnostic, PluginModelRequest } from '
|
|
2
|
-
import type { PluginInvocationIdentity, PluginExecutionError } from '
|
|
3
|
-
import type { PluginInvocation, PluginOptions, PluginProgress } from '
|
|
4
|
-
import type { PluginRegistration } from '
|
|
1
|
+
import type { PluginModelDiagnostic, PluginModelRequest } from '@mearl/browser-core';
|
|
2
|
+
import type { PluginInvocationIdentity, PluginExecutionError } from '@mearl/browser-core';
|
|
3
|
+
import type { PluginInvocation, PluginOptions, PluginProgress } from '../sdk/plugin.js';
|
|
4
|
+
import type { PluginRegistration } from '../pluginRegistry.js';
|
|
5
5
|
export type PluginWorkerRequest = {
|
|
6
6
|
type: 'start';
|
|
7
7
|
plugin: string;
|
|
@@ -4,8 +4,8 @@ import { PluginStateManager } from './pluginStateManager.js';
|
|
|
4
4
|
import { PluginPageManager } from './pluginPageManager.js';
|
|
5
5
|
import { PluginModelCatalog } from './pluginModelCatalog.js';
|
|
6
6
|
import { PluginModelSessions } from './pluginModelSessions.js';
|
|
7
|
-
import type { PluginDiagnosticOptions } from '
|
|
8
|
-
import type { PluginTaskScope } from '
|
|
7
|
+
import type { PluginDiagnosticOptions } from '@mearl/browser-core';
|
|
8
|
+
import type { PluginTaskScope } from '../pluginTaskProtocol.js';
|
|
9
9
|
/** The host owns service composition; task execution receives explicit service dependencies. */
|
|
10
10
|
export declare class PluginHost {
|
|
11
11
|
readonly tasks: PluginTaskManager;
|
|
@@ -15,6 +15,6 @@ export declare class PluginHost {
|
|
|
15
15
|
readonly modelSessions: PluginModelSessions;
|
|
16
16
|
private closing?;
|
|
17
17
|
constructor(configuration?: PluginTaskManagerOptions);
|
|
18
|
-
diagnose(value: PluginDiagnosticOptions, scope: PluginTaskScope): import("
|
|
18
|
+
diagnose(value: PluginDiagnosticOptions, scope: PluginTaskScope): import("@mearl/browser-core").PluginDiagnosticReport;
|
|
19
19
|
close(): Promise<void>;
|
|
20
20
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { pluginDirectory } from '
|
|
4
|
+
import { pluginDirectory } from '../pluginRegistry.js';
|
|
5
5
|
export function pluginHostPaths() {
|
|
6
6
|
const registry = pluginDirectory();
|
|
7
7
|
const key = createHash('sha256').update(registry).digest('hex').slice(0, 16);
|
|
@@ -2,10 +2,10 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { createServer } from 'node:net';
|
|
3
3
|
import { chmodSync, rmSync } from 'node:fs';
|
|
4
4
|
import { claimRecord, isProcessOwnerAlive, processIdentity, readRecord, removeInvalidRecord, removeRecordIfPid, writeRecordIfPid, } from '@mearl/daemon-core';
|
|
5
|
-
import { PLUGIN_TASK_PROTOCOL_VERSION } from '
|
|
5
|
+
import { PLUGIN_TASK_PROTOCOL_VERSION } from '@mearl/browser-core';
|
|
6
6
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
7
7
|
import { PluginHost } from './pluginHost.js';
|
|
8
|
-
import { readPluginTaskMessages, writePluginTaskMessage } from '
|
|
8
|
+
import { readPluginTaskMessages, writePluginTaskMessage } from '../pluginTaskWire.js';
|
|
9
9
|
import { pluginExecutionError, serializePluginExecutionError } from './pluginExecutorProtocol.js';
|
|
10
10
|
export async function startPluginHostServer(configuration = {}) {
|
|
11
11
|
const paths = pluginHostPaths();
|
|
@@ -122,7 +122,7 @@ export async function startPluginHostServer(configuration = {}) {
|
|
|
122
122
|
if (method === 'model.list')
|
|
123
123
|
return models.list(input.provider);
|
|
124
124
|
if (method === 'model.capabilities')
|
|
125
|
-
return (await import('
|
|
125
|
+
return (await import('../sdk/pluginModelDefinition.js')).pluginModelCapabilities();
|
|
126
126
|
if (method === 'page.call') {
|
|
127
127
|
const execution = input.execution;
|
|
128
128
|
return pages.call(String(input.plugin), input.input, bridge, input.options, execution
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PluginModelList, PluginModelOption } from '
|
|
1
|
+
import type { PluginModelList, PluginModelOption } from '@mearl/browser-core';
|
|
2
2
|
/** A bounded shared lookup avoids starting a discovery process for each open tool. */
|
|
3
3
|
export declare class PluginModelCatalog {
|
|
4
4
|
private readonly discover;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { fork } from 'node:child_process';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import {
|
|
3
|
+
import { PLUGIN_MODEL_SESSION_WORKER_PATH } from '../../runtimePaths.js';
|
|
4
4
|
import { processIdentity } from '@mearl/daemon-core';
|
|
5
5
|
import { pluginExecutionError } from './pluginExecutorProtocol.js';
|
|
6
6
|
import { stopPluginProcessTree } from './pluginProcessTree.js';
|
|
7
|
-
import { validatePluginModelResult } from '
|
|
7
|
+
import { validatePluginModelResult } from '../sdk/pluginModelDefinition.js';
|
|
8
8
|
/** Opt-in conversations retain a supervised process and thread within one execution owner. */
|
|
9
9
|
export class PluginModelSessions {
|
|
10
10
|
idleMs;
|
|
@@ -13,7 +13,7 @@ export class PluginModelSessions {
|
|
|
13
13
|
sessions = new Map();
|
|
14
14
|
closing = new Set();
|
|
15
15
|
closed = false;
|
|
16
|
-
constructor(idleMs = 5 * 60_000, limit = 2, workerPath =
|
|
16
|
+
constructor(idleMs = 5 * 60_000, limit = 2, workerPath = PLUGIN_MODEL_SESSION_WORKER_PATH) {
|
|
17
17
|
this.idleMs = idleMs;
|
|
18
18
|
this.limit = limit;
|
|
19
19
|
this.workerPath = workerPath;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { PluginDiagnosticPage } from '
|
|
1
|
+
import type { PluginDiagnosticPage } from '@mearl/browser-core';
|
|
2
2
|
import type { PluginStateManager } from './pluginStateManager.js';
|
|
3
|
-
import type { PluginInvocationIdentity } from '
|
|
3
|
+
import type { PluginInvocationIdentity } from '@mearl/browser-core';
|
|
4
4
|
import type { PluginRevision } from './pluginRevision.js';
|
|
5
|
-
import type { PluginOptions } from '
|
|
6
|
-
import type { PluginPageTarget } from '
|
|
5
|
+
import type { PluginOptions } from '../sdk/plugin.js';
|
|
6
|
+
import type { PluginPageTarget } from '@mearl/browser-core';
|
|
7
7
|
import type { PluginTaskBridge, PluginTaskManager } from './pluginTaskManager.js';
|
|
8
8
|
interface Execution {
|
|
9
9
|
cwd: string;
|
|
@@ -4,13 +4,13 @@ import { EventEmitter } from 'node:events';
|
|
|
4
4
|
import { readFileSync, statSync } from 'node:fs';
|
|
5
5
|
import { isAbsolute, join } from 'node:path';
|
|
6
6
|
import { capturePluginRevision } from './pluginRevision.js';
|
|
7
|
-
import { findPluginRegistration } from '
|
|
8
|
-
import { compilePluginPageSchema } from '
|
|
9
|
-
import { UnifiedClient, decodeBrowserTarget } from '
|
|
7
|
+
import { findPluginRegistration } from '../sdk/plugin.js';
|
|
8
|
+
import { compilePluginPageSchema } from '../sdk/pluginPageDefinition.js';
|
|
9
|
+
import { UnifiedClient, decodeBrowserTarget } from '../../unified.js';
|
|
10
10
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
11
11
|
import { serializePluginExecutionError, pluginExecutionError } from './pluginExecutorProtocol.js';
|
|
12
|
-
import { isPluginTaskActive } from '
|
|
13
|
-
import { isPluginPageInstanceId, matchesPluginPageURL, isPluginPageInvalidation, isPluginPageUnavailable, pluginPageUnavailable, PLUGIN_PAGE_LEASE_MS, } from '
|
|
12
|
+
import { isPluginTaskActive } from '@mearl/browser-core';
|
|
13
|
+
import { isPluginPageInstanceId, matchesPluginPageURL, isPluginPageInvalidation, isPluginPageUnavailable, pluginPageUnavailable, PLUGIN_PAGE_LEASE_MS, } from '@mearl/browser-core';
|
|
14
14
|
function failure(code, message) {
|
|
15
15
|
return Object.assign(new Error(message), { code });
|
|
16
16
|
}
|
|
@@ -5,7 +5,8 @@ import { claimRecord, readRecord, writeRecord } from '@mearl/daemon-core';
|
|
|
5
5
|
import { isBuiltin } from 'node:module';
|
|
6
6
|
import { parse } from 'acorn';
|
|
7
7
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
8
|
-
import {
|
|
8
|
+
import { skillManifestPath } from '../skillManifest.js';
|
|
9
|
+
import { findPluginRegistration, PluginError } from '../pluginRegistry.js';
|
|
9
10
|
const MAX_REVISION_BYTES = 64 * 1024 * 1024;
|
|
10
11
|
const validatedSources = new Set();
|
|
11
12
|
function within(root, file) {
|
|
@@ -15,7 +16,7 @@ function within(root, file) {
|
|
|
15
16
|
function sourceRoot(entry) {
|
|
16
17
|
let candidate = dirname(entry);
|
|
17
18
|
for (let depth = 0; depth < 6; depth++) {
|
|
18
|
-
if (
|
|
19
|
+
if (skillManifestPath(candidate))
|
|
19
20
|
return candidate;
|
|
20
21
|
const parent = dirname(candidate);
|
|
21
22
|
if (parent === candidate)
|
|
@@ -2,8 +2,8 @@ import { rmSync } from 'node:fs';
|
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { claimRecord, isProcessOwnerAlive, processIdentity, readRecord, removeInvalidRecord, removeRecordIfPid, } from '@mearl/daemon-core';
|
|
4
4
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
5
|
-
import { listPluginNames } from '
|
|
6
|
-
import { PluginTaskClient } from '
|
|
5
|
+
import { listPluginNames } from '../pluginRegistry.js';
|
|
6
|
+
import { PluginTaskClient } from '../clients/pluginTasks.js';
|
|
7
7
|
import { PluginTaskStore, pluginTaskExecutionUnconfirmed } from './pluginTaskStore.js';
|
|
8
8
|
/** Complete uninstall discards execution caches after every plugin has been removed. */
|
|
9
9
|
export async function cleanupPluginRuntime() {
|