@nextclaw/openclaw-compat 0.3.35 → 0.3.37

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +64 -44
  2. package/dist/index.js +595 -50
  3. 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 fs6 from "fs";
1208
- import path7 from "path";
1209
- import { createRequire as createRequire2 } from "module";
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, resolvePackageRootFromEntry3) {
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: resolvePackageRootFromEntry3(entryFile)
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 path10 = error.instancePath?.replace(/^\//, "").replace(/\//g, ".") || "<root>";
1614
+ const path11 = error.instancePath?.replace(/^\//, "").replace(/\//g, ".") || "<root>";
1615
1615
  const message = error.message ?? "invalid";
1616
- return `${path10}: ${message}`;
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 i = 0; i < 8; i += 1) {
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 appendBundledChannelPlugins(params) {
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
- resolvePackageRootFromEntry
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 = resolvePluginModuleExport(moduleExport);
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
- logPluginStartupTrace("plugin.loader.bundled_plugin", {
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 loadExternalPluginModule(candidateSource, pluginRoot) {
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 ?? defaultLogger2;
2946
- const workspaceDir = options.workspaceDir?.trim() || getWorkspacePathFromConfig(options.config);
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 = loadExternalPluginModule(candidate.source, candidate.rootDir);
3093
- logPluginStartupTrace("plugin.loader.external_module_loaded", {
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 = resolvePluginModuleExport(moduleExport);
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
- logPluginStartupTrace("plugin.loader.external_plugin_registered", {
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
- logPluginStartupTrace("plugin.loader.total", {
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 fs7 from "fs";
3178
- import { createRequire as createRequire3 } from "module";
3179
- import path8 from "path";
3180
- import { getWorkspacePathFromConfig as getWorkspacePathFromConfig2 } from "@nextclaw/core";
3181
- function createEmptyPluginRegistry() {
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 resolvePackageRootFromEntry2(entryFile) {
3194
- let cursor = path8.dirname(entryFile);
3737
+ function resolvePackageRootFromEntry3(entryFile) {
3738
+ let cursor = path9.dirname(entryFile);
3195
3739
  for (let index = 0; index < 8; index += 1) {
3196
- const candidate = path8.join(cursor, "package.json");
3197
- if (fs7.existsSync(candidate)) {
3740
+ const candidate = path9.join(cursor, "package.json");
3741
+ if (fs8.existsSync(candidate)) {
3198
3742
  return cursor;
3199
3743
  }
3200
- const parent = path8.dirname(cursor);
3744
+ const parent = path9.dirname(cursor);
3201
3745
  if (parent === cursor) {
3202
3746
  break;
3203
3747
  }
3204
3748
  cursor = parent;
3205
3749
  }
3206
- return path8.dirname(entryFile);
3750
+ return path9.dirname(entryFile);
3207
3751
  }
3208
3752
  function discoverBundledPluginCandidates(workspaceDir, diagnostics) {
3209
- const require2 = createRequire3(import.meta.url);
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: resolvePackageRootFromEntry2(entryFile),
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() || getWorkspacePathFromConfig2(params.config);
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 = createEmptyPluginRegistry();
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() || getWorkspacePathFromConfig2(params.config);
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 fs8 from "fs/promises";
3902
+ import fs9 from "fs/promises";
3359
3903
  import { existsSync as existsSync2, statSync } from "fs";
3360
- import path9 from "path";
3361
- import { getWorkspacePathFromConfig as getWorkspacePathFromConfig3 } from "@nextclaw/core";
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 path9.resolve(record.sourcePath) === path9.resolve(record.installPath);
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 = path9.resolve(candidate);
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 (path9.resolve(configuredPath) === path9.resolve(defaultPath)) {
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 = getWorkspacePathFromConfig3(params.config);
3418
- pushUniquePath(targets, path9.join(workspaceDir, ".nextclaw", "extensions", params.pluginId));
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 = path9.resolve(normalizedPath);
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 : path9.dirname(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 fs8.access(deleteTarget).then(() => true).catch(() => false);
4083
+ const existed = await fs9.access(deleteTarget).then(() => true).catch(() => false);
3540
4084
  try {
3541
- await fs8.rm(deleteTarget, { recursive: true, force: true });
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.35",
3
+ "version": "0.3.37",
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-discord": "0.2.17",
22
+ "@nextclaw/channel-plugin-dingtalk": "0.2.19",
23
+ "@nextclaw/channel-plugin-discord": "0.2.19",
24
+ "@nextclaw/channel-plugin-email": "0.2.19",
25
+ "@nextclaw/channel-plugin-mochat": "0.2.19",
26
+ "@nextclaw/channel-plugin-qq": "0.2.19",
27
+ "@nextclaw/channel-plugin-slack": "0.2.19",
28
+ "@nextclaw/channel-plugin-weixin": "0.1.12",
29
+ "@nextclaw/channel-plugin-wecom": "0.2.19",
30
+ "@nextclaw/channel-plugin-whatsapp": "0.2.19",
31
+ "@nextclaw/channel-runtime": "0.4.5",
32
+ "@nextclaw/core": "0.11.4",
33
+ "@nextclaw/channel-plugin-telegram": "0.2.19",
23
34
  "@nextclaw/channel-plugin-feishu": "0.2.21",
24
- "@nextclaw/channel-plugin-qq": "0.2.17",
25
- "@nextclaw/channel-plugin-dingtalk": "0.2.17",
26
- "@nextclaw/channel-plugin-email": "0.2.17",
27
- "@nextclaw/channel-plugin-mochat": "0.2.17",
28
- "@nextclaw/core": "0.11.2",
29
- "@nextclaw/channel-runtime": "0.4.3",
30
- "@nextclaw/channel-plugin-slack": "0.2.17",
31
- "@nextclaw/ncp-toolkit": "0.4.4",
32
- "@nextclaw/channel-plugin-telegram": "0.2.17",
33
35
  "@nextclaw/ncp": "0.4.0",
34
- "@nextclaw/channel-plugin-weixin": "0.1.10",
35
- "@nextclaw/channel-plugin-whatsapp": "0.2.17",
36
- "@nextclaw/channel-plugin-wecom": "0.2.17"
36
+ "@nextclaw/ncp-toolkit": "0.4.4"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^20.17.6",