@nextclaw/openclaw-compat 0.3.35 → 0.3.36
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/dist/index.d.ts +64 -44
- package/dist/index.js +595 -50
- package/package.json +14 -14
package/dist/index.d.ts
CHANGED
|
@@ -659,6 +659,69 @@ declare function installPluginFromPath(params: {
|
|
|
659
659
|
|
|
660
660
|
declare function buildPluginLoaderAliases(pluginRoot?: string): Record<string, string>;
|
|
661
661
|
|
|
662
|
+
type PluginRegisterRuntime = {
|
|
663
|
+
config: Config;
|
|
664
|
+
workspaceDir: string;
|
|
665
|
+
logger: PluginLogger;
|
|
666
|
+
registry: PluginRegistry;
|
|
667
|
+
toolNameOwners: Map<string, string>;
|
|
668
|
+
channelIdOwners: Map<string, string>;
|
|
669
|
+
providerIdOwners: Map<string, string>;
|
|
670
|
+
engineKindOwners: Map<string, string>;
|
|
671
|
+
ncpAgentRuntimeKindOwners: Map<string, string>;
|
|
672
|
+
resolvedToolNames: Set<string>;
|
|
673
|
+
reservedToolNames: Set<string>;
|
|
674
|
+
reservedChannelIds: Set<string>;
|
|
675
|
+
reservedProviderIds: Set<string>;
|
|
676
|
+
reservedEngineKinds: Set<string>;
|
|
677
|
+
reservedNcpAgentRuntimeKinds: Set<string>;
|
|
678
|
+
};
|
|
679
|
+
declare function createPluginRegisterRuntime(params: {
|
|
680
|
+
config: Config;
|
|
681
|
+
workspaceDir: string;
|
|
682
|
+
logger: PluginLogger;
|
|
683
|
+
registry: PluginRegistry;
|
|
684
|
+
reservedToolNames: Set<string>;
|
|
685
|
+
reservedChannelIds: Set<string>;
|
|
686
|
+
reservedProviderIds: Set<string>;
|
|
687
|
+
reservedEngineKinds: Set<string>;
|
|
688
|
+
reservedNcpAgentRuntimeKinds: Set<string>;
|
|
689
|
+
}): PluginRegisterRuntime;
|
|
690
|
+
declare function registerPluginWithApi(params: {
|
|
691
|
+
runtime: PluginRegisterRuntime;
|
|
692
|
+
record: PluginRecord;
|
|
693
|
+
pluginId: string;
|
|
694
|
+
source: string;
|
|
695
|
+
rootDir: string;
|
|
696
|
+
register: (api: OpenClawPluginApi) => void | Promise<void>;
|
|
697
|
+
pluginConfig?: Record<string, unknown>;
|
|
698
|
+
}): {
|
|
699
|
+
ok: true;
|
|
700
|
+
} | {
|
|
701
|
+
ok: false;
|
|
702
|
+
error: string;
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
type ProgressivePluginLoadOptions = {
|
|
706
|
+
config: Config;
|
|
707
|
+
workspaceDir?: string;
|
|
708
|
+
logger?: PluginLogger;
|
|
709
|
+
mode?: "full" | "validate";
|
|
710
|
+
excludeRoots?: string[];
|
|
711
|
+
reservedToolNames?: string[];
|
|
712
|
+
reservedChannelIds?: string[];
|
|
713
|
+
reservedProviderIds?: string[];
|
|
714
|
+
reservedEngineKinds?: string[];
|
|
715
|
+
reservedNcpAgentRuntimeKinds?: string[];
|
|
716
|
+
onPluginProcessed?: (params: {
|
|
717
|
+
loadedPluginCount: number;
|
|
718
|
+
pluginId?: string;
|
|
719
|
+
}) => void;
|
|
720
|
+
yieldToEventLoop?: () => Promise<void>;
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
declare function loadOpenClawPluginsProgressively(options: ProgressivePluginLoadOptions): Promise<PluginRegistry>;
|
|
724
|
+
|
|
662
725
|
type PluginLoadOptions = {
|
|
663
726
|
config: Config;
|
|
664
727
|
workspaceDir?: string;
|
|
@@ -739,49 +802,6 @@ declare function createPluginRuntime(params: {
|
|
|
739
802
|
config?: Config;
|
|
740
803
|
}): PluginRuntime;
|
|
741
804
|
|
|
742
|
-
type PluginRegisterRuntime = {
|
|
743
|
-
config: Config;
|
|
744
|
-
workspaceDir: string;
|
|
745
|
-
logger: PluginLogger;
|
|
746
|
-
registry: PluginRegistry;
|
|
747
|
-
toolNameOwners: Map<string, string>;
|
|
748
|
-
channelIdOwners: Map<string, string>;
|
|
749
|
-
providerIdOwners: Map<string, string>;
|
|
750
|
-
engineKindOwners: Map<string, string>;
|
|
751
|
-
ncpAgentRuntimeKindOwners: Map<string, string>;
|
|
752
|
-
resolvedToolNames: Set<string>;
|
|
753
|
-
reservedToolNames: Set<string>;
|
|
754
|
-
reservedChannelIds: Set<string>;
|
|
755
|
-
reservedProviderIds: Set<string>;
|
|
756
|
-
reservedEngineKinds: Set<string>;
|
|
757
|
-
reservedNcpAgentRuntimeKinds: Set<string>;
|
|
758
|
-
};
|
|
759
|
-
declare function createPluginRegisterRuntime(params: {
|
|
760
|
-
config: Config;
|
|
761
|
-
workspaceDir: string;
|
|
762
|
-
logger: PluginLogger;
|
|
763
|
-
registry: PluginRegistry;
|
|
764
|
-
reservedToolNames: Set<string>;
|
|
765
|
-
reservedChannelIds: Set<string>;
|
|
766
|
-
reservedProviderIds: Set<string>;
|
|
767
|
-
reservedEngineKinds: Set<string>;
|
|
768
|
-
reservedNcpAgentRuntimeKinds: Set<string>;
|
|
769
|
-
}): PluginRegisterRuntime;
|
|
770
|
-
declare function registerPluginWithApi(params: {
|
|
771
|
-
runtime: PluginRegisterRuntime;
|
|
772
|
-
record: PluginRecord;
|
|
773
|
-
pluginId: string;
|
|
774
|
-
source: string;
|
|
775
|
-
rootDir: string;
|
|
776
|
-
register: (api: OpenClawPluginApi) => void | Promise<void>;
|
|
777
|
-
pluginConfig?: Record<string, unknown>;
|
|
778
|
-
}): {
|
|
779
|
-
ok: true;
|
|
780
|
-
} | {
|
|
781
|
-
ok: false;
|
|
782
|
-
error: string;
|
|
783
|
-
};
|
|
784
|
-
|
|
785
805
|
declare function validateJsonSchemaValue(params: {
|
|
786
806
|
schema: Record<string, unknown>;
|
|
787
807
|
cacheKey: string;
|
|
@@ -853,4 +873,4 @@ declare function uninstallPlugin(params: {
|
|
|
853
873
|
extensionsDir?: string;
|
|
854
874
|
}): Promise<UninstallPluginResult>;
|
|
855
875
|
|
|
856
|
-
export { DEFAULT_ACCOUNT_ID, type InstallPluginResult, type NormalizedPluginsConfig, type OpenClawChannelAgentPrompt, type OpenClawChannelAuth, type OpenClawChannelAuthLoginResult, type OpenClawChannelAuthPollResult, type OpenClawChannelAuthStartResult, type OpenClawChannelConfigAdapter, type OpenClawChannelConfigSchema, type OpenClawChannelGateway, type OpenClawChannelGatewayStartContext, type OpenClawChannelPlugin, type OpenClawChannelSetup, type OpenClawPluginApi, type OpenClawPluginChannelRegistration, type OpenClawPluginConfigSchema, type OpenClawPluginDefinition, type OpenClawPluginEngineOptions, type OpenClawPluginModule, type OpenClawPluginNcpAgentRuntimeRegistration, type OpenClawPluginTool, type OpenClawPluginToolContext, type OpenClawPluginToolFactory, type OpenClawPluginToolOptions, type OpenClawProviderPlugin, PLUGIN_MANIFEST_FILENAME, PLUGIN_MANIFEST_FILENAMES, type PackageManifest, type PluginCandidate, type PluginChannelBinding, type PluginChannelGatewayHandle, type PluginChannelRegistration, type PluginConfigUiHint, type PluginDiagnostic, type PluginDiscoveryResult, type PluginEngineRegistration, type PluginInstallLogger, type PluginInstallSource, type PluginInstallUpdate, type PluginKind, type PluginLoadOptions, type PluginLogger, type PluginManifest, type PluginManifestLoadResult, type PluginManifestRecord, type PluginManifestRegistry, type PluginNcpAgentRuntimeRegistration, type PluginOrigin, type PluginProviderRegistration, type PluginRecord, type PluginRegisterRuntime, type PluginRegistry, type PluginReplyDispatchParams, type PluginRuntime, type PluginRuntimeBridge, type PluginStatusReport, type PluginToolRegistration, type PluginUiMetadata, type UninstallActions, type UninstallPluginResult, type _CompatOnly, __nextclawPluginSdkCompat, addPluginLoadPath, buildChannelConfigSchema, buildOauthProviderAuthResult, buildPluginLoaderAliases, buildPluginStatusReport, createNextclawBuiltinChannelPlugin, createPluginRegisterRuntime, createPluginRuntime, disablePluginInConfig, discoverOpenClawPlugins, discoverPluginStatusReport, emptyPluginConfigSchema, enablePluginInConfig, getPackageManifestMetadata, getPluginChannelBindings, getPluginUiMetadataFromRegistry, installPluginFromArchive, installPluginFromDir, installPluginFromFile, installPluginFromNpmSpec, installPluginFromPath, loadOpenClawPlugins, loadPluginManifest, loadPluginManifestRegistry, loadPluginUiMetadata, mergePluginConfigView, normalizeAccountId, normalizePluginHttpPath, normalizePluginsConfig, recordPluginInstall, registerPluginWithApi, removePluginFromConfig, resolveEnableState, resolvePluginChannelMessageToolHints, resolvePluginInstallDir, resolvePluginManifestPath, resolveUninstallDirectoryTarget, resolveUninstallDirectoryTargets, setPluginRuntimeBridge, sleep, startPluginChannelGateways, stopPluginChannelGateways, toPluginConfigView, toPluginUiMetadata, uninstallPlugin, validateJsonSchemaValue };
|
|
876
|
+
export { DEFAULT_ACCOUNT_ID, type InstallPluginResult, type NormalizedPluginsConfig, type OpenClawChannelAgentPrompt, type OpenClawChannelAuth, type OpenClawChannelAuthLoginResult, type OpenClawChannelAuthPollResult, type OpenClawChannelAuthStartResult, type OpenClawChannelConfigAdapter, type OpenClawChannelConfigSchema, type OpenClawChannelGateway, type OpenClawChannelGatewayStartContext, type OpenClawChannelPlugin, type OpenClawChannelSetup, type OpenClawPluginApi, type OpenClawPluginChannelRegistration, type OpenClawPluginConfigSchema, type OpenClawPluginDefinition, type OpenClawPluginEngineOptions, type OpenClawPluginModule, type OpenClawPluginNcpAgentRuntimeRegistration, type OpenClawPluginTool, type OpenClawPluginToolContext, type OpenClawPluginToolFactory, type OpenClawPluginToolOptions, type OpenClawProviderPlugin, PLUGIN_MANIFEST_FILENAME, PLUGIN_MANIFEST_FILENAMES, type PackageManifest, type PluginCandidate, type PluginChannelBinding, type PluginChannelGatewayHandle, type PluginChannelRegistration, type PluginConfigUiHint, type PluginDiagnostic, type PluginDiscoveryResult, type PluginEngineRegistration, type PluginInstallLogger, type PluginInstallSource, type PluginInstallUpdate, type PluginKind, type PluginLoadOptions, type PluginLogger, type PluginManifest, type PluginManifestLoadResult, type PluginManifestRecord, type PluginManifestRegistry, type PluginNcpAgentRuntimeRegistration, type PluginOrigin, type PluginProviderRegistration, type PluginRecord, type PluginRegisterRuntime, type PluginRegistry, type PluginReplyDispatchParams, type PluginRuntime, type PluginRuntimeBridge, type PluginStatusReport, type PluginToolRegistration, type PluginUiMetadata, type ProgressivePluginLoadOptions, type UninstallActions, type UninstallPluginResult, type _CompatOnly, __nextclawPluginSdkCompat, addPluginLoadPath, buildChannelConfigSchema, buildOauthProviderAuthResult, buildPluginLoaderAliases, buildPluginStatusReport, createNextclawBuiltinChannelPlugin, createPluginRegisterRuntime, createPluginRuntime, disablePluginInConfig, discoverOpenClawPlugins, discoverPluginStatusReport, emptyPluginConfigSchema, enablePluginInConfig, getPackageManifestMetadata, getPluginChannelBindings, getPluginUiMetadataFromRegistry, installPluginFromArchive, installPluginFromDir, installPluginFromFile, installPluginFromNpmSpec, installPluginFromPath, loadOpenClawPlugins, loadOpenClawPluginsProgressively, loadPluginManifest, loadPluginManifestRegistry, loadPluginUiMetadata, mergePluginConfigView, normalizeAccountId, normalizePluginHttpPath, normalizePluginsConfig, recordPluginInstall, registerPluginWithApi, removePluginFromConfig, resolveEnableState, resolvePluginChannelMessageToolHints, resolvePluginInstallDir, resolvePluginManifestPath, resolveUninstallDirectoryTarget, resolveUninstallDirectoryTargets, setPluginRuntimeBridge, sleep, startPluginChannelGateways, stopPluginChannelGateways, toPluginConfigView, toPluginUiMetadata, uninstallPlugin, validateJsonSchemaValue };
|
package/dist/index.js
CHANGED
|
@@ -1204,10 +1204,10 @@ async function installPluginFromPath(params) {
|
|
|
1204
1204
|
}
|
|
1205
1205
|
|
|
1206
1206
|
// src/plugins/loader.ts
|
|
1207
|
-
import
|
|
1208
|
-
import
|
|
1209
|
-
import { createRequire as
|
|
1210
|
-
import { getWorkspacePathFromConfig } from "@nextclaw/core";
|
|
1207
|
+
import fs7 from "fs";
|
|
1208
|
+
import path8 from "path";
|
|
1209
|
+
import { createRequire as createRequire3 } from "module";
|
|
1210
|
+
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig2 } from "@nextclaw/core";
|
|
1211
1211
|
|
|
1212
1212
|
// src/plugins/bundled-channel-plugin-packages.constants.ts
|
|
1213
1213
|
var BUNDLED_CHANNEL_PLUGIN_PACKAGES = [
|
|
@@ -1576,12 +1576,12 @@ function buildPluginLoaderAliases(pluginRoot) {
|
|
|
1576
1576
|
}
|
|
1577
1577
|
|
|
1578
1578
|
// src/plugins/bundled-plugin-loader.ts
|
|
1579
|
-
function resolveBundledPluginEntry(require2, packageName, diagnostics,
|
|
1579
|
+
function resolveBundledPluginEntry(require2, packageName, diagnostics, resolvePackageRootFromEntry4) {
|
|
1580
1580
|
try {
|
|
1581
1581
|
const entryFile = require2.resolve(packageName);
|
|
1582
1582
|
return {
|
|
1583
1583
|
entryFile,
|
|
1584
|
-
rootDir:
|
|
1584
|
+
rootDir: resolvePackageRootFromEntry4(entryFile)
|
|
1585
1585
|
};
|
|
1586
1586
|
} catch (err) {
|
|
1587
1587
|
diagnostics.push({
|
|
@@ -1611,9 +1611,9 @@ function formatAjvErrors(errors) {
|
|
|
1611
1611
|
return ["invalid config"];
|
|
1612
1612
|
}
|
|
1613
1613
|
return errors.map((error) => {
|
|
1614
|
-
const
|
|
1614
|
+
const path11 = error.instancePath?.replace(/^\//, "").replace(/\//g, ".") || "<root>";
|
|
1615
1615
|
const message = error.message ?? "invalid";
|
|
1616
|
-
return `${
|
|
1616
|
+
return `${path11}: ${message}`;
|
|
1617
1617
|
});
|
|
1618
1618
|
}
|
|
1619
1619
|
function validateJsonSchemaValue(params) {
|
|
@@ -2792,7 +2792,14 @@ function registerPluginWithApi(params) {
|
|
|
2792
2792
|
}
|
|
2793
2793
|
}
|
|
2794
2794
|
|
|
2795
|
-
// src/plugins/loader.ts
|
|
2795
|
+
// src/plugins/loader/progressive-bundled-plugin-loader.ts
|
|
2796
|
+
import { createRequire as createRequire2 } from "module";
|
|
2797
|
+
|
|
2798
|
+
// src/plugins/loader/progressive-plugin-loader-context.ts
|
|
2799
|
+
import fs6 from "fs";
|
|
2800
|
+
import path7 from "path";
|
|
2801
|
+
import { setImmediate as waitForNextTick } from "timers/promises";
|
|
2802
|
+
import { getWorkspacePathFromConfig } from "@nextclaw/core";
|
|
2796
2803
|
var defaultLogger2 = {
|
|
2797
2804
|
info: (message) => console.log(message),
|
|
2798
2805
|
warn: (message) => console.warn(message),
|
|
@@ -2809,7 +2816,7 @@ function logPluginStartupTrace(step, fields) {
|
|
|
2809
2816
|
}
|
|
2810
2817
|
function resolvePackageRootFromEntry(entryFile) {
|
|
2811
2818
|
let cursor = path7.dirname(entryFile);
|
|
2812
|
-
for (let
|
|
2819
|
+
for (let index = 0; index < 8; index += 1) {
|
|
2813
2820
|
const candidate = path7.join(cursor, "package.json");
|
|
2814
2821
|
if (fs6.existsSync(candidate)) {
|
|
2815
2822
|
return cursor;
|
|
@@ -2838,15 +2845,552 @@ function resolvePluginModuleExport(moduleExport) {
|
|
|
2838
2845
|
}
|
|
2839
2846
|
return {};
|
|
2840
2847
|
}
|
|
2841
|
-
function
|
|
2848
|
+
function loadExternalPluginModule(candidateSource, pluginRoot) {
|
|
2849
|
+
const pluginJiti = createPluginJiti(buildPluginLoaderAliases(pluginRoot));
|
|
2850
|
+
return pluginJiti(candidateSource);
|
|
2851
|
+
}
|
|
2852
|
+
function createEmptyPluginRegistry() {
|
|
2853
|
+
return {
|
|
2854
|
+
plugins: [],
|
|
2855
|
+
tools: [],
|
|
2856
|
+
channels: [],
|
|
2857
|
+
providers: [],
|
|
2858
|
+
engines: [],
|
|
2859
|
+
ncpAgentRuntimes: [],
|
|
2860
|
+
diagnostics: [],
|
|
2861
|
+
resolvedTools: []
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
function createRegisterRuntimeFromOptions(options, registry, workspaceDir) {
|
|
2865
|
+
const logger = options.logger ?? defaultLogger2;
|
|
2866
|
+
return createPluginRegisterRuntime({
|
|
2867
|
+
config: options.config,
|
|
2868
|
+
workspaceDir,
|
|
2869
|
+
logger,
|
|
2870
|
+
registry,
|
|
2871
|
+
reservedToolNames: new Set(options.reservedToolNames ?? []),
|
|
2872
|
+
reservedChannelIds: new Set(options.reservedChannelIds ?? []),
|
|
2873
|
+
reservedProviderIds: new Set(options.reservedProviderIds ?? []),
|
|
2874
|
+
reservedEngineKinds: new Set((options.reservedEngineKinds ?? ["native"]).map((entry) => entry.toLowerCase())),
|
|
2875
|
+
reservedNcpAgentRuntimeKinds: new Set(
|
|
2876
|
+
(options.reservedNcpAgentRuntimeKinds ?? ["native"]).map((entry) => entry.toLowerCase())
|
|
2877
|
+
)
|
|
2878
|
+
});
|
|
2879
|
+
}
|
|
2880
|
+
function createProgressivePluginLoadContext(options) {
|
|
2881
|
+
const workspaceDir = options.workspaceDir?.trim() || getWorkspacePathFromConfig(options.config);
|
|
2882
|
+
const normalizedConfig = normalizePluginsConfig(options.config.plugins);
|
|
2883
|
+
const registry = createEmptyPluginRegistry();
|
|
2884
|
+
return {
|
|
2885
|
+
options,
|
|
2886
|
+
workspaceDir,
|
|
2887
|
+
normalizedConfig,
|
|
2888
|
+
mode: options.mode ?? "full",
|
|
2889
|
+
registry,
|
|
2890
|
+
registerRuntime: createRegisterRuntimeFromOptions(options, registry, workspaceDir),
|
|
2891
|
+
tracker: {
|
|
2892
|
+
loadedPluginCount: 0,
|
|
2893
|
+
onPluginProcessed: options.onPluginProcessed,
|
|
2894
|
+
yieldToEventLoop: options.yieldToEventLoop ?? (() => waitForNextTick())
|
|
2895
|
+
}
|
|
2896
|
+
};
|
|
2897
|
+
}
|
|
2898
|
+
async function markPluginProcessed(tracker, pluginId) {
|
|
2899
|
+
tracker.loadedPluginCount += 1;
|
|
2900
|
+
tracker.onPluginProcessed?.({
|
|
2901
|
+
loadedPluginCount: tracker.loadedPluginCount,
|
|
2902
|
+
...pluginId ? { pluginId } : {}
|
|
2903
|
+
});
|
|
2904
|
+
await tracker.yieldToEventLoop();
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
// src/plugins/loader/progressive-bundled-plugin-loader.ts
|
|
2908
|
+
function pushBundledPluginLoadError(registry, entryFile, error) {
|
|
2909
|
+
registry.diagnostics.push({
|
|
2910
|
+
level: "error",
|
|
2911
|
+
source: entryFile,
|
|
2912
|
+
message: `failed to load bundled plugin: ${String(error)}`
|
|
2913
|
+
});
|
|
2914
|
+
}
|
|
2915
|
+
function buildBundledPluginRecord(params) {
|
|
2916
|
+
return createPluginRecord({
|
|
2917
|
+
id: params.pluginId,
|
|
2918
|
+
name: params.definition?.name ?? params.pluginId,
|
|
2919
|
+
description: params.definition?.description,
|
|
2920
|
+
version: params.definition?.version,
|
|
2921
|
+
kind: params.definition?.kind,
|
|
2922
|
+
source: params.entryFile,
|
|
2923
|
+
origin: "bundled",
|
|
2924
|
+
workspaceDir: params.context.registerRuntime.workspaceDir,
|
|
2925
|
+
enabled: true,
|
|
2926
|
+
configSchema: Boolean(params.definition?.configSchema),
|
|
2927
|
+
configJsonSchema: params.definition?.configSchema
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
function disableBundledPluginRecord(record, reason) {
|
|
2931
|
+
record.status = "disabled";
|
|
2932
|
+
record.error = reason;
|
|
2933
|
+
return record;
|
|
2934
|
+
}
|
|
2935
|
+
function markBundledPluginError(params) {
|
|
2936
|
+
params.record.status = "error";
|
|
2937
|
+
params.record.error = params.message;
|
|
2938
|
+
params.registry.diagnostics.push({
|
|
2939
|
+
level: "error",
|
|
2940
|
+
pluginId: params.pluginId,
|
|
2941
|
+
source: params.entryFile,
|
|
2942
|
+
message: params.message
|
|
2943
|
+
});
|
|
2944
|
+
return params.record;
|
|
2945
|
+
}
|
|
2946
|
+
function finalizeBundledPluginRecord(params) {
|
|
2947
|
+
if (params.record) {
|
|
2948
|
+
params.context.registry.plugins.push(params.record);
|
|
2949
|
+
}
|
|
2950
|
+
logPluginStartupTrace("plugin.loader.bundled_plugin", {
|
|
2951
|
+
package: params.packageName,
|
|
2952
|
+
plugin_id: params.pluginId,
|
|
2953
|
+
duration_ms: Date.now() - params.packageStartedAt
|
|
2954
|
+
});
|
|
2955
|
+
}
|
|
2956
|
+
function resolveBundledPluginRegistrationCandidate(params) {
|
|
2957
|
+
const resolvedEntry = resolveBundledPluginEntry(
|
|
2958
|
+
params.require,
|
|
2959
|
+
params.packageName,
|
|
2960
|
+
params.context.registry.diagnostics,
|
|
2961
|
+
resolvePackageRootFromEntry
|
|
2962
|
+
);
|
|
2963
|
+
if (!resolvedEntry) {
|
|
2964
|
+
return { done: true };
|
|
2965
|
+
}
|
|
2966
|
+
const { entryFile, rootDir } = resolvedEntry;
|
|
2967
|
+
let loadedModule;
|
|
2968
|
+
try {
|
|
2969
|
+
loadedModule = loadBundledPluginModule(entryFile, rootDir);
|
|
2970
|
+
} catch (error) {
|
|
2971
|
+
pushBundledPluginLoadError(params.context.registry, entryFile, error);
|
|
2972
|
+
return { done: true };
|
|
2973
|
+
}
|
|
2974
|
+
const resolved = resolvePluginModuleExport(loadedModule);
|
|
2975
|
+
const pluginId = typeof resolved.definition?.id === "string" ? resolved.definition.id.trim() : "";
|
|
2976
|
+
if (!pluginId) {
|
|
2977
|
+
params.context.registry.diagnostics.push({
|
|
2978
|
+
level: "error",
|
|
2979
|
+
source: entryFile,
|
|
2980
|
+
message: "bundled plugin definition missing id"
|
|
2981
|
+
});
|
|
2982
|
+
return { done: true };
|
|
2983
|
+
}
|
|
2984
|
+
const enableState = resolveEnableState(pluginId, params.context.normalizedConfig);
|
|
2985
|
+
const record = buildBundledPluginRecord({
|
|
2986
|
+
pluginId,
|
|
2987
|
+
definition: resolved.definition,
|
|
2988
|
+
entryFile,
|
|
2989
|
+
context: params.context
|
|
2990
|
+
});
|
|
2991
|
+
if (!enableState.enabled) {
|
|
2992
|
+
finalizeBundledPluginRecord({
|
|
2993
|
+
packageName: params.packageName,
|
|
2994
|
+
pluginId,
|
|
2995
|
+
record: disableBundledPluginRecord(record, enableState.reason ?? "disabled"),
|
|
2996
|
+
context: params.context,
|
|
2997
|
+
packageStartedAt: params.packageStartedAt
|
|
2998
|
+
});
|
|
2999
|
+
return { done: true, pluginId };
|
|
3000
|
+
}
|
|
3001
|
+
if (typeof resolved.register !== "function") {
|
|
3002
|
+
finalizeBundledPluginRecord({
|
|
3003
|
+
packageName: params.packageName,
|
|
3004
|
+
pluginId,
|
|
3005
|
+
record: markBundledPluginError({
|
|
3006
|
+
record,
|
|
3007
|
+
registry: params.context.registry,
|
|
3008
|
+
pluginId,
|
|
3009
|
+
entryFile,
|
|
3010
|
+
message: "plugin export missing register/activate"
|
|
3011
|
+
}),
|
|
3012
|
+
context: params.context,
|
|
3013
|
+
packageStartedAt: params.packageStartedAt
|
|
3014
|
+
});
|
|
3015
|
+
return { done: true, pluginId };
|
|
3016
|
+
}
|
|
3017
|
+
return {
|
|
3018
|
+
done: false,
|
|
3019
|
+
entryFile,
|
|
3020
|
+
rootDir,
|
|
3021
|
+
pluginId,
|
|
3022
|
+
record,
|
|
3023
|
+
register: resolved.register
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
async function processBundledPluginPackage(context, require2, packageName) {
|
|
3027
|
+
const packageStartedAt = Date.now();
|
|
3028
|
+
const candidate = resolveBundledPluginRegistrationCandidate({
|
|
3029
|
+
context,
|
|
3030
|
+
require: require2,
|
|
3031
|
+
packageName,
|
|
3032
|
+
packageStartedAt
|
|
3033
|
+
});
|
|
3034
|
+
if (candidate.done) {
|
|
3035
|
+
await markPluginProcessed(context.tracker, candidate.pluginId);
|
|
3036
|
+
return;
|
|
3037
|
+
}
|
|
3038
|
+
const result = registerPluginWithApi({
|
|
3039
|
+
runtime: context.registerRuntime,
|
|
3040
|
+
record: candidate.record,
|
|
3041
|
+
pluginId: candidate.pluginId,
|
|
3042
|
+
source: candidate.entryFile,
|
|
3043
|
+
rootDir: candidate.rootDir,
|
|
3044
|
+
register: candidate.register,
|
|
3045
|
+
pluginConfig: void 0
|
|
3046
|
+
});
|
|
3047
|
+
if (!result.ok) {
|
|
3048
|
+
markBundledPluginError({
|
|
3049
|
+
record: candidate.record,
|
|
3050
|
+
registry: context.registry,
|
|
3051
|
+
pluginId: candidate.pluginId,
|
|
3052
|
+
entryFile: candidate.entryFile,
|
|
3053
|
+
message: result.error
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
finalizeBundledPluginRecord({
|
|
3057
|
+
packageName,
|
|
3058
|
+
pluginId: candidate.pluginId,
|
|
3059
|
+
record: candidate.record,
|
|
3060
|
+
context,
|
|
3061
|
+
packageStartedAt
|
|
3062
|
+
});
|
|
3063
|
+
await markPluginProcessed(context.tracker, candidate.pluginId);
|
|
3064
|
+
}
|
|
3065
|
+
async function appendBundledChannelPluginsProgressively(context) {
|
|
2842
3066
|
const require2 = createRequire2(import.meta.url);
|
|
3067
|
+
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
3068
|
+
await processBundledPluginPackage(context, require2, packageName);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// src/plugins/loader/progressive-external-plugin-loader.ts
|
|
3073
|
+
function createManifestPluginRecord(manifest, candidate, enabled) {
|
|
3074
|
+
return createPluginRecord({
|
|
3075
|
+
id: manifest.id,
|
|
3076
|
+
name: manifest.name ?? manifest.id,
|
|
3077
|
+
description: manifest.description,
|
|
3078
|
+
version: manifest.version,
|
|
3079
|
+
kind: manifest.kind,
|
|
3080
|
+
source: candidate.source,
|
|
3081
|
+
origin: candidate.origin,
|
|
3082
|
+
workspaceDir: candidate.workspaceDir,
|
|
3083
|
+
enabled,
|
|
3084
|
+
configSchema: Boolean(manifest.configSchema),
|
|
3085
|
+
configUiHints: manifest.configUiHints,
|
|
3086
|
+
configJsonSchema: manifest.configSchema
|
|
3087
|
+
});
|
|
3088
|
+
}
|
|
3089
|
+
async function finalizeExternalPluginRecord(params) {
|
|
3090
|
+
params.context.registry.plugins.push(params.record);
|
|
3091
|
+
if (params.pluginId && params.seenIds && params.origin) {
|
|
3092
|
+
params.seenIds.set(params.pluginId, params.origin);
|
|
3093
|
+
}
|
|
3094
|
+
await markPluginProcessed(params.context.tracker, params.pluginId);
|
|
3095
|
+
}
|
|
3096
|
+
async function finalizeExternalPluginError(params) {
|
|
3097
|
+
params.record.status = "error";
|
|
3098
|
+
params.record.error = params.message;
|
|
3099
|
+
params.context.registry.diagnostics.push({
|
|
3100
|
+
level: "error",
|
|
3101
|
+
pluginId: params.pluginId,
|
|
3102
|
+
source: params.candidate.source,
|
|
3103
|
+
message: params.message
|
|
3104
|
+
});
|
|
3105
|
+
await finalizeExternalPluginRecord({
|
|
3106
|
+
context: params.context,
|
|
3107
|
+
record: params.record,
|
|
3108
|
+
pluginId: params.pluginId,
|
|
3109
|
+
seenIds: params.seenIds,
|
|
3110
|
+
origin: params.candidate.origin
|
|
3111
|
+
});
|
|
3112
|
+
}
|
|
3113
|
+
async function finalizeDisabledExternalPlugin(params) {
|
|
3114
|
+
params.record.status = "disabled";
|
|
3115
|
+
params.record.error = params.reason;
|
|
3116
|
+
await finalizeExternalPluginRecord({
|
|
3117
|
+
context: params.context,
|
|
3118
|
+
record: params.record,
|
|
3119
|
+
pluginId: params.pluginId,
|
|
3120
|
+
seenIds: params.seenIds,
|
|
3121
|
+
origin: params.candidate.origin
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
function applyDefinitionMetadata(record, definition) {
|
|
3125
|
+
record.name = definition?.name ?? record.name;
|
|
3126
|
+
record.description = definition?.description ?? record.description;
|
|
3127
|
+
record.version = definition?.version ?? record.version;
|
|
3128
|
+
record.kind = definition?.kind ?? record.kind;
|
|
3129
|
+
}
|
|
3130
|
+
function loadExternalPluginDefinition(params) {
|
|
3131
|
+
const moduleLoadStartedAt = Date.now();
|
|
3132
|
+
const loadedModule = loadExternalPluginModule(params.candidate.source, params.candidate.rootDir);
|
|
3133
|
+
logPluginStartupTrace("plugin.loader.external_module_loaded", {
|
|
3134
|
+
plugin_id: params.pluginId,
|
|
3135
|
+
duration_ms: Date.now() - moduleLoadStartedAt,
|
|
3136
|
+
source: params.candidate.source
|
|
3137
|
+
});
|
|
3138
|
+
return resolvePluginModuleExport(loadedModule);
|
|
3139
|
+
}
|
|
3140
|
+
function pushDefinitionMismatchWarning(context, candidate, pluginId, definitionId) {
|
|
3141
|
+
if (!definitionId || definitionId === pluginId) {
|
|
3142
|
+
return;
|
|
3143
|
+
}
|
|
3144
|
+
context.registry.diagnostics.push({
|
|
3145
|
+
level: "warn",
|
|
3146
|
+
pluginId,
|
|
3147
|
+
source: candidate.source,
|
|
3148
|
+
message: `plugin id mismatch (manifest uses "${pluginId}", export uses "${definitionId}")`
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
async function loadAndRegisterExternalPlugin(params) {
|
|
3152
|
+
let resolved;
|
|
3153
|
+
try {
|
|
3154
|
+
resolved = loadExternalPluginDefinition({
|
|
3155
|
+
context: params.context,
|
|
3156
|
+
candidate: params.candidate,
|
|
3157
|
+
pluginId: params.pluginId
|
|
3158
|
+
});
|
|
3159
|
+
} catch (error) {
|
|
3160
|
+
await finalizeExternalPluginError({
|
|
3161
|
+
context: params.context,
|
|
3162
|
+
record: params.record,
|
|
3163
|
+
candidate: params.candidate,
|
|
3164
|
+
pluginId: params.pluginId,
|
|
3165
|
+
seenIds: params.seenIds,
|
|
3166
|
+
message: `failed to load plugin: ${String(error)}`
|
|
3167
|
+
});
|
|
3168
|
+
return;
|
|
3169
|
+
}
|
|
3170
|
+
pushDefinitionMismatchWarning(params.context, params.candidate, params.pluginId, resolved.definition?.id);
|
|
3171
|
+
applyDefinitionMetadata(params.record, resolved.definition);
|
|
3172
|
+
if (typeof resolved.register !== "function") {
|
|
3173
|
+
await finalizeExternalPluginError({
|
|
3174
|
+
context: params.context,
|
|
3175
|
+
record: params.record,
|
|
3176
|
+
candidate: params.candidate,
|
|
3177
|
+
pluginId: params.pluginId,
|
|
3178
|
+
seenIds: params.seenIds,
|
|
3179
|
+
message: "plugin export missing register/activate"
|
|
3180
|
+
});
|
|
3181
|
+
return;
|
|
3182
|
+
}
|
|
3183
|
+
const registerResult = registerPluginWithApi({
|
|
3184
|
+
runtime: params.context.registerRuntime,
|
|
3185
|
+
record: params.record,
|
|
3186
|
+
pluginId: params.pluginId,
|
|
3187
|
+
source: params.candidate.source,
|
|
3188
|
+
rootDir: params.candidate.rootDir,
|
|
3189
|
+
register: resolved.register,
|
|
3190
|
+
pluginConfig: params.validatedConfig.value
|
|
3191
|
+
});
|
|
3192
|
+
logPluginStartupTrace("plugin.loader.external_plugin_registered", {
|
|
3193
|
+
plugin_id: params.pluginId,
|
|
3194
|
+
duration_ms: Date.now() - params.candidateStartedAt,
|
|
3195
|
+
source: params.candidate.source
|
|
3196
|
+
});
|
|
3197
|
+
if (!registerResult.ok) {
|
|
3198
|
+
await finalizeExternalPluginError({
|
|
3199
|
+
context: params.context,
|
|
3200
|
+
record: params.record,
|
|
3201
|
+
candidate: params.candidate,
|
|
3202
|
+
pluginId: params.pluginId,
|
|
3203
|
+
seenIds: params.seenIds,
|
|
3204
|
+
message: registerResult.error
|
|
3205
|
+
});
|
|
3206
|
+
return;
|
|
3207
|
+
}
|
|
3208
|
+
await finalizeExternalPluginRecord({
|
|
3209
|
+
context: params.context,
|
|
3210
|
+
record: params.record,
|
|
3211
|
+
pluginId: params.pluginId,
|
|
3212
|
+
seenIds: params.seenIds,
|
|
3213
|
+
origin: params.candidate.origin
|
|
3214
|
+
});
|
|
3215
|
+
}
|
|
3216
|
+
async function processExternalPluginCandidate(params) {
|
|
3217
|
+
const candidateStartedAt = Date.now();
|
|
3218
|
+
const pluginId = params.manifest.id;
|
|
3219
|
+
const existingOrigin = params.seenIds.get(pluginId);
|
|
3220
|
+
if (existingOrigin) {
|
|
3221
|
+
const overriddenRecord = createManifestPluginRecord(params.manifest, params.candidate, false);
|
|
3222
|
+
overriddenRecord.status = "disabled";
|
|
3223
|
+
overriddenRecord.error = `overridden by ${existingOrigin} plugin`;
|
|
3224
|
+
await finalizeExternalPluginRecord({
|
|
3225
|
+
context: params.context,
|
|
3226
|
+
record: overriddenRecord,
|
|
3227
|
+
pluginId
|
|
3228
|
+
});
|
|
3229
|
+
return;
|
|
3230
|
+
}
|
|
3231
|
+
const enableState = resolveEnableState(pluginId, params.context.normalizedConfig);
|
|
3232
|
+
const record = createManifestPluginRecord(params.manifest, params.candidate, enableState.enabled);
|
|
3233
|
+
if (!enableState.enabled) {
|
|
3234
|
+
await finalizeDisabledExternalPlugin({
|
|
3235
|
+
context: params.context,
|
|
3236
|
+
record,
|
|
3237
|
+
candidate: params.candidate,
|
|
3238
|
+
pluginId,
|
|
3239
|
+
seenIds: params.seenIds,
|
|
3240
|
+
reason: enableState.reason ?? "disabled"
|
|
3241
|
+
});
|
|
3242
|
+
return;
|
|
3243
|
+
}
|
|
3244
|
+
if (!params.manifest.configSchema) {
|
|
3245
|
+
await finalizeExternalPluginError({
|
|
3246
|
+
context: params.context,
|
|
3247
|
+
record,
|
|
3248
|
+
candidate: params.candidate,
|
|
3249
|
+
pluginId,
|
|
3250
|
+
seenIds: params.seenIds,
|
|
3251
|
+
message: "missing config schema"
|
|
3252
|
+
});
|
|
3253
|
+
return;
|
|
3254
|
+
}
|
|
3255
|
+
const validatedConfig = validatePluginConfig({
|
|
3256
|
+
schema: params.manifest.configSchema,
|
|
3257
|
+
cacheKey: params.manifest.schemaCacheKey,
|
|
3258
|
+
value: params.context.normalizedConfig.entries[pluginId]?.config
|
|
3259
|
+
});
|
|
3260
|
+
if (!validatedConfig.ok) {
|
|
3261
|
+
await finalizeExternalPluginError({
|
|
3262
|
+
context: params.context,
|
|
3263
|
+
record,
|
|
3264
|
+
candidate: params.candidate,
|
|
3265
|
+
pluginId,
|
|
3266
|
+
seenIds: params.seenIds,
|
|
3267
|
+
message: `invalid config: ${validatedConfig.errors.join(", ")}`
|
|
3268
|
+
});
|
|
3269
|
+
return;
|
|
3270
|
+
}
|
|
3271
|
+
if (params.context.mode === "validate") {
|
|
3272
|
+
await finalizeExternalPluginRecord({
|
|
3273
|
+
context: params.context,
|
|
3274
|
+
record,
|
|
3275
|
+
pluginId,
|
|
3276
|
+
seenIds: params.seenIds,
|
|
3277
|
+
origin: params.candidate.origin
|
|
3278
|
+
});
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
await loadAndRegisterExternalPlugin({
|
|
3282
|
+
context: params.context,
|
|
3283
|
+
candidate: params.candidate,
|
|
3284
|
+
record,
|
|
3285
|
+
pluginId,
|
|
3286
|
+
seenIds: params.seenIds,
|
|
3287
|
+
validatedConfig,
|
|
3288
|
+
candidateStartedAt
|
|
3289
|
+
});
|
|
3290
|
+
}
|
|
3291
|
+
async function appendExternalPluginsProgressively(context) {
|
|
3292
|
+
const discovery = discoverOpenClawPlugins({
|
|
3293
|
+
config: context.options.config,
|
|
3294
|
+
workspaceDir: context.workspaceDir,
|
|
3295
|
+
extraPaths: context.normalizedConfig.loadPaths
|
|
3296
|
+
});
|
|
3297
|
+
const filteredCandidates = filterPluginCandidatesByExcludedRoots(discovery.candidates, context.options.excludeRoots ?? []);
|
|
3298
|
+
const manifestRegistry = loadPluginManifestRegistry({
|
|
3299
|
+
config: context.options.config,
|
|
3300
|
+
workspaceDir: context.workspaceDir,
|
|
3301
|
+
candidates: filteredCandidates,
|
|
3302
|
+
diagnostics: discovery.diagnostics
|
|
3303
|
+
});
|
|
3304
|
+
context.registry.diagnostics.push(...manifestRegistry.diagnostics);
|
|
3305
|
+
const manifestByRoot = new Map(manifestRegistry.plugins.map((entry) => [entry.rootDir, entry]));
|
|
3306
|
+
const seenIds = new Map(
|
|
3307
|
+
context.registry.plugins.map((entry) => [entry.id, entry.origin])
|
|
3308
|
+
);
|
|
3309
|
+
for (const candidate of filteredCandidates) {
|
|
3310
|
+
const manifest = manifestByRoot.get(candidate.rootDir);
|
|
3311
|
+
if (!manifest) {
|
|
3312
|
+
await markPluginProcessed(context.tracker);
|
|
3313
|
+
continue;
|
|
3314
|
+
}
|
|
3315
|
+
await processExternalPluginCandidate({
|
|
3316
|
+
context,
|
|
3317
|
+
candidate,
|
|
3318
|
+
manifest,
|
|
3319
|
+
seenIds
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
|
|
3324
|
+
// src/plugins/loader/progressive-plugin-loader.ts
|
|
3325
|
+
async function loadOpenClawPluginsProgressively(options) {
|
|
3326
|
+
const startedAt = Date.now();
|
|
3327
|
+
const context = createProgressivePluginLoadContext(options);
|
|
3328
|
+
await appendBundledChannelPluginsProgressively(context);
|
|
3329
|
+
if (process.env.NEXTCLAW_ENABLE_OPENCLAW_PLUGINS !== "0") {
|
|
3330
|
+
await appendExternalPluginsProgressively(context);
|
|
3331
|
+
}
|
|
3332
|
+
logPluginStartupTrace("plugin.loader.total", {
|
|
3333
|
+
duration_ms: Date.now() - startedAt,
|
|
3334
|
+
plugin_count: context.registry.plugins.length
|
|
3335
|
+
});
|
|
3336
|
+
return context.registry;
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
// src/plugins/loader.ts
|
|
3340
|
+
var defaultLogger3 = {
|
|
3341
|
+
info: (message) => console.log(message),
|
|
3342
|
+
warn: (message) => console.warn(message),
|
|
3343
|
+
error: (message) => console.error(message),
|
|
3344
|
+
debug: (message) => console.debug(message)
|
|
3345
|
+
};
|
|
3346
|
+
var STARTUP_TRACE_ENABLED2 = process.env.NEXTCLAW_STARTUP_TRACE === "1";
|
|
3347
|
+
function logPluginStartupTrace2(step, fields) {
|
|
3348
|
+
if (!STARTUP_TRACE_ENABLED2) {
|
|
3349
|
+
return;
|
|
3350
|
+
}
|
|
3351
|
+
const suffix = Object.entries(fields ?? {}).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}=${String(value)}`).join(" ");
|
|
3352
|
+
console.log(`[startup-trace] ${step}${suffix ? ` ${suffix}` : ""}`);
|
|
3353
|
+
}
|
|
3354
|
+
function resolvePackageRootFromEntry2(entryFile) {
|
|
3355
|
+
let cursor = path8.dirname(entryFile);
|
|
3356
|
+
for (let i = 0; i < 8; i += 1) {
|
|
3357
|
+
const candidate = path8.join(cursor, "package.json");
|
|
3358
|
+
if (fs7.existsSync(candidate)) {
|
|
3359
|
+
return cursor;
|
|
3360
|
+
}
|
|
3361
|
+
const parent = path8.dirname(cursor);
|
|
3362
|
+
if (parent === cursor) {
|
|
3363
|
+
break;
|
|
3364
|
+
}
|
|
3365
|
+
cursor = parent;
|
|
3366
|
+
}
|
|
3367
|
+
return path8.dirname(entryFile);
|
|
3368
|
+
}
|
|
3369
|
+
function resolvePluginModuleExport2(moduleExport) {
|
|
3370
|
+
const resolved = moduleExport && typeof moduleExport === "object" && "default" in moduleExport ? moduleExport.default : moduleExport;
|
|
3371
|
+
if (typeof resolved === "function") {
|
|
3372
|
+
return {
|
|
3373
|
+
register: resolved
|
|
3374
|
+
};
|
|
3375
|
+
}
|
|
3376
|
+
if (resolved && typeof resolved === "object") {
|
|
3377
|
+
const definition = resolved;
|
|
3378
|
+
return {
|
|
3379
|
+
definition,
|
|
3380
|
+
register: definition.register ?? definition.activate
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3383
|
+
return {};
|
|
3384
|
+
}
|
|
3385
|
+
function appendBundledChannelPlugins(params) {
|
|
3386
|
+
const require2 = createRequire3(import.meta.url);
|
|
2843
3387
|
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
2844
3388
|
const packageStartedAt = Date.now();
|
|
2845
3389
|
const resolvedEntry = resolveBundledPluginEntry(
|
|
2846
3390
|
require2,
|
|
2847
3391
|
packageName,
|
|
2848
3392
|
params.registry.diagnostics,
|
|
2849
|
-
|
|
3393
|
+
resolvePackageRootFromEntry2
|
|
2850
3394
|
);
|
|
2851
3395
|
if (!resolvedEntry) {
|
|
2852
3396
|
continue;
|
|
@@ -2863,7 +3407,7 @@ function appendBundledChannelPlugins(params) {
|
|
|
2863
3407
|
});
|
|
2864
3408
|
continue;
|
|
2865
3409
|
}
|
|
2866
|
-
const resolved =
|
|
3410
|
+
const resolved = resolvePluginModuleExport2(moduleExport);
|
|
2867
3411
|
const definition = resolved.definition;
|
|
2868
3412
|
const register = resolved.register;
|
|
2869
3413
|
const pluginId = typeof definition?.id === "string" ? definition.id.trim() : "";
|
|
@@ -2928,22 +3472,22 @@ function appendBundledChannelPlugins(params) {
|
|
|
2928
3472
|
});
|
|
2929
3473
|
}
|
|
2930
3474
|
params.registry.plugins.push(record);
|
|
2931
|
-
|
|
3475
|
+
logPluginStartupTrace2("plugin.loader.bundled_plugin", {
|
|
2932
3476
|
package: packageName,
|
|
2933
3477
|
plugin_id: pluginId,
|
|
2934
3478
|
duration_ms: Date.now() - packageStartedAt
|
|
2935
3479
|
});
|
|
2936
3480
|
}
|
|
2937
3481
|
}
|
|
2938
|
-
function
|
|
3482
|
+
function loadExternalPluginModule2(candidateSource, pluginRoot) {
|
|
2939
3483
|
const pluginJiti = createPluginJiti(buildPluginLoaderAliases(pluginRoot));
|
|
2940
3484
|
return pluginJiti(candidateSource);
|
|
2941
3485
|
}
|
|
2942
3486
|
function loadOpenClawPlugins(options) {
|
|
2943
3487
|
const startedAt = Date.now();
|
|
2944
3488
|
const loadExternalPlugins = process.env.NEXTCLAW_ENABLE_OPENCLAW_PLUGINS !== "0";
|
|
2945
|
-
const logger = options.logger ??
|
|
2946
|
-
const workspaceDir = options.workspaceDir?.trim() ||
|
|
3489
|
+
const logger = options.logger ?? defaultLogger3;
|
|
3490
|
+
const workspaceDir = options.workspaceDir?.trim() || getWorkspacePathFromConfig2(options.config);
|
|
2947
3491
|
const normalized = normalizePluginsConfig(options.config.plugins);
|
|
2948
3492
|
const mode = options.mode ?? "full";
|
|
2949
3493
|
const registry = {
|
|
@@ -3089,8 +3633,8 @@ function loadOpenClawPlugins(options) {
|
|
|
3089
3633
|
let moduleExport = null;
|
|
3090
3634
|
try {
|
|
3091
3635
|
const moduleLoadStartedAt = Date.now();
|
|
3092
|
-
moduleExport =
|
|
3093
|
-
|
|
3636
|
+
moduleExport = loadExternalPluginModule2(candidate.source, candidate.rootDir);
|
|
3637
|
+
logPluginStartupTrace2("plugin.loader.external_module_loaded", {
|
|
3094
3638
|
plugin_id: pluginId,
|
|
3095
3639
|
duration_ms: Date.now() - moduleLoadStartedAt,
|
|
3096
3640
|
source: candidate.source
|
|
@@ -3108,7 +3652,7 @@ function loadOpenClawPlugins(options) {
|
|
|
3108
3652
|
});
|
|
3109
3653
|
continue;
|
|
3110
3654
|
}
|
|
3111
|
-
const resolved =
|
|
3655
|
+
const resolved = resolvePluginModuleExport2(moduleExport);
|
|
3112
3656
|
const definition = resolved.definition;
|
|
3113
3657
|
const register = resolved.register;
|
|
3114
3658
|
if (definition?.id && definition.id !== pluginId) {
|
|
@@ -3145,7 +3689,7 @@ function loadOpenClawPlugins(options) {
|
|
|
3145
3689
|
register,
|
|
3146
3690
|
pluginConfig: validatedConfig.value
|
|
3147
3691
|
});
|
|
3148
|
-
|
|
3692
|
+
logPluginStartupTrace2("plugin.loader.external_plugin_registered", {
|
|
3149
3693
|
plugin_id: pluginId,
|
|
3150
3694
|
duration_ms: Date.now() - candidateStartedAt,
|
|
3151
3695
|
source: candidate.source
|
|
@@ -3166,7 +3710,7 @@ function loadOpenClawPlugins(options) {
|
|
|
3166
3710
|
registry.plugins.push(record);
|
|
3167
3711
|
seenIds.set(pluginId, candidate.origin);
|
|
3168
3712
|
}
|
|
3169
|
-
|
|
3713
|
+
logPluginStartupTrace2("plugin.loader.total", {
|
|
3170
3714
|
duration_ms: Date.now() - startedAt,
|
|
3171
3715
|
plugin_count: registry.plugins.length
|
|
3172
3716
|
});
|
|
@@ -3174,11 +3718,11 @@ function loadOpenClawPlugins(options) {
|
|
|
3174
3718
|
}
|
|
3175
3719
|
|
|
3176
3720
|
// src/plugins/status.ts
|
|
3177
|
-
import
|
|
3178
|
-
import { createRequire as
|
|
3179
|
-
import
|
|
3180
|
-
import { getWorkspacePathFromConfig as
|
|
3181
|
-
function
|
|
3721
|
+
import fs8 from "fs";
|
|
3722
|
+
import { createRequire as createRequire4 } from "module";
|
|
3723
|
+
import path9 from "path";
|
|
3724
|
+
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig3 } from "@nextclaw/core";
|
|
3725
|
+
function createEmptyPluginRegistry2() {
|
|
3182
3726
|
return {
|
|
3183
3727
|
plugins: [],
|
|
3184
3728
|
tools: [],
|
|
@@ -3190,23 +3734,23 @@ function createEmptyPluginRegistry() {
|
|
|
3190
3734
|
resolvedTools: []
|
|
3191
3735
|
};
|
|
3192
3736
|
}
|
|
3193
|
-
function
|
|
3194
|
-
let cursor =
|
|
3737
|
+
function resolvePackageRootFromEntry3(entryFile) {
|
|
3738
|
+
let cursor = path9.dirname(entryFile);
|
|
3195
3739
|
for (let index = 0; index < 8; index += 1) {
|
|
3196
|
-
const candidate =
|
|
3197
|
-
if (
|
|
3740
|
+
const candidate = path9.join(cursor, "package.json");
|
|
3741
|
+
if (fs8.existsSync(candidate)) {
|
|
3198
3742
|
return cursor;
|
|
3199
3743
|
}
|
|
3200
|
-
const parent =
|
|
3744
|
+
const parent = path9.dirname(cursor);
|
|
3201
3745
|
if (parent === cursor) {
|
|
3202
3746
|
break;
|
|
3203
3747
|
}
|
|
3204
3748
|
cursor = parent;
|
|
3205
3749
|
}
|
|
3206
|
-
return
|
|
3750
|
+
return path9.dirname(entryFile);
|
|
3207
3751
|
}
|
|
3208
3752
|
function discoverBundledPluginCandidates(workspaceDir, diagnostics) {
|
|
3209
|
-
const require2 =
|
|
3753
|
+
const require2 = createRequire4(import.meta.url);
|
|
3210
3754
|
const candidates = [];
|
|
3211
3755
|
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
3212
3756
|
try {
|
|
@@ -3214,7 +3758,7 @@ function discoverBundledPluginCandidates(workspaceDir, diagnostics) {
|
|
|
3214
3758
|
candidates.push({
|
|
3215
3759
|
idHint: packageName.split("/").pop() ?? packageName,
|
|
3216
3760
|
source: entryFile,
|
|
3217
|
-
rootDir:
|
|
3761
|
+
rootDir: resolvePackageRootFromEntry3(entryFile),
|
|
3218
3762
|
origin: "bundled",
|
|
3219
3763
|
workspaceDir,
|
|
3220
3764
|
packageName
|
|
@@ -3296,7 +3840,7 @@ function finalizeDiscoveredManifestRecord(params) {
|
|
|
3296
3840
|
};
|
|
3297
3841
|
}
|
|
3298
3842
|
function discoverPluginStatusReport(params) {
|
|
3299
|
-
const workspaceDir = params.workspaceDir?.trim() ||
|
|
3843
|
+
const workspaceDir = params.workspaceDir?.trim() || getWorkspacePathFromConfig3(params.config);
|
|
3300
3844
|
const normalized = normalizePluginsConfig(params.config.plugins);
|
|
3301
3845
|
const discovery = discoverOpenClawPlugins({
|
|
3302
3846
|
config: params.config,
|
|
@@ -3311,7 +3855,7 @@ function discoverPluginStatusReport(params) {
|
|
|
3311
3855
|
candidates: [...bundledCandidates, ...discovery.candidates],
|
|
3312
3856
|
diagnostics: [...bundledDiagnostics, ...discovery.diagnostics]
|
|
3313
3857
|
});
|
|
3314
|
-
const registry =
|
|
3858
|
+
const registry = createEmptyPluginRegistry2();
|
|
3315
3859
|
const seenIds = /* @__PURE__ */ new Map();
|
|
3316
3860
|
registry.diagnostics.push(...manifestRegistry.diagnostics);
|
|
3317
3861
|
for (const manifest of manifestRegistry.plugins) {
|
|
@@ -3337,7 +3881,7 @@ function discoverPluginStatusReport(params) {
|
|
|
3337
3881
|
};
|
|
3338
3882
|
}
|
|
3339
3883
|
function buildPluginStatusReport(params) {
|
|
3340
|
-
const workspaceDir = params.workspaceDir?.trim() ||
|
|
3884
|
+
const workspaceDir = params.workspaceDir?.trim() || getWorkspacePathFromConfig3(params.config);
|
|
3341
3885
|
const registry = loadOpenClawPlugins({
|
|
3342
3886
|
config: params.config,
|
|
3343
3887
|
workspaceDir,
|
|
@@ -3355,10 +3899,10 @@ function buildPluginStatusReport(params) {
|
|
|
3355
3899
|
}
|
|
3356
3900
|
|
|
3357
3901
|
// src/plugins/uninstall.ts
|
|
3358
|
-
import
|
|
3902
|
+
import fs9 from "fs/promises";
|
|
3359
3903
|
import { existsSync as existsSync2, statSync } from "fs";
|
|
3360
|
-
import
|
|
3361
|
-
import { getWorkspacePathFromConfig as
|
|
3904
|
+
import path10 from "path";
|
|
3905
|
+
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig4 } from "@nextclaw/core";
|
|
3362
3906
|
function isLinkedPathInstall(record) {
|
|
3363
3907
|
if (!record || record.source !== "path") {
|
|
3364
3908
|
return false;
|
|
@@ -3366,13 +3910,13 @@ function isLinkedPathInstall(record) {
|
|
|
3366
3910
|
if (!record.sourcePath || !record.installPath) {
|
|
3367
3911
|
return true;
|
|
3368
3912
|
}
|
|
3369
|
-
return
|
|
3913
|
+
return path10.resolve(record.sourcePath) === path10.resolve(record.installPath);
|
|
3370
3914
|
}
|
|
3371
3915
|
function pushUniquePath(targets, candidate) {
|
|
3372
3916
|
if (!candidate) {
|
|
3373
3917
|
return;
|
|
3374
3918
|
}
|
|
3375
|
-
const resolved =
|
|
3919
|
+
const resolved = path10.resolve(candidate);
|
|
3376
3920
|
if (!targets.includes(resolved)) {
|
|
3377
3921
|
targets.push(resolved);
|
|
3378
3922
|
}
|
|
@@ -3394,7 +3938,7 @@ function resolveUninstallDirectoryTarget(params) {
|
|
|
3394
3938
|
if (!configuredPath) {
|
|
3395
3939
|
return defaultPath;
|
|
3396
3940
|
}
|
|
3397
|
-
if (
|
|
3941
|
+
if (path10.resolve(configuredPath) === path10.resolve(defaultPath)) {
|
|
3398
3942
|
return configuredPath;
|
|
3399
3943
|
}
|
|
3400
3944
|
return defaultPath;
|
|
@@ -3414,8 +3958,8 @@ function resolveUninstallDirectoryTargets(params) {
|
|
|
3414
3958
|
})
|
|
3415
3959
|
);
|
|
3416
3960
|
pushUniquePath(targets, params.installRecord?.installPath);
|
|
3417
|
-
const workspaceDir =
|
|
3418
|
-
pushUniquePath(targets,
|
|
3961
|
+
const workspaceDir = getWorkspacePathFromConfig4(params.config);
|
|
3962
|
+
pushUniquePath(targets, path10.join(workspaceDir, ".nextclaw", "extensions", params.pluginId));
|
|
3419
3963
|
return targets;
|
|
3420
3964
|
}
|
|
3421
3965
|
function removePluginFromConfig(config, pluginId) {
|
|
@@ -3496,13 +4040,13 @@ function matchesPluginLoadPath(rawPath, pluginId) {
|
|
|
3496
4040
|
if (!normalizedPath) {
|
|
3497
4041
|
return false;
|
|
3498
4042
|
}
|
|
3499
|
-
const resolvedPath =
|
|
4043
|
+
const resolvedPath = path10.resolve(normalizedPath);
|
|
3500
4044
|
if (!existsSync2(resolvedPath)) {
|
|
3501
4045
|
return false;
|
|
3502
4046
|
}
|
|
3503
4047
|
const candidateRoot = (() => {
|
|
3504
4048
|
try {
|
|
3505
|
-
return statSync(resolvedPath).isDirectory() ? resolvedPath :
|
|
4049
|
+
return statSync(resolvedPath).isDirectory() ? resolvedPath : path10.dirname(resolvedPath);
|
|
3506
4050
|
} catch {
|
|
3507
4051
|
return null;
|
|
3508
4052
|
}
|
|
@@ -3536,9 +4080,9 @@ async function uninstallPlugin(params) {
|
|
|
3536
4080
|
extensionsDir
|
|
3537
4081
|
}) : [];
|
|
3538
4082
|
for (const deleteTarget of deleteTargets) {
|
|
3539
|
-
const existed = await
|
|
4083
|
+
const existed = await fs9.access(deleteTarget).then(() => true).catch(() => false);
|
|
3540
4084
|
try {
|
|
3541
|
-
await
|
|
4085
|
+
await fs9.rm(deleteTarget, { recursive: true, force: true });
|
|
3542
4086
|
actions.directory = actions.directory || existed;
|
|
3543
4087
|
} catch (error) {
|
|
3544
4088
|
warnings.push(
|
|
@@ -3581,6 +4125,7 @@ export {
|
|
|
3581
4125
|
installPluginFromNpmSpec,
|
|
3582
4126
|
installPluginFromPath,
|
|
3583
4127
|
loadOpenClawPlugins,
|
|
4128
|
+
loadOpenClawPluginsProgressively,
|
|
3584
4129
|
loadPluginManifest,
|
|
3585
4130
|
loadPluginManifestRegistry,
|
|
3586
4131
|
loadPluginUiMetadata,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/openclaw-compat",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.36",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "OpenClaw plugin compatibility layer for NextClaw.",
|
|
6
6
|
"type": "module",
|
|
@@ -19,21 +19,21 @@
|
|
|
19
19
|
"jiti": "^1.21.7",
|
|
20
20
|
"jszip": "^3.10.1",
|
|
21
21
|
"tar": "^7.4.3",
|
|
22
|
-
"@nextclaw/channel-plugin-
|
|
23
|
-
"@nextclaw/channel-plugin-
|
|
24
|
-
"@nextclaw/channel-plugin-
|
|
25
|
-
"@nextclaw/channel-plugin-
|
|
26
|
-
"@nextclaw/channel-plugin-
|
|
27
|
-
"@nextclaw/channel-plugin-
|
|
28
|
-
"@nextclaw/
|
|
29
|
-
"@nextclaw/channel-
|
|
30
|
-
"@nextclaw/channel-
|
|
22
|
+
"@nextclaw/channel-plugin-dingtalk": "0.2.18",
|
|
23
|
+
"@nextclaw/channel-plugin-discord": "0.2.18",
|
|
24
|
+
"@nextclaw/channel-plugin-email": "0.2.18",
|
|
25
|
+
"@nextclaw/channel-plugin-mochat": "0.2.18",
|
|
26
|
+
"@nextclaw/channel-plugin-qq": "0.2.18",
|
|
27
|
+
"@nextclaw/channel-plugin-slack": "0.2.18",
|
|
28
|
+
"@nextclaw/channel-plugin-telegram": "0.2.18",
|
|
29
|
+
"@nextclaw/channel-plugin-weixin": "0.1.11",
|
|
30
|
+
"@nextclaw/channel-runtime": "0.4.4",
|
|
31
|
+
"@nextclaw/core": "0.11.3",
|
|
31
32
|
"@nextclaw/ncp-toolkit": "0.4.4",
|
|
32
|
-
"@nextclaw/channel-plugin-telegram": "0.2.17",
|
|
33
33
|
"@nextclaw/ncp": "0.4.0",
|
|
34
|
-
"@nextclaw/channel-plugin-
|
|
35
|
-
"@nextclaw/channel-plugin-whatsapp": "0.2.
|
|
36
|
-
"@nextclaw/channel-plugin-wecom": "0.2.
|
|
34
|
+
"@nextclaw/channel-plugin-feishu": "0.2.21",
|
|
35
|
+
"@nextclaw/channel-plugin-whatsapp": "0.2.18",
|
|
36
|
+
"@nextclaw/channel-plugin-wecom": "0.2.18"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^20.17.6",
|