@nextclaw/openclaw-compat 0.3.17 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +331 -97
- package/package.json +24 -25
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NextClaw contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -562,6 +562,8 @@ declare function installPluginFromPath(params: {
|
|
|
562
562
|
expectedPluginId?: string;
|
|
563
563
|
}): Promise<InstallPluginResult>;
|
|
564
564
|
|
|
565
|
+
declare function buildPluginLoaderAliases(pluginRoot?: string): Record<string, string>;
|
|
566
|
+
|
|
565
567
|
type PluginLoadOptions = {
|
|
566
568
|
config: Config;
|
|
567
569
|
workspaceDir?: string;
|
|
@@ -574,7 +576,7 @@ type PluginLoadOptions = {
|
|
|
574
576
|
reservedEngineKinds?: string[];
|
|
575
577
|
reservedNcpAgentRuntimeKinds?: string[];
|
|
576
578
|
};
|
|
577
|
-
|
|
579
|
+
|
|
578
580
|
declare function loadOpenClawPlugins(options: PluginLoadOptions): PluginRegistry;
|
|
579
581
|
|
|
580
582
|
type PluginManifestRecord = {
|
|
@@ -699,6 +701,10 @@ declare function validateJsonSchemaValue(params: {
|
|
|
699
701
|
type PluginStatusReport = PluginRegistry & {
|
|
700
702
|
workspaceDir: string;
|
|
701
703
|
};
|
|
704
|
+
declare function discoverPluginStatusReport(params: {
|
|
705
|
+
config: Config;
|
|
706
|
+
workspaceDir?: string;
|
|
707
|
+
}): PluginStatusReport;
|
|
702
708
|
declare function buildPluginStatusReport(params: {
|
|
703
709
|
config: Config;
|
|
704
710
|
workspaceDir?: string;
|
|
@@ -752,4 +758,4 @@ declare function uninstallPlugin(params: {
|
|
|
752
758
|
extensionsDir?: string;
|
|
753
759
|
}): Promise<UninstallPluginResult>;
|
|
754
760
|
|
|
755
|
-
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, 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 };
|
|
761
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -1137,10 +1137,9 @@ async function installPluginFromPath(params) {
|
|
|
1137
1137
|
}
|
|
1138
1138
|
|
|
1139
1139
|
// src/plugins/loader.ts
|
|
1140
|
-
import
|
|
1141
|
-
import
|
|
1142
|
-
import {
|
|
1143
|
-
import { createRequire } from "module";
|
|
1140
|
+
import fs6 from "fs";
|
|
1141
|
+
import path7 from "path";
|
|
1142
|
+
import { createRequire as createRequire2 } from "module";
|
|
1144
1143
|
import { getWorkspacePathFromConfig } from "@nextclaw/core";
|
|
1145
1144
|
|
|
1146
1145
|
// src/plugins/bundled-channel-plugin-packages.constants.ts
|
|
@@ -1325,6 +1324,143 @@ function loadPluginUiMetadata(params) {
|
|
|
1325
1324
|
return toPluginUiMetadata(registry.plugins);
|
|
1326
1325
|
}
|
|
1327
1326
|
|
|
1327
|
+
// src/plugins/plugin-loader-aliases.ts
|
|
1328
|
+
import fs5 from "fs";
|
|
1329
|
+
import path5 from "path";
|
|
1330
|
+
import { createRequire } from "module";
|
|
1331
|
+
import { fileURLToPath } from "url";
|
|
1332
|
+
function resolvePluginSdkAliasFile(params) {
|
|
1333
|
+
try {
|
|
1334
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
1335
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
1336
|
+
let cursor = path5.dirname(modulePath);
|
|
1337
|
+
for (let i = 0; i < 6; i += 1) {
|
|
1338
|
+
const srcCandidate = path5.join(cursor, "src", "plugin-sdk", params.srcFile);
|
|
1339
|
+
const distCandidate = path5.join(cursor, "dist", "plugin-sdk", params.distFile);
|
|
1340
|
+
const candidates = isProduction ? [distCandidate, srcCandidate] : [srcCandidate, distCandidate];
|
|
1341
|
+
for (const candidate of candidates) {
|
|
1342
|
+
if (fs5.existsSync(candidate)) {
|
|
1343
|
+
return candidate;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
const parent = path5.dirname(cursor);
|
|
1347
|
+
if (parent === cursor) {
|
|
1348
|
+
break;
|
|
1349
|
+
}
|
|
1350
|
+
cursor = parent;
|
|
1351
|
+
}
|
|
1352
|
+
} catch {
|
|
1353
|
+
return null;
|
|
1354
|
+
}
|
|
1355
|
+
return null;
|
|
1356
|
+
}
|
|
1357
|
+
function resolvePluginSdkAlias() {
|
|
1358
|
+
return resolvePluginSdkAliasFile({ srcFile: "index.ts", distFile: "index.js" });
|
|
1359
|
+
}
|
|
1360
|
+
function collectExportStringValues(value, values) {
|
|
1361
|
+
if (typeof value === "string") {
|
|
1362
|
+
values.push(value);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
for (const child of Object.values(value)) {
|
|
1369
|
+
collectExportStringValues(child, values);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
function resolveLocalPackageDir(pluginRoot, packageName) {
|
|
1373
|
+
const segments = packageName.split("/");
|
|
1374
|
+
return path5.join(pluginRoot, "node_modules", ...segments);
|
|
1375
|
+
}
|
|
1376
|
+
function isRunnableEntryFile(filePath) {
|
|
1377
|
+
const normalized = filePath.toLowerCase();
|
|
1378
|
+
if (normalized.endsWith(".d.ts") || normalized.endsWith(".map")) {
|
|
1379
|
+
return false;
|
|
1380
|
+
}
|
|
1381
|
+
return fs5.existsSync(filePath);
|
|
1382
|
+
}
|
|
1383
|
+
function hasRunnableLocalPackage(pluginRoot, packageName) {
|
|
1384
|
+
try {
|
|
1385
|
+
const packageDir = resolveLocalPackageDir(pluginRoot, packageName);
|
|
1386
|
+
const packageJsonPath = path5.join(packageDir, "package.json");
|
|
1387
|
+
if (!fs5.existsSync(packageJsonPath)) {
|
|
1388
|
+
return false;
|
|
1389
|
+
}
|
|
1390
|
+
const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
|
|
1391
|
+
const entryCandidates = [];
|
|
1392
|
+
collectExportStringValues(packageJson.exports, entryCandidates);
|
|
1393
|
+
if (typeof packageJson.module === "string") {
|
|
1394
|
+
entryCandidates.push(packageJson.module);
|
|
1395
|
+
}
|
|
1396
|
+
if (typeof packageJson.main === "string") {
|
|
1397
|
+
entryCandidates.push(packageJson.main);
|
|
1398
|
+
}
|
|
1399
|
+
if (entryCandidates.length === 0) {
|
|
1400
|
+
entryCandidates.push("index.js", "index.mjs", "index.cjs");
|
|
1401
|
+
}
|
|
1402
|
+
return entryCandidates.some((candidate) => {
|
|
1403
|
+
const resolved = path5.resolve(packageDir, candidate);
|
|
1404
|
+
return resolved.startsWith(`${path5.resolve(packageDir)}${path5.sep}`) && isRunnableEntryFile(resolved);
|
|
1405
|
+
});
|
|
1406
|
+
} catch {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
function readScopeEntries(scopeDir) {
|
|
1411
|
+
try {
|
|
1412
|
+
return fs5.readdirSync(scopeDir, { withFileTypes: true });
|
|
1413
|
+
} catch {
|
|
1414
|
+
return [];
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
function isAliasablePackageEntry(entry) {
|
|
1418
|
+
return entry.isDirectory() || entry.isSymbolicLink();
|
|
1419
|
+
}
|
|
1420
|
+
function shouldAliasHostPackage(pluginRoot, packageName) {
|
|
1421
|
+
return !pluginRoot || !hasRunnableLocalPackage(pluginRoot, packageName);
|
|
1422
|
+
}
|
|
1423
|
+
function appendScopeAliases(params) {
|
|
1424
|
+
for (const entry of readScopeEntries(params.scopeDir)) {
|
|
1425
|
+
if (!isAliasablePackageEntry(entry)) {
|
|
1426
|
+
continue;
|
|
1427
|
+
}
|
|
1428
|
+
const packageName = `${params.scope}/${entry.name}`;
|
|
1429
|
+
if (!shouldAliasHostPackage(params.pluginRoot, packageName)) {
|
|
1430
|
+
continue;
|
|
1431
|
+
}
|
|
1432
|
+
try {
|
|
1433
|
+
params.aliases[packageName] = params.require.resolve(packageName);
|
|
1434
|
+
} catch {
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
function buildScopedPackageAliases(scope, pluginRoot) {
|
|
1439
|
+
const aliases = {};
|
|
1440
|
+
const require2 = createRequire(import.meta.url);
|
|
1441
|
+
let cursor = path5.dirname(fileURLToPath(import.meta.url));
|
|
1442
|
+
for (let i = 0; i < 8; i += 1) {
|
|
1443
|
+
const scopeDir = path5.join(cursor, "node_modules", scope);
|
|
1444
|
+
if (fs5.existsSync(scopeDir)) {
|
|
1445
|
+
appendScopeAliases({ aliases, scopeDir, scope, pluginRoot, require: require2 });
|
|
1446
|
+
}
|
|
1447
|
+
const parent = path5.dirname(cursor);
|
|
1448
|
+
if (parent === cursor) {
|
|
1449
|
+
break;
|
|
1450
|
+
}
|
|
1451
|
+
cursor = parent;
|
|
1452
|
+
}
|
|
1453
|
+
return aliases;
|
|
1454
|
+
}
|
|
1455
|
+
function buildPluginLoaderAliases(pluginRoot) {
|
|
1456
|
+
const aliases = buildScopedPackageAliases("@nextclaw", pluginRoot);
|
|
1457
|
+
const pluginSdkAlias = resolvePluginSdkAlias();
|
|
1458
|
+
if (pluginSdkAlias) {
|
|
1459
|
+
aliases["openclaw/plugin-sdk"] = pluginSdkAlias;
|
|
1460
|
+
}
|
|
1461
|
+
return aliases;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1328
1464
|
// src/plugins/plugin-loader-jiti.ts
|
|
1329
1465
|
import createJitiImport from "jiti";
|
|
1330
1466
|
var createJiti = createJitiImport;
|
|
@@ -1355,9 +1491,9 @@ function formatAjvErrors(errors) {
|
|
|
1355
1491
|
return ["invalid config"];
|
|
1356
1492
|
}
|
|
1357
1493
|
return errors.map((error) => {
|
|
1358
|
-
const
|
|
1494
|
+
const path10 = error.instancePath?.replace(/^\//, "").replace(/\//g, ".") || "<root>";
|
|
1359
1495
|
const message = error.message ?? "invalid";
|
|
1360
|
-
return `${
|
|
1496
|
+
return `${path10}: ${message}`;
|
|
1361
1497
|
});
|
|
1362
1498
|
}
|
|
1363
1499
|
function validateJsonSchemaValue(params) {
|
|
@@ -1427,7 +1563,7 @@ function validatePluginConfig(params) {
|
|
|
1427
1563
|
}
|
|
1428
1564
|
|
|
1429
1565
|
// src/plugins/registry.ts
|
|
1430
|
-
import
|
|
1566
|
+
import path6 from "path";
|
|
1431
1567
|
import { expandHome as expandHome2 } from "@nextclaw/core";
|
|
1432
1568
|
|
|
1433
1569
|
// src/plugins/plugin-capability-registration.ts
|
|
@@ -1881,10 +2017,10 @@ function registerPluginWithApi(params) {
|
|
|
1881
2017
|
if (!trimmed) {
|
|
1882
2018
|
return params.rootDir;
|
|
1883
2019
|
}
|
|
1884
|
-
if (
|
|
1885
|
-
return
|
|
2020
|
+
if (path6.isAbsolute(trimmed)) {
|
|
2021
|
+
return path6.resolve(expandHome2(trimmed));
|
|
1886
2022
|
}
|
|
1887
|
-
return
|
|
2023
|
+
return path6.resolve(params.rootDir, trimmed);
|
|
1888
2024
|
}
|
|
1889
2025
|
};
|
|
1890
2026
|
try {
|
|
@@ -1912,87 +2048,19 @@ var defaultLogger2 = {
|
|
|
1912
2048
|
debug: (message) => console.debug(message)
|
|
1913
2049
|
};
|
|
1914
2050
|
function resolvePackageRootFromEntry(entryFile) {
|
|
1915
|
-
let cursor =
|
|
2051
|
+
let cursor = path7.dirname(entryFile);
|
|
1916
2052
|
for (let i = 0; i < 8; i += 1) {
|
|
1917
|
-
const candidate =
|
|
1918
|
-
if (
|
|
2053
|
+
const candidate = path7.join(cursor, "package.json");
|
|
2054
|
+
if (fs6.existsSync(candidate)) {
|
|
1919
2055
|
return cursor;
|
|
1920
2056
|
}
|
|
1921
|
-
const parent =
|
|
2057
|
+
const parent = path7.dirname(cursor);
|
|
1922
2058
|
if (parent === cursor) {
|
|
1923
2059
|
break;
|
|
1924
2060
|
}
|
|
1925
2061
|
cursor = parent;
|
|
1926
2062
|
}
|
|
1927
|
-
return
|
|
1928
|
-
}
|
|
1929
|
-
function resolvePluginSdkAliasFile(params) {
|
|
1930
|
-
try {
|
|
1931
|
-
const modulePath = fileURLToPath(import.meta.url);
|
|
1932
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
1933
|
-
let cursor = path6.dirname(modulePath);
|
|
1934
|
-
for (let i = 0; i < 6; i += 1) {
|
|
1935
|
-
const srcCandidate = path6.join(cursor, "src", "plugin-sdk", params.srcFile);
|
|
1936
|
-
const distCandidate = path6.join(cursor, "dist", "plugin-sdk", params.distFile);
|
|
1937
|
-
const candidates = isProduction ? [distCandidate, srcCandidate] : [srcCandidate, distCandidate];
|
|
1938
|
-
for (const candidate of candidates) {
|
|
1939
|
-
if (fs5.existsSync(candidate)) {
|
|
1940
|
-
return candidate;
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
const parent = path6.dirname(cursor);
|
|
1944
|
-
if (parent === cursor) {
|
|
1945
|
-
break;
|
|
1946
|
-
}
|
|
1947
|
-
cursor = parent;
|
|
1948
|
-
}
|
|
1949
|
-
} catch {
|
|
1950
|
-
return null;
|
|
1951
|
-
}
|
|
1952
|
-
return null;
|
|
1953
|
-
}
|
|
1954
|
-
function resolvePluginSdkAlias() {
|
|
1955
|
-
return resolvePluginSdkAliasFile({ srcFile: "index.ts", distFile: "index.js" });
|
|
1956
|
-
}
|
|
1957
|
-
function buildScopedPackageAliases(scope) {
|
|
1958
|
-
const aliases = {};
|
|
1959
|
-
const require2 = createRequire(import.meta.url);
|
|
1960
|
-
let cursor = path6.dirname(fileURLToPath(import.meta.url));
|
|
1961
|
-
for (let i = 0; i < 8; i += 1) {
|
|
1962
|
-
const scopeDir = path6.join(cursor, "node_modules", scope);
|
|
1963
|
-
if (fs5.existsSync(scopeDir)) {
|
|
1964
|
-
let entries = [];
|
|
1965
|
-
try {
|
|
1966
|
-
entries = fs5.readdirSync(scopeDir, { withFileTypes: true });
|
|
1967
|
-
} catch {
|
|
1968
|
-
entries = [];
|
|
1969
|
-
}
|
|
1970
|
-
for (const entry of entries) {
|
|
1971
|
-
if (!entry.isDirectory() && !entry.isSymbolicLink()) {
|
|
1972
|
-
continue;
|
|
1973
|
-
}
|
|
1974
|
-
const packageName = `${scope}/${entry.name}`;
|
|
1975
|
-
try {
|
|
1976
|
-
aliases[packageName] = require2.resolve(packageName);
|
|
1977
|
-
} catch {
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
const parent = path6.dirname(cursor);
|
|
1982
|
-
if (parent === cursor) {
|
|
1983
|
-
break;
|
|
1984
|
-
}
|
|
1985
|
-
cursor = parent;
|
|
1986
|
-
}
|
|
1987
|
-
return aliases;
|
|
1988
|
-
}
|
|
1989
|
-
function buildPluginLoaderAliases() {
|
|
1990
|
-
const aliases = buildScopedPackageAliases("@nextclaw");
|
|
1991
|
-
const pluginSdkAlias = resolvePluginSdkAlias();
|
|
1992
|
-
if (pluginSdkAlias) {
|
|
1993
|
-
aliases["openclaw/plugin-sdk"] = pluginSdkAlias;
|
|
1994
|
-
}
|
|
1995
|
-
return aliases;
|
|
2063
|
+
return path7.dirname(entryFile);
|
|
1996
2064
|
}
|
|
1997
2065
|
function resolvePluginModuleExport(moduleExport) {
|
|
1998
2066
|
const resolved = moduleExport && typeof moduleExport === "object" && "default" in moduleExport ? moduleExport.default : moduleExport;
|
|
@@ -2011,7 +2079,7 @@ function resolvePluginModuleExport(moduleExport) {
|
|
|
2011
2079
|
return {};
|
|
2012
2080
|
}
|
|
2013
2081
|
function appendBundledChannelPlugins(params) {
|
|
2014
|
-
const require2 =
|
|
2082
|
+
const require2 = createRequire2(import.meta.url);
|
|
2015
2083
|
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
2016
2084
|
let entryFile = "";
|
|
2017
2085
|
let rootDir = "";
|
|
@@ -2104,6 +2172,10 @@ function appendBundledChannelPlugins(params) {
|
|
|
2104
2172
|
params.registry.plugins.push(record);
|
|
2105
2173
|
}
|
|
2106
2174
|
}
|
|
2175
|
+
function loadExternalPluginModule(candidateSource, pluginRoot) {
|
|
2176
|
+
const pluginJiti = createPluginJiti(buildPluginLoaderAliases(pluginRoot));
|
|
2177
|
+
return pluginJiti(candidateSource);
|
|
2178
|
+
}
|
|
2107
2179
|
function loadOpenClawPlugins(options) {
|
|
2108
2180
|
const loadExternalPlugins = process.env.NEXTCLAW_ENABLE_OPENCLAW_PLUGINS !== "0";
|
|
2109
2181
|
const logger = options.logger ?? defaultLogger2;
|
|
@@ -2138,11 +2210,11 @@ function loadOpenClawPlugins(options) {
|
|
|
2138
2210
|
reservedEngineKinds,
|
|
2139
2211
|
reservedNcpAgentRuntimeKinds
|
|
2140
2212
|
});
|
|
2141
|
-
const
|
|
2213
|
+
const bundledPluginJiti = createPluginJiti(buildPluginLoaderAliases());
|
|
2142
2214
|
appendBundledChannelPlugins({
|
|
2143
2215
|
registry,
|
|
2144
2216
|
runtime: registerRuntime,
|
|
2145
|
-
jiti,
|
|
2217
|
+
jiti: bundledPluginJiti,
|
|
2146
2218
|
normalizedConfig: normalized
|
|
2147
2219
|
});
|
|
2148
2220
|
if (!loadExternalPlugins) {
|
|
@@ -2253,7 +2325,7 @@ function loadOpenClawPlugins(options) {
|
|
|
2253
2325
|
}
|
|
2254
2326
|
let moduleExport = null;
|
|
2255
2327
|
try {
|
|
2256
|
-
moduleExport =
|
|
2328
|
+
moduleExport = loadExternalPluginModule(candidate.source, candidate.rootDir);
|
|
2257
2329
|
} catch (err) {
|
|
2258
2330
|
record.status = "error";
|
|
2259
2331
|
record.error = `failed to load plugin: ${String(err)}`;
|
|
@@ -2324,7 +2396,168 @@ function loadOpenClawPlugins(options) {
|
|
|
2324
2396
|
}
|
|
2325
2397
|
|
|
2326
2398
|
// src/plugins/status.ts
|
|
2399
|
+
import fs7 from "fs";
|
|
2400
|
+
import { createRequire as createRequire3 } from "module";
|
|
2401
|
+
import path8 from "path";
|
|
2327
2402
|
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig2 } from "@nextclaw/core";
|
|
2403
|
+
function createEmptyPluginRegistry() {
|
|
2404
|
+
return {
|
|
2405
|
+
plugins: [],
|
|
2406
|
+
tools: [],
|
|
2407
|
+
channels: [],
|
|
2408
|
+
providers: [],
|
|
2409
|
+
engines: [],
|
|
2410
|
+
ncpAgentRuntimes: [],
|
|
2411
|
+
diagnostics: [],
|
|
2412
|
+
resolvedTools: []
|
|
2413
|
+
};
|
|
2414
|
+
}
|
|
2415
|
+
function resolvePackageRootFromEntry2(entryFile) {
|
|
2416
|
+
let cursor = path8.dirname(entryFile);
|
|
2417
|
+
for (let index = 0; index < 8; index += 1) {
|
|
2418
|
+
const candidate = path8.join(cursor, "package.json");
|
|
2419
|
+
if (fs7.existsSync(candidate)) {
|
|
2420
|
+
return cursor;
|
|
2421
|
+
}
|
|
2422
|
+
const parent = path8.dirname(cursor);
|
|
2423
|
+
if (parent === cursor) {
|
|
2424
|
+
break;
|
|
2425
|
+
}
|
|
2426
|
+
cursor = parent;
|
|
2427
|
+
}
|
|
2428
|
+
return path8.dirname(entryFile);
|
|
2429
|
+
}
|
|
2430
|
+
function discoverBundledPluginCandidates(workspaceDir, diagnostics) {
|
|
2431
|
+
const require2 = createRequire3(import.meta.url);
|
|
2432
|
+
const candidates = [];
|
|
2433
|
+
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
2434
|
+
try {
|
|
2435
|
+
const entryFile = require2.resolve(packageName);
|
|
2436
|
+
candidates.push({
|
|
2437
|
+
idHint: packageName.split("/").pop() ?? packageName,
|
|
2438
|
+
source: entryFile,
|
|
2439
|
+
rootDir: resolvePackageRootFromEntry2(entryFile),
|
|
2440
|
+
origin: "bundled",
|
|
2441
|
+
workspaceDir,
|
|
2442
|
+
packageName
|
|
2443
|
+
});
|
|
2444
|
+
} catch (error) {
|
|
2445
|
+
diagnostics.push({
|
|
2446
|
+
level: "error",
|
|
2447
|
+
source: packageName,
|
|
2448
|
+
message: `bundled plugin package not resolvable: ${String(error)}`
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
return candidates;
|
|
2453
|
+
}
|
|
2454
|
+
function createRecordFromManifest(manifest, enabled) {
|
|
2455
|
+
return createPluginRecord({
|
|
2456
|
+
id: manifest.id,
|
|
2457
|
+
name: manifest.name ?? manifest.id,
|
|
2458
|
+
description: manifest.description,
|
|
2459
|
+
version: manifest.version,
|
|
2460
|
+
kind: manifest.kind,
|
|
2461
|
+
source: manifest.source,
|
|
2462
|
+
origin: manifest.origin,
|
|
2463
|
+
workspaceDir: manifest.workspaceDir,
|
|
2464
|
+
enabled,
|
|
2465
|
+
configSchema: Boolean(manifest.configSchema),
|
|
2466
|
+
configUiHints: manifest.configUiHints,
|
|
2467
|
+
configJsonSchema: manifest.configSchema
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
function createOverriddenManifestRecord(manifest, existingOrigin) {
|
|
2471
|
+
const record = createRecordFromManifest(manifest, false);
|
|
2472
|
+
record.status = "disabled";
|
|
2473
|
+
record.error = `overridden by ${existingOrigin} plugin`;
|
|
2474
|
+
return record;
|
|
2475
|
+
}
|
|
2476
|
+
function finalizeDiscoveredManifestRecord(params) {
|
|
2477
|
+
const record = createRecordFromManifest(params.manifest, params.enabled);
|
|
2478
|
+
if (!params.enabled) {
|
|
2479
|
+
record.status = "disabled";
|
|
2480
|
+
record.error = params.disabledReason;
|
|
2481
|
+
return { record, diagnostics: [] };
|
|
2482
|
+
}
|
|
2483
|
+
if (!params.manifest.configSchema) {
|
|
2484
|
+
record.status = "error";
|
|
2485
|
+
record.error = "missing config schema";
|
|
2486
|
+
return {
|
|
2487
|
+
record,
|
|
2488
|
+
diagnostics: [
|
|
2489
|
+
{
|
|
2490
|
+
level: "error",
|
|
2491
|
+
pluginId: params.manifest.id,
|
|
2492
|
+
source: params.manifest.source,
|
|
2493
|
+
message: record.error
|
|
2494
|
+
}
|
|
2495
|
+
]
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
const validatedConfig = validatePluginConfig({
|
|
2499
|
+
schema: params.manifest.configSchema,
|
|
2500
|
+
cacheKey: params.manifest.schemaCacheKey,
|
|
2501
|
+
value: params.normalizedEntries[params.manifest.id]?.config
|
|
2502
|
+
});
|
|
2503
|
+
if (validatedConfig.ok) {
|
|
2504
|
+
return { record, diagnostics: [] };
|
|
2505
|
+
}
|
|
2506
|
+
record.status = "error";
|
|
2507
|
+
record.error = `invalid config: ${validatedConfig.errors.join(", ")}`;
|
|
2508
|
+
return {
|
|
2509
|
+
record,
|
|
2510
|
+
diagnostics: [
|
|
2511
|
+
{
|
|
2512
|
+
level: "error",
|
|
2513
|
+
pluginId: params.manifest.id,
|
|
2514
|
+
source: params.manifest.source,
|
|
2515
|
+
message: record.error
|
|
2516
|
+
}
|
|
2517
|
+
]
|
|
2518
|
+
};
|
|
2519
|
+
}
|
|
2520
|
+
function discoverPluginStatusReport(params) {
|
|
2521
|
+
const workspaceDir = params.workspaceDir?.trim() || getWorkspacePathFromConfig2(params.config);
|
|
2522
|
+
const normalized = normalizePluginsConfig(params.config.plugins);
|
|
2523
|
+
const discovery = discoverOpenClawPlugins({
|
|
2524
|
+
config: params.config,
|
|
2525
|
+
workspaceDir,
|
|
2526
|
+
extraPaths: normalized.loadPaths
|
|
2527
|
+
});
|
|
2528
|
+
const bundledDiagnostics = [];
|
|
2529
|
+
const bundledCandidates = discoverBundledPluginCandidates(workspaceDir, bundledDiagnostics);
|
|
2530
|
+
const manifestRegistry = loadPluginManifestRegistry({
|
|
2531
|
+
config: params.config,
|
|
2532
|
+
workspaceDir,
|
|
2533
|
+
candidates: [...bundledCandidates, ...discovery.candidates],
|
|
2534
|
+
diagnostics: [...bundledDiagnostics, ...discovery.diagnostics]
|
|
2535
|
+
});
|
|
2536
|
+
const registry = createEmptyPluginRegistry();
|
|
2537
|
+
const seenIds = /* @__PURE__ */ new Map();
|
|
2538
|
+
registry.diagnostics.push(...manifestRegistry.diagnostics);
|
|
2539
|
+
for (const manifest of manifestRegistry.plugins) {
|
|
2540
|
+
const existingOrigin = seenIds.get(manifest.id);
|
|
2541
|
+
if (existingOrigin) {
|
|
2542
|
+
registry.plugins.push(createOverriddenManifestRecord(manifest, existingOrigin));
|
|
2543
|
+
continue;
|
|
2544
|
+
}
|
|
2545
|
+
const enableState = resolveEnableState(manifest.id, normalized);
|
|
2546
|
+
const { record, diagnostics } = finalizeDiscoveredManifestRecord({
|
|
2547
|
+
manifest,
|
|
2548
|
+
normalizedEntries: normalized.entries,
|
|
2549
|
+
enabled: enableState.enabled,
|
|
2550
|
+
disabledReason: enableState.reason
|
|
2551
|
+
});
|
|
2552
|
+
registry.plugins.push(record);
|
|
2553
|
+
registry.diagnostics.push(...diagnostics);
|
|
2554
|
+
seenIds.set(manifest.id, manifest.origin);
|
|
2555
|
+
}
|
|
2556
|
+
return {
|
|
2557
|
+
workspaceDir,
|
|
2558
|
+
...registry
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2328
2561
|
function buildPluginStatusReport(params) {
|
|
2329
2562
|
const workspaceDir = params.workspaceDir?.trim() || getWorkspacePathFromConfig2(params.config);
|
|
2330
2563
|
const registry = loadOpenClawPlugins({
|
|
@@ -2344,9 +2577,9 @@ function buildPluginStatusReport(params) {
|
|
|
2344
2577
|
}
|
|
2345
2578
|
|
|
2346
2579
|
// src/plugins/uninstall.ts
|
|
2347
|
-
import
|
|
2580
|
+
import fs8 from "fs/promises";
|
|
2348
2581
|
import { existsSync, statSync } from "fs";
|
|
2349
|
-
import
|
|
2582
|
+
import path9 from "path";
|
|
2350
2583
|
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig3 } from "@nextclaw/core";
|
|
2351
2584
|
function isLinkedPathInstall(record) {
|
|
2352
2585
|
if (!record || record.source !== "path") {
|
|
@@ -2355,13 +2588,13 @@ function isLinkedPathInstall(record) {
|
|
|
2355
2588
|
if (!record.sourcePath || !record.installPath) {
|
|
2356
2589
|
return true;
|
|
2357
2590
|
}
|
|
2358
|
-
return
|
|
2591
|
+
return path9.resolve(record.sourcePath) === path9.resolve(record.installPath);
|
|
2359
2592
|
}
|
|
2360
2593
|
function pushUniquePath(targets, candidate) {
|
|
2361
2594
|
if (!candidate) {
|
|
2362
2595
|
return;
|
|
2363
2596
|
}
|
|
2364
|
-
const resolved =
|
|
2597
|
+
const resolved = path9.resolve(candidate);
|
|
2365
2598
|
if (!targets.includes(resolved)) {
|
|
2366
2599
|
targets.push(resolved);
|
|
2367
2600
|
}
|
|
@@ -2383,7 +2616,7 @@ function resolveUninstallDirectoryTarget(params) {
|
|
|
2383
2616
|
if (!configuredPath) {
|
|
2384
2617
|
return defaultPath;
|
|
2385
2618
|
}
|
|
2386
|
-
if (
|
|
2619
|
+
if (path9.resolve(configuredPath) === path9.resolve(defaultPath)) {
|
|
2387
2620
|
return configuredPath;
|
|
2388
2621
|
}
|
|
2389
2622
|
return defaultPath;
|
|
@@ -2404,7 +2637,7 @@ function resolveUninstallDirectoryTargets(params) {
|
|
|
2404
2637
|
);
|
|
2405
2638
|
pushUniquePath(targets, params.installRecord?.installPath);
|
|
2406
2639
|
const workspaceDir = getWorkspacePathFromConfig3(params.config);
|
|
2407
|
-
pushUniquePath(targets,
|
|
2640
|
+
pushUniquePath(targets, path9.join(workspaceDir, ".nextclaw", "extensions", params.pluginId));
|
|
2408
2641
|
return targets;
|
|
2409
2642
|
}
|
|
2410
2643
|
function removePluginFromConfig(config, pluginId) {
|
|
@@ -2485,13 +2718,13 @@ function matchesPluginLoadPath(rawPath, pluginId) {
|
|
|
2485
2718
|
if (!normalizedPath) {
|
|
2486
2719
|
return false;
|
|
2487
2720
|
}
|
|
2488
|
-
const resolvedPath =
|
|
2721
|
+
const resolvedPath = path9.resolve(normalizedPath);
|
|
2489
2722
|
if (!existsSync(resolvedPath)) {
|
|
2490
2723
|
return false;
|
|
2491
2724
|
}
|
|
2492
2725
|
const candidateRoot = (() => {
|
|
2493
2726
|
try {
|
|
2494
|
-
return statSync(resolvedPath).isDirectory() ? resolvedPath :
|
|
2727
|
+
return statSync(resolvedPath).isDirectory() ? resolvedPath : path9.dirname(resolvedPath);
|
|
2495
2728
|
} catch {
|
|
2496
2729
|
return null;
|
|
2497
2730
|
}
|
|
@@ -2525,9 +2758,9 @@ async function uninstallPlugin(params) {
|
|
|
2525
2758
|
extensionsDir
|
|
2526
2759
|
}) : [];
|
|
2527
2760
|
for (const deleteTarget of deleteTargets) {
|
|
2528
|
-
const existed = await
|
|
2761
|
+
const existed = await fs8.access(deleteTarget).then(() => true).catch(() => false);
|
|
2529
2762
|
try {
|
|
2530
|
-
await
|
|
2763
|
+
await fs8.rm(deleteTarget, { recursive: true, force: true });
|
|
2531
2764
|
actions.directory = actions.directory || existed;
|
|
2532
2765
|
} catch (error) {
|
|
2533
2766
|
warnings.push(
|
|
@@ -2558,6 +2791,7 @@ export {
|
|
|
2558
2791
|
createPluginRuntime,
|
|
2559
2792
|
disablePluginInConfig,
|
|
2560
2793
|
discoverOpenClawPlugins,
|
|
2794
|
+
discoverPluginStatusReport,
|
|
2561
2795
|
emptyPluginConfigSchema,
|
|
2562
2796
|
enablePluginInConfig,
|
|
2563
2797
|
getPackageManifestMetadata,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/openclaw-compat",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "OpenClaw plugin compatibility layer for NextClaw.",
|
|
6
6
|
"type": "module",
|
|
@@ -14,33 +14,26 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "tsup src/index.ts --format esm --dts --out-dir dist",
|
|
19
|
-
"prepack": "pnpm run build",
|
|
20
|
-
"lint": "eslint .",
|
|
21
|
-
"tsc": "tsc -p tsconfig.json",
|
|
22
|
-
"test": "vitest"
|
|
23
|
-
},
|
|
24
17
|
"dependencies": {
|
|
25
|
-
"@nextclaw/channel-plugin-dingtalk": "workspace:*",
|
|
26
|
-
"@nextclaw/channel-plugin-discord": "workspace:*",
|
|
27
|
-
"@nextclaw/channel-plugin-email": "workspace:*",
|
|
28
|
-
"@nextclaw/channel-plugin-feishu": "workspace:*",
|
|
29
|
-
"@nextclaw/channel-plugin-mochat": "workspace:*",
|
|
30
|
-
"@nextclaw/channel-plugin-qq": "workspace:*",
|
|
31
|
-
"@nextclaw/channel-plugin-slack": "workspace:*",
|
|
32
|
-
"@nextclaw/channel-plugin-telegram": "workspace:*",
|
|
33
|
-
"@nextclaw/channel-plugin-weixin": "workspace:*",
|
|
34
|
-
"@nextclaw/channel-plugin-wecom": "workspace:*",
|
|
35
|
-
"@nextclaw/channel-plugin-whatsapp": "workspace:*",
|
|
36
|
-
"@nextclaw/channel-runtime": "workspace:*",
|
|
37
|
-
"@nextclaw/core": "workspace:*",
|
|
38
|
-
"@nextclaw/ncp": "workspace:*",
|
|
39
|
-
"@nextclaw/ncp-toolkit": "workspace:*",
|
|
40
18
|
"ajv": "^8.17.1",
|
|
41
19
|
"jiti": "^1.21.7",
|
|
42
20
|
"jszip": "^3.10.1",
|
|
43
|
-
"tar": "^7.4.3"
|
|
21
|
+
"tar": "^7.4.3",
|
|
22
|
+
"@nextclaw/channel-plugin-discord": "0.2.13",
|
|
23
|
+
"@nextclaw/channel-plugin-qq": "0.2.13",
|
|
24
|
+
"@nextclaw/channel-plugin-mochat": "0.2.13",
|
|
25
|
+
"@nextclaw/channel-plugin-dingtalk": "0.2.13",
|
|
26
|
+
"@nextclaw/channel-plugin-telegram": "0.2.13",
|
|
27
|
+
"@nextclaw/channel-plugin-slack": "0.2.13",
|
|
28
|
+
"@nextclaw/core": "0.10.0",
|
|
29
|
+
"@nextclaw/channel-runtime": "0.3.0",
|
|
30
|
+
"@nextclaw/ncp": "0.3.2",
|
|
31
|
+
"@nextclaw/channel-plugin-feishu": "0.2.13",
|
|
32
|
+
"@nextclaw/channel-plugin-email": "0.2.13",
|
|
33
|
+
"@nextclaw/ncp-toolkit": "0.4.2",
|
|
34
|
+
"@nextclaw/channel-plugin-weixin": "0.1.7",
|
|
35
|
+
"@nextclaw/channel-plugin-whatsapp": "0.2.13",
|
|
36
|
+
"@nextclaw/channel-plugin-wecom": "0.2.13"
|
|
44
37
|
},
|
|
45
38
|
"devDependencies": {
|
|
46
39
|
"@types/node": "^20.17.6",
|
|
@@ -49,5 +42,11 @@
|
|
|
49
42
|
"tsx": "^4.19.2",
|
|
50
43
|
"typescript": "^5.6.3",
|
|
51
44
|
"vitest": "^2.1.2"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup src/index.ts --format esm --dts --out-dir dist",
|
|
48
|
+
"lint": "eslint .",
|
|
49
|
+
"tsc": "tsc -p tsconfig.json",
|
|
50
|
+
"test": "vitest"
|
|
52
51
|
}
|
|
53
|
-
}
|
|
52
|
+
}
|