@mearl/client 2.21.0 → 2.22.1
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 +52 -8
- package/dist/actionTimeouts.js +1 -1
- package/dist/artifacts.d.ts +1 -1
- package/dist/browserRegistry.d.ts +1 -1
- package/dist/check.d.ts +1 -1
- package/dist/cli.js +4 -3
- package/dist/commands.d.ts +12 -12
- package/dist/commands.js +6 -4
- package/dist/{generated-app-profile-definition.d.ts → generated/app-profile-definition.d.ts} +2 -2
- package/dist/{generated-app-profile-runtime-types.d.ts → generated/app-profile-runtime-types.d.ts} +2 -2
- package/dist/{generated-browser-action-protocol.d.ts → generated/browser-action-protocol.d.ts} +1 -1
- package/dist/{generated-plugin-diagnostics.d.ts → generated/plugin-diagnostics.d.ts} +4 -4
- package/dist/{generated-plugin-execution.d.ts → generated/plugin-execution.d.ts} +2 -2
- package/dist/generated/plugin-host-build.d.ts +1 -0
- package/dist/generated/plugin-host-build.js +2 -0
- package/dist/{generated-plugin-pages.d.ts → generated/plugin-pages.d.ts} +1 -1
- package/dist/{generated-plugin-tasks.d.ts → generated/plugin-tasks.d.ts} +2 -2
- package/dist/index.d.ts +15 -15
- package/dist/index.js +7 -7
- 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} +4 -2
- package/dist/{pluginHostConnection.js → plugins/clients/pluginHostConnection.js} +9 -8
- 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/{officialPluginInstaller.js → plugins/officialPluginInstaller.js} +1 -3
- package/dist/{pluginRegistry.d.ts → plugins/pluginRegistry.d.ts} +2 -2
- package/dist/{pluginRegistry.js → plugins/pluginRegistry.js} +14 -7
- 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} +11 -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} +4 -8
- package/dist/{pluginRevision.d.ts → plugins/runtime/pluginRevision.d.ts} +1 -1
- package/dist/{pluginRevision.js → plugins/runtime/pluginRevision.js} +3 -53
- 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} +3 -8
- package/dist/{pluginTaskManager.d.ts → plugins/runtime/pluginTaskManager.d.ts} +12 -12
- package/dist/{pluginTaskManager.js → plugins/runtime/pluginTaskManager.js} +8 -12
- 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 +118 -0
- package/dist/plugins/sdk/plugin.js +676 -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/{pluginModelDefinition.js → plugins/sdk/pluginModelDefinition.js} +0 -6
- package/dist/plugins/sdk/pluginPageDefinition.d.ts +2 -0
- package/dist/{pluginPageDefinition.js → plugins/sdk/pluginPageDefinition.js} +3 -19
- package/dist/{pluginRecoveryDefinition.d.ts → plugins/sdk/pluginRecoveryDefinition.d.ts} +1 -1
- package/dist/{pluginRecoveryDefinition.js → plugins/sdk/pluginRecoveryDefinition.js} +0 -3
- package/dist/plugins/sdk/pluginStateDefinition.d.ts +3 -0
- package/dist/{pluginStateDefinition.js → plugins/sdk/pluginStateDefinition.js} +0 -11
- package/dist/plugins/skillManifest.d.ts +5 -0
- package/dist/plugins/skillManifest.js +35 -0
- package/dist/runtimePaths.d.ts +4 -0
- package/dist/runtimePaths.js +8 -0
- package/dist/socket.d.ts +2 -2
- package/dist/socket.js +5 -4
- package/dist/unified.d.ts +2 -2
- package/dist/unified.js +7 -7
- package/package.json +6 -8
- package/dist/pluginPageDefinition.d.ts +0 -3
- package/dist/pluginStateDefinition.d.ts +0 -4
- /package/dist/{generated-app-profile-definition.js → generated/app-profile-definition.js} +0 -0
- /package/dist/{generated-app-profile-runtime-types.js → generated/app-profile-runtime-types.js} +0 -0
- /package/dist/{generated-browser-action-protocol.js → generated/browser-action-protocol.js} +0 -0
- /package/dist/{generated-plugin-diagnostics.js → generated/plugin-diagnostics.js} +0 -0
- /package/dist/{generated-plugin-execution.js → generated/plugin-execution.js} +0 -0
- /package/dist/{generated-plugin-models.d.ts → generated/plugin-models.d.ts} +0 -0
- /package/dist/{generated-plugin-models.js → generated/plugin-models.js} +0 -0
- /package/dist/{generated-plugin-pages.js → generated/plugin-pages.js} +0 -0
- /package/dist/{generated-plugin-recovery.d.ts → generated/plugin-recovery.d.ts} +0 -0
- /package/dist/{generated-plugin-recovery.js → generated/plugin-recovery.js} +0 -0
- /package/dist/{generated-plugin-state.d.ts → generated/plugin-state.d.ts} +0 -0
- /package/dist/{generated-plugin-state.js → generated/plugin-state.js} +0 -0
- /package/dist/{generated-plugin-tasks.js → generated/plugin-tasks.js} +0 -0
- /package/dist/{generated-toolbox-icon.d.ts → generated/toolbox-icon.d.ts} +0 -0
- /package/dist/{generated-toolbox-icon.js → generated/toolbox-icon.js} +0 -0
- /package/dist/{pluginModels.js → plugins/clients/pluginModels.js} +0 -0
- /package/dist/{pluginState.js → plugins/clients/pluginState.js} +0 -0
- /package/dist/{officialPluginCatalog.d.ts → plugins/officialPluginCatalog.d.ts} +0 -0
- /package/dist/{officialPluginCatalog.js → plugins/officialPluginCatalog.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
|
@@ -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 '../../generated/plugin-execution.js';
|
|
2
|
+
import type { PluginExecutionContext } from '../sdk/plugin.js';
|
|
3
3
|
export interface PluginHostConnectionOptions {
|
|
4
4
|
source?: PluginInvocationSource;
|
|
5
5
|
plugin?: string;
|
|
@@ -16,6 +16,8 @@ export interface PluginHostClientOptions extends PluginHostConnectionOptions {
|
|
|
16
16
|
}
|
|
17
17
|
export interface HostStatus {
|
|
18
18
|
protocolVersion: number;
|
|
19
|
+
version?: string;
|
|
20
|
+
buildId?: string;
|
|
19
21
|
host: PluginExecutionHost;
|
|
20
22
|
pid: number;
|
|
21
23
|
}
|
|
@@ -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 '../../generated/plugin-tasks.js';
|
|
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 {
|
|
@@ -244,7 +243,9 @@ export class PluginHostConnection {
|
|
|
244
243
|
this.connection = undefined;
|
|
245
244
|
});
|
|
246
245
|
}
|
|
247
|
-
|
|
246
|
+
const connection = await this.connection;
|
|
247
|
+
// The handshake protocol defines compatibility; build identity is diagnostic metadata.
|
|
248
|
+
return connection.request(method, input, timeoutMs);
|
|
248
249
|
}
|
|
249
250
|
disconnect() {
|
|
250
251
|
this.generation++;
|
|
@@ -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 '../../generated/plugin-models.js';
|
|
5
|
+
import type { PluginTaskStartResult } from '../../generated/plugin-tasks.js';
|
|
6
|
+
export type * from '../../generated/plugin-models.js';
|
|
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 '../../generated/plugin-pages.js';
|
|
4
|
+
export type { PluginPageInstance, PluginPageEvents, PluginPageRuntime, PluginPageActivation, PluginPageTarget, PluginPageOperation, } from '../../generated/plugin-pages.js';
|
|
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 '../../generated/plugin-state.js';
|
|
5
|
+
export type * from '../../generated/plugin-state.js';
|
|
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 '../../generated/plugin-recovery.js';
|
|
4
|
+
import type { PluginDiagnosticOptions, PluginDiagnosticReport } from '../../generated/plugin-diagnostics.js';
|
|
5
|
+
import type { PluginTask, PluginTaskEvents, PluginTaskListResult, PluginTaskResultChunk, PluginTaskStartResult } from '../../generated/plugin-tasks.js';
|
|
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 '../../generated/plugin-tasks.js';
|
|
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 = () => {
|
|
@@ -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
5
|
import { findOfficialPlugin } 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;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type AppProfileContribution } from '
|
|
1
|
+
import { type AppProfileContribution } from '../generated/app-profile-definition.js';
|
|
2
2
|
export declare class PluginError extends Error {
|
|
3
3
|
readonly code: string;
|
|
4
|
-
constructor(code: string, message: string);
|
|
4
|
+
constructor(code: string, message: string, options?: ErrorOptions);
|
|
5
5
|
}
|
|
6
6
|
export interface PluginToolboxSandboxPage {
|
|
7
7
|
type: 'sandbox';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { validateAppProfileContribution, } from '
|
|
1
|
+
import { validateAppProfileContribution, } from '../generated/app-profile-definition.js';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { parseToolboxIcon } from '
|
|
3
|
+
import { parseToolboxIcon } from '../generated/toolbox-icon.js';
|
|
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([
|
|
@@ -17,8 +17,8 @@ const RESERVED_NAMES = new Set([
|
|
|
17
17
|
]);
|
|
18
18
|
export class PluginError extends Error {
|
|
19
19
|
code;
|
|
20
|
-
constructor(code, message) {
|
|
21
|
-
super(`${code}: ${message}
|
|
20
|
+
constructor(code, message, options) {
|
|
21
|
+
super(`${code}: ${message}`, options);
|
|
22
22
|
this.code = code;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -405,8 +405,15 @@ export function findPluginRegistration(name) {
|
|
|
405
405
|
...(source ? { source } : {}),
|
|
406
406
|
};
|
|
407
407
|
}
|
|
408
|
-
catch {
|
|
409
|
-
|
|
408
|
+
catch (cause) {
|
|
409
|
+
const reason = cause instanceof SyntaxError
|
|
410
|
+
? 'JSON 格式错误'
|
|
411
|
+
: cause instanceof Error
|
|
412
|
+
? cause.message
|
|
413
|
+
: '未知校验错误';
|
|
414
|
+
throw new PluginError('PLUGIN_REGISTRY_INVALID', `无效的插件记录: ${file} (${reason})`, {
|
|
415
|
+
cause,
|
|
416
|
+
});
|
|
410
417
|
}
|
|
411
418
|
}
|
|
412
419
|
export function readPluginPageBundleChunk(name, hash, index) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PluginExecutionError, PluginInvocationSource } from '
|
|
2
|
-
import type { PluginOptions } from './plugin.js';
|
|
1
|
+
import type { PluginExecutionError, PluginInvocationSource } from '../generated/plugin-execution.js';
|
|
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 '../../generated/plugin-models.js';
|
|
2
|
+
import type { PluginDiagnosticFailure, PluginDiagnosticOptions, PluginDiagnosticPage, PluginDiagnosticPageBinding, PluginDiagnosticReport } from '../../generated/plugin-diagnostics.js';
|
|
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 '../../generated/plugin-execution.js';
|
|
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 '../../generated/plugin-tasks.js';
|
|
4
|
+
import { isPluginPageInstanceId } from '../../generated/plugin-pages.js';
|
|
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 '../../generated/plugin-execution.js';
|
|
2
|
+
import type { PluginApp } from '../sdk/plugin.js';
|
|
3
|
+
import type { PluginTaskRecoveryContext } from '../../generated/plugin-recovery.js';
|
|
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 '../../generated/plugin-models.js';
|
|
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 '../../generated/plugin-models.js';
|
|
2
|
+
import type { PluginInvocationIdentity, PluginExecutionError } from '../../generated/plugin-execution.js';
|
|
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 '../../generated/plugin-diagnostics.js';
|
|
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("../../generated/plugin-diagnostics.js").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);
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { CLIENT_VERSION } from '../../runtimePaths.js';
|
|
2
|
+
import { PLUGIN_HOST_BUILD_ID } from '../../generated/plugin-host-build.js';
|
|
1
3
|
import { randomUUID } from 'node:crypto';
|
|
2
4
|
import { createServer } from 'node:net';
|
|
3
5
|
import { chmodSync, rmSync } from 'node:fs';
|
|
4
6
|
import { claimRecord, isProcessOwnerAlive, processIdentity, readRecord, removeInvalidRecord, removeRecordIfPid, writeRecordIfPid, } from '@mearl/daemon-core';
|
|
5
|
-
import { PLUGIN_TASK_PROTOCOL_VERSION } from '
|
|
7
|
+
import { PLUGIN_TASK_PROTOCOL_VERSION } from '../../generated/plugin-tasks.js';
|
|
6
8
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
7
9
|
import { PluginHost } from './pluginHost.js';
|
|
8
|
-
import { readPluginTaskMessages, writePluginTaskMessage } from '
|
|
10
|
+
import { readPluginTaskMessages, writePluginTaskMessage } from '../pluginTaskWire.js';
|
|
9
11
|
import { pluginExecutionError, serializePluginExecutionError } from './pluginExecutorProtocol.js';
|
|
10
12
|
export async function startPluginHostServer(configuration = {}) {
|
|
11
13
|
const paths = pluginHostPaths();
|
|
@@ -17,6 +19,8 @@ export async function startPluginHostServer(configuration = {}) {
|
|
|
17
19
|
const owner = {
|
|
18
20
|
pid: process.pid,
|
|
19
21
|
protocolVersion: PLUGIN_TASK_PROTOCOL_VERSION,
|
|
22
|
+
version: CLIENT_VERSION,
|
|
23
|
+
buildId: PLUGIN_HOST_BUILD_ID,
|
|
20
24
|
processIdentity: processIdentity(process.pid),
|
|
21
25
|
};
|
|
22
26
|
if (!claimRecord(paths.lease, owner))
|
|
@@ -103,6 +107,8 @@ export async function startPluginHostServer(configuration = {}) {
|
|
|
103
107
|
};
|
|
104
108
|
return {
|
|
105
109
|
protocolVersion: PLUGIN_TASK_PROTOCOL_VERSION,
|
|
110
|
+
version: CLIENT_VERSION,
|
|
111
|
+
buildId: PLUGIN_HOST_BUILD_ID,
|
|
106
112
|
host: manager.host,
|
|
107
113
|
pid: process.pid,
|
|
108
114
|
};
|
|
@@ -112,6 +118,8 @@ export async function startPluginHostServer(configuration = {}) {
|
|
|
112
118
|
if (method === 'status')
|
|
113
119
|
return {
|
|
114
120
|
protocolVersion: PLUGIN_TASK_PROTOCOL_VERSION,
|
|
121
|
+
version: CLIENT_VERSION,
|
|
122
|
+
buildId: PLUGIN_HOST_BUILD_ID,
|
|
115
123
|
host: manager.host,
|
|
116
124
|
pid: process.pid,
|
|
117
125
|
};
|
|
@@ -122,7 +130,7 @@ export async function startPluginHostServer(configuration = {}) {
|
|
|
122
130
|
if (method === 'model.list')
|
|
123
131
|
return models.list(input.provider);
|
|
124
132
|
if (method === 'model.capabilities')
|
|
125
|
-
return (await import('
|
|
133
|
+
return (await import('../sdk/pluginModelDefinition.js')).pluginModelCapabilities();
|
|
126
134
|
if (method === 'page.call') {
|
|
127
135
|
const execution = input.execution;
|
|
128
136
|
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 '../../generated/plugin-models.js';
|
|
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 '../../generated/plugin-diagnostics.js';
|
|
2
2
|
import type { PluginStateManager } from './pluginStateManager.js';
|
|
3
|
-
import type { PluginInvocationIdentity } from '
|
|
3
|
+
import type { PluginInvocationIdentity } from '../../generated/plugin-execution.js';
|
|
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 '../../generated/plugin-pages.js';
|
|
7
7
|
import type { PluginTaskBridge, PluginTaskManager } from './pluginTaskManager.js';
|
|
8
8
|
interface Execution {
|
|
9
9
|
cwd: string;
|
|
@@ -4,13 +4,12 @@ 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 {
|
|
9
|
-
import { UnifiedClient, decodeBrowserTarget } from './unified.js';
|
|
7
|
+
import { findPluginRegistration } from '../sdk/plugin.js';
|
|
8
|
+
import { UnifiedClient, decodeBrowserTarget } from '../../unified.js';
|
|
10
9
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
11
10
|
import { serializePluginExecutionError, pluginExecutionError } from './pluginExecutorProtocol.js';
|
|
12
|
-
import { isPluginTaskActive } from '
|
|
13
|
-
import { isPluginPageInstanceId, matchesPluginPageURL, isPluginPageInvalidation, isPluginPageUnavailable, pluginPageUnavailable, PLUGIN_PAGE_LEASE_MS, } from '
|
|
11
|
+
import { isPluginTaskActive } from '../../generated/plugin-tasks.js';
|
|
12
|
+
import { isPluginPageInstanceId, matchesPluginPageURL, isPluginPageInvalidation, isPluginPageUnavailable, pluginPageUnavailable, PLUGIN_PAGE_LEASE_MS, } from '../../generated/plugin-pages.js';
|
|
14
13
|
function failure(code, message) {
|
|
15
14
|
return Object.assign(new Error(message), { code });
|
|
16
15
|
}
|
|
@@ -726,9 +725,6 @@ export class PluginPageManager {
|
|
|
726
725
|
const binding = record.runtime.events?.[name];
|
|
727
726
|
if (!binding || Buffer.byteLength(JSON.stringify(input.payload ?? null)) > 32 * 1024)
|
|
728
727
|
throw new Error('Page event is not declared or exceeds 32 KiB');
|
|
729
|
-
const validate = compilePluginPageSchema(binding.schema);
|
|
730
|
-
if (!validate(input.payload))
|
|
731
|
-
throw failure('PLUGIN_PAGE_EVENT_INVALID', 'Page event payload does not match its schema');
|
|
732
728
|
const waiting = record.deliveries.filter(item => item.name === name && item.state === 'queued');
|
|
733
729
|
if (binding.policy === 'latest') {
|
|
734
730
|
for (const previous of waiting) {
|
|
@@ -2,12 +2,10 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
3
3
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
4
|
import { claimRecord, readRecord, writeRecord } from '@mearl/daemon-core';
|
|
5
|
-
import { isBuiltin } from 'node:module';
|
|
6
|
-
import { parse } from 'acorn';
|
|
7
5
|
import { pluginHostPaths } from './pluginHostPaths.js';
|
|
8
|
-
import {
|
|
6
|
+
import { skillManifestPath } from '../skillManifest.js';
|
|
7
|
+
import { findPluginRegistration, PluginError } from '../pluginRegistry.js';
|
|
9
8
|
const MAX_REVISION_BYTES = 64 * 1024 * 1024;
|
|
10
|
-
const validatedSources = new Set();
|
|
11
9
|
function within(root, file) {
|
|
12
10
|
const path = relative(root, file);
|
|
13
11
|
return path === '' || (!path.startsWith(`..${sep}`) && path !== '..' && !isAbsolute(path));
|
|
@@ -15,7 +13,7 @@ function within(root, file) {
|
|
|
15
13
|
function sourceRoot(entry) {
|
|
16
14
|
let candidate = dirname(entry);
|
|
17
15
|
for (let depth = 0; depth < 6; depth++) {
|
|
18
|
-
if (
|
|
16
|
+
if (skillManifestPath(candidate))
|
|
19
17
|
return candidate;
|
|
20
18
|
const parent = dirname(candidate);
|
|
21
19
|
if (parent === candidate)
|
|
@@ -67,48 +65,6 @@ function readSources(root) {
|
|
|
67
65
|
visit(root, new Set());
|
|
68
66
|
return files;
|
|
69
67
|
}
|
|
70
|
-
function validateDependencies(files) {
|
|
71
|
-
const paths = new Set(files.map(file => file.path));
|
|
72
|
-
for (const file of files) {
|
|
73
|
-
if (!/\.[cm]?js$/.test(file.path))
|
|
74
|
-
continue;
|
|
75
|
-
const tree = parse(file.bytes.toString('utf8'), {
|
|
76
|
-
ecmaVersion: 'latest',
|
|
77
|
-
sourceType: 'module',
|
|
78
|
-
allowReturnOutsideFunction: true,
|
|
79
|
-
});
|
|
80
|
-
const check = (specifier) => {
|
|
81
|
-
if (typeof specifier !== 'string' || isBuiltin(specifier))
|
|
82
|
-
return;
|
|
83
|
-
if (!specifier.startsWith('./') && !specifier.startsWith('../'))
|
|
84
|
-
throw new PluginError('PLUGIN_SOURCE_NOT_SELF_CONTAINED', `后台任务需要自包含 Skill,请先打包依赖: ${file.path}: ${specifier}`);
|
|
85
|
-
const local = resolve('/source', dirname(file.path), specifier);
|
|
86
|
-
const normalized = relative('/source', local).split(sep).join('/');
|
|
87
|
-
if (!within('/source', local) ||
|
|
88
|
-
![normalized, `${normalized}.js`, `${normalized}.json`, `${normalized}/index.js`].some(path => paths.has(path)))
|
|
89
|
-
throw new PluginError('PLUGIN_SOURCE_NOT_SELF_CONTAINED', `依赖不在 Skill 快照中: ${file.path}: ${specifier}`);
|
|
90
|
-
};
|
|
91
|
-
const visit = (node) => {
|
|
92
|
-
if (!node || typeof node !== 'object')
|
|
93
|
-
return;
|
|
94
|
-
if (['ImportDeclaration', 'ExportNamedDeclaration', 'ExportAllDeclaration'].includes(node.type))
|
|
95
|
-
check(node.source?.value);
|
|
96
|
-
if (node.type === 'ImportExpression')
|
|
97
|
-
check(node.source?.value);
|
|
98
|
-
if (node.type === 'CallExpression' &&
|
|
99
|
-
node.callee?.type === 'Identifier' &&
|
|
100
|
-
node.callee.name === 'require')
|
|
101
|
-
check(node.arguments[0]?.value);
|
|
102
|
-
for (const value of Object.values(node)) {
|
|
103
|
-
if (Array.isArray(value))
|
|
104
|
-
value.forEach(visit);
|
|
105
|
-
else if (value && typeof value === 'object')
|
|
106
|
-
visit(value);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
visit(tree);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
68
|
function fingerprint(files, entry) {
|
|
113
69
|
return createHash('sha256')
|
|
114
70
|
.update(JSON.stringify({ entry, files: files.map(file => [file.path, file.hash, file.executable]) }))
|
|
@@ -138,12 +94,6 @@ export function capturePluginRevision(plugin) {
|
|
|
138
94
|
const relativeEntry = relative(root, entry).split(sep).join('/');
|
|
139
95
|
const files = readSources(root);
|
|
140
96
|
const revision = fingerprint(files, relativeEntry);
|
|
141
|
-
if (!validatedSources.has(revision)) {
|
|
142
|
-
validateDependencies(files);
|
|
143
|
-
if (validatedSources.size >= 64)
|
|
144
|
-
validatedSources.delete(validatedSources.values().next().value);
|
|
145
|
-
validatedSources.add(revision);
|
|
146
|
-
}
|
|
147
97
|
const revisionRoot = join(paths.revisions, installation.installationId, revision);
|
|
148
98
|
if (!existsSync(revisionRoot)) {
|
|
149
99
|
const temporary = `${revisionRoot}.${randomUUID()}.tmp`;
|
|
@@ -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() {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { PluginRevision } from './pluginRevision.js';
|
|
2
2
|
import { PluginStateStore } from './pluginStateStore.js';
|
|
3
3
|
import type { PluginTaskManager, PluginTaskBridge } from './pluginTaskManager.js';
|
|
4
|
-
import type { PluginOptions } from '
|
|
5
|
-
import type { PluginPageTarget } from '
|
|
4
|
+
import type { PluginOptions } from '../sdk/plugin.js';
|
|
5
|
+
import type { PluginPageTarget } from '../../generated/plugin-pages.js';
|
|
6
6
|
export declare class PluginStateManager {
|
|
7
7
|
private readonly tasks;
|
|
8
8
|
readonly store: PluginStateStore;
|