@nextclaw/openclaw-compat 0.3.18 → 0.3.20
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 +8 -2
- package/dist/index.js +391 -109
- package/package.json +14 -14
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
|
|
@@ -1331,6 +1330,7 @@ var createJiti = createJitiImport;
|
|
|
1331
1330
|
function createPluginJiti(aliases) {
|
|
1332
1331
|
return createJiti(import.meta.url, {
|
|
1333
1332
|
interopDefault: true,
|
|
1333
|
+
esmResolve: true,
|
|
1334
1334
|
extensions: [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs", ".json"],
|
|
1335
1335
|
alias: aliases,
|
|
1336
1336
|
// Plugin install/upgrade is expected to hot-apply at runtime. Disable
|
|
@@ -1341,6 +1341,195 @@ function createPluginJiti(aliases) {
|
|
|
1341
1341
|
});
|
|
1342
1342
|
}
|
|
1343
1343
|
|
|
1344
|
+
// src/plugins/plugin-loader-aliases.ts
|
|
1345
|
+
import fs5 from "fs";
|
|
1346
|
+
import path5 from "path";
|
|
1347
|
+
import { createRequire } from "module";
|
|
1348
|
+
import { fileURLToPath } from "url";
|
|
1349
|
+
function resolvePluginSdkAliasFile(params) {
|
|
1350
|
+
try {
|
|
1351
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
1352
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
1353
|
+
let cursor = path5.dirname(modulePath);
|
|
1354
|
+
for (let i = 0; i < 6; i += 1) {
|
|
1355
|
+
const srcCandidate = path5.join(cursor, "src", "plugin-sdk", params.srcFile);
|
|
1356
|
+
const distCandidate = path5.join(cursor, "dist", "plugin-sdk", params.distFile);
|
|
1357
|
+
const candidates = isProduction ? [distCandidate, srcCandidate] : [srcCandidate, distCandidate];
|
|
1358
|
+
for (const candidate of candidates) {
|
|
1359
|
+
if (fs5.existsSync(candidate)) {
|
|
1360
|
+
return candidate;
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
const parent = path5.dirname(cursor);
|
|
1364
|
+
if (parent === cursor) {
|
|
1365
|
+
break;
|
|
1366
|
+
}
|
|
1367
|
+
cursor = parent;
|
|
1368
|
+
}
|
|
1369
|
+
} catch {
|
|
1370
|
+
return null;
|
|
1371
|
+
}
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
function resolvePluginSdkAlias() {
|
|
1375
|
+
return resolvePluginSdkAliasFile({ srcFile: "index.ts", distFile: "index.js" });
|
|
1376
|
+
}
|
|
1377
|
+
function resolvePluginShimFile(relativePath) {
|
|
1378
|
+
try {
|
|
1379
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
1380
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
1381
|
+
let cursor = path5.dirname(modulePath);
|
|
1382
|
+
for (let i = 0; i < 6; i += 1) {
|
|
1383
|
+
const srcCandidate = path5.join(cursor, "src", "plugins", "shims", relativePath);
|
|
1384
|
+
const distCandidate = path5.join(cursor, "dist", "plugins", "shims", relativePath.replace(/\.ts$/, ".js"));
|
|
1385
|
+
const candidates = isProduction ? [distCandidate, srcCandidate] : [srcCandidate, distCandidate];
|
|
1386
|
+
for (const candidate of candidates) {
|
|
1387
|
+
if (fs5.existsSync(candidate)) {
|
|
1388
|
+
return candidate;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
const parent = path5.dirname(cursor);
|
|
1392
|
+
if (parent === cursor) {
|
|
1393
|
+
break;
|
|
1394
|
+
}
|
|
1395
|
+
cursor = parent;
|
|
1396
|
+
}
|
|
1397
|
+
} catch {
|
|
1398
|
+
return null;
|
|
1399
|
+
}
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
function collectExportStringValues(value, values) {
|
|
1403
|
+
if (typeof value === "string") {
|
|
1404
|
+
values.push(value);
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
for (const child of Object.values(value)) {
|
|
1411
|
+
collectExportStringValues(child, values);
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
function resolveLocalPackageDir(pluginRoot, packageName) {
|
|
1415
|
+
const segments = packageName.split("/");
|
|
1416
|
+
return path5.join(pluginRoot, "node_modules", ...segments);
|
|
1417
|
+
}
|
|
1418
|
+
function isRunnableEntryFile(filePath) {
|
|
1419
|
+
const normalized = filePath.toLowerCase();
|
|
1420
|
+
if (normalized.endsWith(".d.ts") || normalized.endsWith(".map")) {
|
|
1421
|
+
return false;
|
|
1422
|
+
}
|
|
1423
|
+
return fs5.existsSync(filePath);
|
|
1424
|
+
}
|
|
1425
|
+
function hasRunnableLocalPackage(pluginRoot, packageName) {
|
|
1426
|
+
try {
|
|
1427
|
+
const packageDir = resolveLocalPackageDir(pluginRoot, packageName);
|
|
1428
|
+
const packageJsonPath = path5.join(packageDir, "package.json");
|
|
1429
|
+
if (!fs5.existsSync(packageJsonPath)) {
|
|
1430
|
+
return false;
|
|
1431
|
+
}
|
|
1432
|
+
const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
|
|
1433
|
+
const entryCandidates = [];
|
|
1434
|
+
collectExportStringValues(packageJson.exports, entryCandidates);
|
|
1435
|
+
if (typeof packageJson.module === "string") {
|
|
1436
|
+
entryCandidates.push(packageJson.module);
|
|
1437
|
+
}
|
|
1438
|
+
if (typeof packageJson.main === "string") {
|
|
1439
|
+
entryCandidates.push(packageJson.main);
|
|
1440
|
+
}
|
|
1441
|
+
if (entryCandidates.length === 0) {
|
|
1442
|
+
entryCandidates.push("index.js", "index.mjs", "index.cjs");
|
|
1443
|
+
}
|
|
1444
|
+
return entryCandidates.some((candidate) => {
|
|
1445
|
+
const resolved = path5.resolve(packageDir, candidate);
|
|
1446
|
+
return resolved.startsWith(`${path5.resolve(packageDir)}${path5.sep}`) && isRunnableEntryFile(resolved);
|
|
1447
|
+
});
|
|
1448
|
+
} catch {
|
|
1449
|
+
return false;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function readScopeEntries(scopeDir) {
|
|
1453
|
+
try {
|
|
1454
|
+
return fs5.readdirSync(scopeDir, { withFileTypes: true });
|
|
1455
|
+
} catch {
|
|
1456
|
+
return [];
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
function isAliasablePackageEntry(entry) {
|
|
1460
|
+
return entry.isDirectory() || entry.isSymbolicLink();
|
|
1461
|
+
}
|
|
1462
|
+
function shouldAliasHostPackage(pluginRoot, packageName) {
|
|
1463
|
+
return !pluginRoot || !hasRunnableLocalPackage(pluginRoot, packageName);
|
|
1464
|
+
}
|
|
1465
|
+
function appendScopeAliases(params) {
|
|
1466
|
+
for (const entry of readScopeEntries(params.scopeDir)) {
|
|
1467
|
+
if (!isAliasablePackageEntry(entry)) {
|
|
1468
|
+
continue;
|
|
1469
|
+
}
|
|
1470
|
+
const packageName = `${params.scope}/${entry.name}`;
|
|
1471
|
+
if (!shouldAliasHostPackage(params.pluginRoot, packageName)) {
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
try {
|
|
1475
|
+
params.aliases[packageName] = params.require.resolve(packageName);
|
|
1476
|
+
} catch {
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
function buildScopedPackageAliases(scope, pluginRoot) {
|
|
1481
|
+
const aliases = {};
|
|
1482
|
+
const require2 = createRequire(import.meta.url);
|
|
1483
|
+
let cursor = path5.dirname(fileURLToPath(import.meta.url));
|
|
1484
|
+
for (let i = 0; i < 8; i += 1) {
|
|
1485
|
+
const scopeDir = path5.join(cursor, "node_modules", scope);
|
|
1486
|
+
if (fs5.existsSync(scopeDir)) {
|
|
1487
|
+
appendScopeAliases({ aliases, scopeDir, scope, pluginRoot, require: require2 });
|
|
1488
|
+
}
|
|
1489
|
+
const parent = path5.dirname(cursor);
|
|
1490
|
+
if (parent === cursor) {
|
|
1491
|
+
break;
|
|
1492
|
+
}
|
|
1493
|
+
cursor = parent;
|
|
1494
|
+
}
|
|
1495
|
+
return aliases;
|
|
1496
|
+
}
|
|
1497
|
+
function buildPluginLoaderAliases(pluginRoot) {
|
|
1498
|
+
const aliases = buildScopedPackageAliases("@nextclaw", pluginRoot);
|
|
1499
|
+
const pluginSdkAlias = resolvePluginSdkAlias();
|
|
1500
|
+
const shouldUseCompatPluginSdkAlias = shouldAliasHostPackage(pluginRoot, "openclaw");
|
|
1501
|
+
if (pluginSdkAlias && shouldUseCompatPluginSdkAlias) {
|
|
1502
|
+
aliases["openclaw/plugin-sdk"] = pluginSdkAlias;
|
|
1503
|
+
}
|
|
1504
|
+
const piCodingAgentShim = resolvePluginShimFile("pi-coding-agent.ts");
|
|
1505
|
+
if (piCodingAgentShim) {
|
|
1506
|
+
aliases["@mariozechner/pi-coding-agent"] = piCodingAgentShim;
|
|
1507
|
+
}
|
|
1508
|
+
return aliases;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// src/plugins/bundled-plugin-loader.ts
|
|
1512
|
+
function resolveBundledPluginEntry(require2, packageName, diagnostics, resolvePackageRootFromEntry3) {
|
|
1513
|
+
try {
|
|
1514
|
+
const entryFile = require2.resolve(packageName);
|
|
1515
|
+
return {
|
|
1516
|
+
entryFile,
|
|
1517
|
+
rootDir: resolvePackageRootFromEntry3(entryFile)
|
|
1518
|
+
};
|
|
1519
|
+
} catch (err) {
|
|
1520
|
+
diagnostics.push({
|
|
1521
|
+
level: "error",
|
|
1522
|
+
source: packageName,
|
|
1523
|
+
message: `bundled plugin package not resolvable: ${String(err)}`
|
|
1524
|
+
});
|
|
1525
|
+
return null;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
function loadBundledPluginModule(entryFile, rootDir) {
|
|
1529
|
+
const pluginJiti = createPluginJiti(buildPluginLoaderAliases(rootDir));
|
|
1530
|
+
return pluginJiti(entryFile);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1344
1533
|
// src/plugins/schema-validator.ts
|
|
1345
1534
|
import AjvPkg from "ajv";
|
|
1346
1535
|
var AjvCtor = AjvPkg;
|
|
@@ -1355,9 +1544,9 @@ function formatAjvErrors(errors) {
|
|
|
1355
1544
|
return ["invalid config"];
|
|
1356
1545
|
}
|
|
1357
1546
|
return errors.map((error) => {
|
|
1358
|
-
const
|
|
1547
|
+
const path10 = error.instancePath?.replace(/^\//, "").replace(/\//g, ".") || "<root>";
|
|
1359
1548
|
const message = error.message ?? "invalid";
|
|
1360
|
-
return `${
|
|
1549
|
+
return `${path10}: ${message}`;
|
|
1361
1550
|
});
|
|
1362
1551
|
}
|
|
1363
1552
|
function validateJsonSchemaValue(params) {
|
|
@@ -1427,7 +1616,7 @@ function validatePluginConfig(params) {
|
|
|
1427
1616
|
}
|
|
1428
1617
|
|
|
1429
1618
|
// src/plugins/registry.ts
|
|
1430
|
-
import
|
|
1619
|
+
import path6 from "path";
|
|
1431
1620
|
import { expandHome as expandHome2 } from "@nextclaw/core";
|
|
1432
1621
|
|
|
1433
1622
|
// src/plugins/plugin-capability-registration.ts
|
|
@@ -1881,10 +2070,10 @@ function registerPluginWithApi(params) {
|
|
|
1881
2070
|
if (!trimmed) {
|
|
1882
2071
|
return params.rootDir;
|
|
1883
2072
|
}
|
|
1884
|
-
if (
|
|
1885
|
-
return
|
|
2073
|
+
if (path6.isAbsolute(trimmed)) {
|
|
2074
|
+
return path6.resolve(expandHome2(trimmed));
|
|
1886
2075
|
}
|
|
1887
|
-
return
|
|
2076
|
+
return path6.resolve(params.rootDir, trimmed);
|
|
1888
2077
|
}
|
|
1889
2078
|
};
|
|
1890
2079
|
try {
|
|
@@ -1912,87 +2101,19 @@ var defaultLogger2 = {
|
|
|
1912
2101
|
debug: (message) => console.debug(message)
|
|
1913
2102
|
};
|
|
1914
2103
|
function resolvePackageRootFromEntry(entryFile) {
|
|
1915
|
-
let cursor =
|
|
2104
|
+
let cursor = path7.dirname(entryFile);
|
|
1916
2105
|
for (let i = 0; i < 8; i += 1) {
|
|
1917
|
-
const candidate =
|
|
1918
|
-
if (
|
|
2106
|
+
const candidate = path7.join(cursor, "package.json");
|
|
2107
|
+
if (fs6.existsSync(candidate)) {
|
|
1919
2108
|
return cursor;
|
|
1920
2109
|
}
|
|
1921
|
-
const parent =
|
|
1922
|
-
if (parent === cursor) {
|
|
1923
|
-
break;
|
|
1924
|
-
}
|
|
1925
|
-
cursor = parent;
|
|
1926
|
-
}
|
|
1927
|
-
return path6.dirname(entryFile);
|
|
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);
|
|
2110
|
+
const parent = path7.dirname(cursor);
|
|
1982
2111
|
if (parent === cursor) {
|
|
1983
2112
|
break;
|
|
1984
2113
|
}
|
|
1985
2114
|
cursor = parent;
|
|
1986
2115
|
}
|
|
1987
|
-
return
|
|
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;
|
|
2116
|
+
return path7.dirname(entryFile);
|
|
1996
2117
|
}
|
|
1997
2118
|
function resolvePluginModuleExport(moduleExport) {
|
|
1998
2119
|
const resolved = moduleExport && typeof moduleExport === "object" && "default" in moduleExport ? moduleExport.default : moduleExport;
|
|
@@ -2011,24 +2132,21 @@ function resolvePluginModuleExport(moduleExport) {
|
|
|
2011
2132
|
return {};
|
|
2012
2133
|
}
|
|
2013
2134
|
function appendBundledChannelPlugins(params) {
|
|
2014
|
-
const require2 =
|
|
2135
|
+
const require2 = createRequire2(import.meta.url);
|
|
2015
2136
|
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
level: "error",
|
|
2024
|
-
source: packageName,
|
|
2025
|
-
message: `bundled plugin package not resolvable: ${String(err)}`
|
|
2026
|
-
});
|
|
2137
|
+
const resolvedEntry = resolveBundledPluginEntry(
|
|
2138
|
+
require2,
|
|
2139
|
+
packageName,
|
|
2140
|
+
params.registry.diagnostics,
|
|
2141
|
+
resolvePackageRootFromEntry
|
|
2142
|
+
);
|
|
2143
|
+
if (!resolvedEntry) {
|
|
2027
2144
|
continue;
|
|
2028
2145
|
}
|
|
2146
|
+
const { entryFile, rootDir } = resolvedEntry;
|
|
2029
2147
|
let moduleExport = null;
|
|
2030
2148
|
try {
|
|
2031
|
-
moduleExport =
|
|
2149
|
+
moduleExport = loadBundledPluginModule(entryFile, rootDir);
|
|
2032
2150
|
} catch (err) {
|
|
2033
2151
|
params.registry.diagnostics.push({
|
|
2034
2152
|
level: "error",
|
|
@@ -2104,6 +2222,10 @@ function appendBundledChannelPlugins(params) {
|
|
|
2104
2222
|
params.registry.plugins.push(record);
|
|
2105
2223
|
}
|
|
2106
2224
|
}
|
|
2225
|
+
function loadExternalPluginModule(candidateSource, pluginRoot) {
|
|
2226
|
+
const pluginJiti = createPluginJiti(buildPluginLoaderAliases(pluginRoot));
|
|
2227
|
+
return pluginJiti(candidateSource);
|
|
2228
|
+
}
|
|
2107
2229
|
function loadOpenClawPlugins(options) {
|
|
2108
2230
|
const loadExternalPlugins = process.env.NEXTCLAW_ENABLE_OPENCLAW_PLUGINS !== "0";
|
|
2109
2231
|
const logger = options.logger ?? defaultLogger2;
|
|
@@ -2138,11 +2260,9 @@ function loadOpenClawPlugins(options) {
|
|
|
2138
2260
|
reservedEngineKinds,
|
|
2139
2261
|
reservedNcpAgentRuntimeKinds
|
|
2140
2262
|
});
|
|
2141
|
-
const jiti = createPluginJiti(buildPluginLoaderAliases());
|
|
2142
2263
|
appendBundledChannelPlugins({
|
|
2143
2264
|
registry,
|
|
2144
2265
|
runtime: registerRuntime,
|
|
2145
|
-
jiti,
|
|
2146
2266
|
normalizedConfig: normalized
|
|
2147
2267
|
});
|
|
2148
2268
|
if (!loadExternalPlugins) {
|
|
@@ -2253,7 +2373,7 @@ function loadOpenClawPlugins(options) {
|
|
|
2253
2373
|
}
|
|
2254
2374
|
let moduleExport = null;
|
|
2255
2375
|
try {
|
|
2256
|
-
moduleExport =
|
|
2376
|
+
moduleExport = loadExternalPluginModule(candidate.source, candidate.rootDir);
|
|
2257
2377
|
} catch (err) {
|
|
2258
2378
|
record.status = "error";
|
|
2259
2379
|
record.error = `failed to load plugin: ${String(err)}`;
|
|
@@ -2324,7 +2444,168 @@ function loadOpenClawPlugins(options) {
|
|
|
2324
2444
|
}
|
|
2325
2445
|
|
|
2326
2446
|
// src/plugins/status.ts
|
|
2447
|
+
import fs7 from "fs";
|
|
2448
|
+
import { createRequire as createRequire3 } from "module";
|
|
2449
|
+
import path8 from "path";
|
|
2327
2450
|
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig2 } from "@nextclaw/core";
|
|
2451
|
+
function createEmptyPluginRegistry() {
|
|
2452
|
+
return {
|
|
2453
|
+
plugins: [],
|
|
2454
|
+
tools: [],
|
|
2455
|
+
channels: [],
|
|
2456
|
+
providers: [],
|
|
2457
|
+
engines: [],
|
|
2458
|
+
ncpAgentRuntimes: [],
|
|
2459
|
+
diagnostics: [],
|
|
2460
|
+
resolvedTools: []
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2463
|
+
function resolvePackageRootFromEntry2(entryFile) {
|
|
2464
|
+
let cursor = path8.dirname(entryFile);
|
|
2465
|
+
for (let index = 0; index < 8; index += 1) {
|
|
2466
|
+
const candidate = path8.join(cursor, "package.json");
|
|
2467
|
+
if (fs7.existsSync(candidate)) {
|
|
2468
|
+
return cursor;
|
|
2469
|
+
}
|
|
2470
|
+
const parent = path8.dirname(cursor);
|
|
2471
|
+
if (parent === cursor) {
|
|
2472
|
+
break;
|
|
2473
|
+
}
|
|
2474
|
+
cursor = parent;
|
|
2475
|
+
}
|
|
2476
|
+
return path8.dirname(entryFile);
|
|
2477
|
+
}
|
|
2478
|
+
function discoverBundledPluginCandidates(workspaceDir, diagnostics) {
|
|
2479
|
+
const require2 = createRequire3(import.meta.url);
|
|
2480
|
+
const candidates = [];
|
|
2481
|
+
for (const packageName of BUNDLED_CHANNEL_PLUGIN_PACKAGES) {
|
|
2482
|
+
try {
|
|
2483
|
+
const entryFile = require2.resolve(packageName);
|
|
2484
|
+
candidates.push({
|
|
2485
|
+
idHint: packageName.split("/").pop() ?? packageName,
|
|
2486
|
+
source: entryFile,
|
|
2487
|
+
rootDir: resolvePackageRootFromEntry2(entryFile),
|
|
2488
|
+
origin: "bundled",
|
|
2489
|
+
workspaceDir,
|
|
2490
|
+
packageName
|
|
2491
|
+
});
|
|
2492
|
+
} catch (error) {
|
|
2493
|
+
diagnostics.push({
|
|
2494
|
+
level: "error",
|
|
2495
|
+
source: packageName,
|
|
2496
|
+
message: `bundled plugin package not resolvable: ${String(error)}`
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
return candidates;
|
|
2501
|
+
}
|
|
2502
|
+
function createRecordFromManifest(manifest, enabled) {
|
|
2503
|
+
return createPluginRecord({
|
|
2504
|
+
id: manifest.id,
|
|
2505
|
+
name: manifest.name ?? manifest.id,
|
|
2506
|
+
description: manifest.description,
|
|
2507
|
+
version: manifest.version,
|
|
2508
|
+
kind: manifest.kind,
|
|
2509
|
+
source: manifest.source,
|
|
2510
|
+
origin: manifest.origin,
|
|
2511
|
+
workspaceDir: manifest.workspaceDir,
|
|
2512
|
+
enabled,
|
|
2513
|
+
configSchema: Boolean(manifest.configSchema),
|
|
2514
|
+
configUiHints: manifest.configUiHints,
|
|
2515
|
+
configJsonSchema: manifest.configSchema
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
function createOverriddenManifestRecord(manifest, existingOrigin) {
|
|
2519
|
+
const record = createRecordFromManifest(manifest, false);
|
|
2520
|
+
record.status = "disabled";
|
|
2521
|
+
record.error = `overridden by ${existingOrigin} plugin`;
|
|
2522
|
+
return record;
|
|
2523
|
+
}
|
|
2524
|
+
function finalizeDiscoveredManifestRecord(params) {
|
|
2525
|
+
const record = createRecordFromManifest(params.manifest, params.enabled);
|
|
2526
|
+
if (!params.enabled) {
|
|
2527
|
+
record.status = "disabled";
|
|
2528
|
+
record.error = params.disabledReason;
|
|
2529
|
+
return { record, diagnostics: [] };
|
|
2530
|
+
}
|
|
2531
|
+
if (!params.manifest.configSchema) {
|
|
2532
|
+
record.status = "error";
|
|
2533
|
+
record.error = "missing config schema";
|
|
2534
|
+
return {
|
|
2535
|
+
record,
|
|
2536
|
+
diagnostics: [
|
|
2537
|
+
{
|
|
2538
|
+
level: "error",
|
|
2539
|
+
pluginId: params.manifest.id,
|
|
2540
|
+
source: params.manifest.source,
|
|
2541
|
+
message: record.error
|
|
2542
|
+
}
|
|
2543
|
+
]
|
|
2544
|
+
};
|
|
2545
|
+
}
|
|
2546
|
+
const validatedConfig = validatePluginConfig({
|
|
2547
|
+
schema: params.manifest.configSchema,
|
|
2548
|
+
cacheKey: params.manifest.schemaCacheKey,
|
|
2549
|
+
value: params.normalizedEntries[params.manifest.id]?.config
|
|
2550
|
+
});
|
|
2551
|
+
if (validatedConfig.ok) {
|
|
2552
|
+
return { record, diagnostics: [] };
|
|
2553
|
+
}
|
|
2554
|
+
record.status = "error";
|
|
2555
|
+
record.error = `invalid config: ${validatedConfig.errors.join(", ")}`;
|
|
2556
|
+
return {
|
|
2557
|
+
record,
|
|
2558
|
+
diagnostics: [
|
|
2559
|
+
{
|
|
2560
|
+
level: "error",
|
|
2561
|
+
pluginId: params.manifest.id,
|
|
2562
|
+
source: params.manifest.source,
|
|
2563
|
+
message: record.error
|
|
2564
|
+
}
|
|
2565
|
+
]
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
function discoverPluginStatusReport(params) {
|
|
2569
|
+
const workspaceDir = params.workspaceDir?.trim() || getWorkspacePathFromConfig2(params.config);
|
|
2570
|
+
const normalized = normalizePluginsConfig(params.config.plugins);
|
|
2571
|
+
const discovery = discoverOpenClawPlugins({
|
|
2572
|
+
config: params.config,
|
|
2573
|
+
workspaceDir,
|
|
2574
|
+
extraPaths: normalized.loadPaths
|
|
2575
|
+
});
|
|
2576
|
+
const bundledDiagnostics = [];
|
|
2577
|
+
const bundledCandidates = discoverBundledPluginCandidates(workspaceDir, bundledDiagnostics);
|
|
2578
|
+
const manifestRegistry = loadPluginManifestRegistry({
|
|
2579
|
+
config: params.config,
|
|
2580
|
+
workspaceDir,
|
|
2581
|
+
candidates: [...bundledCandidates, ...discovery.candidates],
|
|
2582
|
+
diagnostics: [...bundledDiagnostics, ...discovery.diagnostics]
|
|
2583
|
+
});
|
|
2584
|
+
const registry = createEmptyPluginRegistry();
|
|
2585
|
+
const seenIds = /* @__PURE__ */ new Map();
|
|
2586
|
+
registry.diagnostics.push(...manifestRegistry.diagnostics);
|
|
2587
|
+
for (const manifest of manifestRegistry.plugins) {
|
|
2588
|
+
const existingOrigin = seenIds.get(manifest.id);
|
|
2589
|
+
if (existingOrigin) {
|
|
2590
|
+
registry.plugins.push(createOverriddenManifestRecord(manifest, existingOrigin));
|
|
2591
|
+
continue;
|
|
2592
|
+
}
|
|
2593
|
+
const enableState = resolveEnableState(manifest.id, normalized);
|
|
2594
|
+
const { record, diagnostics } = finalizeDiscoveredManifestRecord({
|
|
2595
|
+
manifest,
|
|
2596
|
+
normalizedEntries: normalized.entries,
|
|
2597
|
+
enabled: enableState.enabled,
|
|
2598
|
+
disabledReason: enableState.reason
|
|
2599
|
+
});
|
|
2600
|
+
registry.plugins.push(record);
|
|
2601
|
+
registry.diagnostics.push(...diagnostics);
|
|
2602
|
+
seenIds.set(manifest.id, manifest.origin);
|
|
2603
|
+
}
|
|
2604
|
+
return {
|
|
2605
|
+
workspaceDir,
|
|
2606
|
+
...registry
|
|
2607
|
+
};
|
|
2608
|
+
}
|
|
2328
2609
|
function buildPluginStatusReport(params) {
|
|
2329
2610
|
const workspaceDir = params.workspaceDir?.trim() || getWorkspacePathFromConfig2(params.config);
|
|
2330
2611
|
const registry = loadOpenClawPlugins({
|
|
@@ -2344,9 +2625,9 @@ function buildPluginStatusReport(params) {
|
|
|
2344
2625
|
}
|
|
2345
2626
|
|
|
2346
2627
|
// src/plugins/uninstall.ts
|
|
2347
|
-
import
|
|
2628
|
+
import fs8 from "fs/promises";
|
|
2348
2629
|
import { existsSync, statSync } from "fs";
|
|
2349
|
-
import
|
|
2630
|
+
import path9 from "path";
|
|
2350
2631
|
import { getWorkspacePathFromConfig as getWorkspacePathFromConfig3 } from "@nextclaw/core";
|
|
2351
2632
|
function isLinkedPathInstall(record) {
|
|
2352
2633
|
if (!record || record.source !== "path") {
|
|
@@ -2355,13 +2636,13 @@ function isLinkedPathInstall(record) {
|
|
|
2355
2636
|
if (!record.sourcePath || !record.installPath) {
|
|
2356
2637
|
return true;
|
|
2357
2638
|
}
|
|
2358
|
-
return
|
|
2639
|
+
return path9.resolve(record.sourcePath) === path9.resolve(record.installPath);
|
|
2359
2640
|
}
|
|
2360
2641
|
function pushUniquePath(targets, candidate) {
|
|
2361
2642
|
if (!candidate) {
|
|
2362
2643
|
return;
|
|
2363
2644
|
}
|
|
2364
|
-
const resolved =
|
|
2645
|
+
const resolved = path9.resolve(candidate);
|
|
2365
2646
|
if (!targets.includes(resolved)) {
|
|
2366
2647
|
targets.push(resolved);
|
|
2367
2648
|
}
|
|
@@ -2383,7 +2664,7 @@ function resolveUninstallDirectoryTarget(params) {
|
|
|
2383
2664
|
if (!configuredPath) {
|
|
2384
2665
|
return defaultPath;
|
|
2385
2666
|
}
|
|
2386
|
-
if (
|
|
2667
|
+
if (path9.resolve(configuredPath) === path9.resolve(defaultPath)) {
|
|
2387
2668
|
return configuredPath;
|
|
2388
2669
|
}
|
|
2389
2670
|
return defaultPath;
|
|
@@ -2404,7 +2685,7 @@ function resolveUninstallDirectoryTargets(params) {
|
|
|
2404
2685
|
);
|
|
2405
2686
|
pushUniquePath(targets, params.installRecord?.installPath);
|
|
2406
2687
|
const workspaceDir = getWorkspacePathFromConfig3(params.config);
|
|
2407
|
-
pushUniquePath(targets,
|
|
2688
|
+
pushUniquePath(targets, path9.join(workspaceDir, ".nextclaw", "extensions", params.pluginId));
|
|
2408
2689
|
return targets;
|
|
2409
2690
|
}
|
|
2410
2691
|
function removePluginFromConfig(config, pluginId) {
|
|
@@ -2485,13 +2766,13 @@ function matchesPluginLoadPath(rawPath, pluginId) {
|
|
|
2485
2766
|
if (!normalizedPath) {
|
|
2486
2767
|
return false;
|
|
2487
2768
|
}
|
|
2488
|
-
const resolvedPath =
|
|
2769
|
+
const resolvedPath = path9.resolve(normalizedPath);
|
|
2489
2770
|
if (!existsSync(resolvedPath)) {
|
|
2490
2771
|
return false;
|
|
2491
2772
|
}
|
|
2492
2773
|
const candidateRoot = (() => {
|
|
2493
2774
|
try {
|
|
2494
|
-
return statSync(resolvedPath).isDirectory() ? resolvedPath :
|
|
2775
|
+
return statSync(resolvedPath).isDirectory() ? resolvedPath : path9.dirname(resolvedPath);
|
|
2495
2776
|
} catch {
|
|
2496
2777
|
return null;
|
|
2497
2778
|
}
|
|
@@ -2525,9 +2806,9 @@ async function uninstallPlugin(params) {
|
|
|
2525
2806
|
extensionsDir
|
|
2526
2807
|
}) : [];
|
|
2527
2808
|
for (const deleteTarget of deleteTargets) {
|
|
2528
|
-
const existed = await
|
|
2809
|
+
const existed = await fs8.access(deleteTarget).then(() => true).catch(() => false);
|
|
2529
2810
|
try {
|
|
2530
|
-
await
|
|
2811
|
+
await fs8.rm(deleteTarget, { recursive: true, force: true });
|
|
2531
2812
|
actions.directory = actions.directory || existed;
|
|
2532
2813
|
} catch (error) {
|
|
2533
2814
|
warnings.push(
|
|
@@ -2558,6 +2839,7 @@ export {
|
|
|
2558
2839
|
createPluginRuntime,
|
|
2559
2840
|
disablePluginInConfig,
|
|
2560
2841
|
discoverOpenClawPlugins,
|
|
2842
|
+
discoverPluginStatusReport,
|
|
2561
2843
|
emptyPluginConfigSchema,
|
|
2562
2844
|
enablePluginInConfig,
|
|
2563
2845
|
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.20",
|
|
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-dingtalk": "0.2.
|
|
23
|
-
"@nextclaw/channel-plugin-
|
|
24
|
-
"@nextclaw/channel-plugin-
|
|
25
|
-
"@nextclaw/channel-plugin-
|
|
26
|
-
"@nextclaw/channel-plugin-qq": "0.2.
|
|
27
|
-
"@nextclaw/channel-plugin-
|
|
28
|
-
"@nextclaw/channel-plugin-
|
|
29
|
-
"@nextclaw/channel-plugin-
|
|
30
|
-
"@nextclaw/channel-plugin-
|
|
31
|
-
"@nextclaw/channel-runtime": "0.2.12",
|
|
22
|
+
"@nextclaw/channel-plugin-dingtalk": "0.2.13",
|
|
23
|
+
"@nextclaw/channel-plugin-email": "0.2.13",
|
|
24
|
+
"@nextclaw/channel-plugin-mochat": "0.2.13",
|
|
25
|
+
"@nextclaw/channel-plugin-feishu": "0.2.14",
|
|
26
|
+
"@nextclaw/channel-plugin-qq": "0.2.13",
|
|
27
|
+
"@nextclaw/channel-plugin-telegram": "0.2.13",
|
|
28
|
+
"@nextclaw/channel-plugin-discord": "0.2.13",
|
|
29
|
+
"@nextclaw/channel-plugin-slack": "0.2.13",
|
|
30
|
+
"@nextclaw/channel-plugin-whatsapp": "0.2.13",
|
|
32
31
|
"@nextclaw/ncp": "0.3.2",
|
|
32
|
+
"@nextclaw/core": "0.10.0",
|
|
33
|
+
"@nextclaw/channel-runtime": "0.3.0",
|
|
33
34
|
"@nextclaw/ncp-toolkit": "0.4.2",
|
|
34
|
-
"@nextclaw/
|
|
35
|
-
"@nextclaw/channel-plugin-
|
|
36
|
-
"@nextclaw/channel-plugin-mochat": "0.2.12"
|
|
35
|
+
"@nextclaw/channel-plugin-weixin": "0.1.7",
|
|
36
|
+
"@nextclaw/channel-plugin-wecom": "0.2.13"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^20.17.6",
|