@nextclaw/service 0.1.10 → 0.1.12
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/cli/commands/agent/agent-runtime.utils.d.ts +1 -2
- package/dist/cli/commands/agent/agent-runtime.utils.js +6 -50
- package/dist/cli/commands/agent/cli-agent-runner.utils.d.ts +0 -7
- package/dist/cli/commands/agent/cli-agent-runner.utils.js +7 -9
- package/dist/cli/commands/agent/services/agent-commands.service.js +0 -1
- package/dist/cli/commands/skills/index.js +1 -1
- package/dist/cli/commands/skills/marketplace-client.d.ts +11 -1
- package/dist/cli/commands/skills/marketplace-client.js +39 -1
- package/dist/cli/commands/skills/marketplace-command-options.utils.d.ts +1 -1
- package/dist/cli/commands/skills/marketplace.metadata.d.ts +3 -12
- package/dist/cli/commands/skills/marketplace.metadata.js +1 -87
- package/dist/cli/commands/skills/{marketplace.service.d.ts → marketplace.utils.d.ts} +1 -1
- package/dist/cli/commands/skills/{marketplace.service.js → marketplace.utils.js} +11 -47
- package/dist/cli/commands/skills/skills-query.service.d.ts +5 -37
- package/dist/cli/commands/skills/skills-query.service.js +16 -98
- package/dist/cli/commands/usage/services/llm-usage-command.service.d.ts +3 -5
- package/dist/cli/commands/usage/services/llm-usage-command.service.js +16 -26
- package/dist/commands/channel/channel-list-view.service.d.ts +7 -14
- package/dist/commands/channel/channel-list-view.service.js +20 -41
- package/dist/commands/channel/index.js +3 -9
- package/dist/commands/plugin/index.d.ts +2 -4
- package/dist/commands/plugin/index.js +8 -20
- package/dist/commands/plugin/{plugin-command-utils.d.ts → plugin-command.utils.d.ts} +1 -2
- package/dist/commands/plugin/{plugin-command-utils.js → plugin-command.utils.js} +2 -4
- package/dist/commands/plugin/{plugin-mutation-actions.d.ts → plugin-mutation-actions.utils.d.ts} +1 -1
- package/dist/commands/plugin/{plugin-mutation-actions.js → plugin-mutation-actions.utils.js} +2 -2
- package/dist/commands/service/services/autostart/linux-systemd-autostart.service.js +1 -1
- package/dist/commands/service/services/autostart/macos-launch-agent-autostart.service.js +1 -1
- package/dist/commands/service/services/autostart/windows-task-autostart.service.js +1 -1
- package/dist/launcher/npm-runtime-launcher.service.js +1 -1
- package/dist/service-runtime.service.d.ts +1 -1
- package/dist/service-runtime.service.js +7 -22
- package/dist/shared/controllers/gateway.controller.d.ts +3 -11
- package/dist/shared/controllers/gateway.controller.js +24 -180
- package/dist/shared/services/gateway/managers/gateway-plugin.manager.d.ts +3 -9
- package/dist/shared/services/gateway/managers/gateway-plugin.manager.js +30 -88
- package/dist/shared/services/gateway/nextclaw-app.service.d.ts +2 -7
- package/dist/shared/services/gateway/nextclaw-app.service.js +6 -16
- package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.d.ts +4 -9
- package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.js +12 -46
- package/dist/shared/services/gateway/{cron-job-handler.service.d.ts → utils/cron-job-handler.utils.d.ts} +3 -6
- package/dist/shared/services/gateway/utils/cron-job-handler.utils.js +57 -0
- package/dist/shared/services/marketplace/service-marketplace-installer.service.js +3 -3
- package/dist/shared/services/plugin/utils/plugin-runtime-bridge.utils.js +1 -1
- package/dist/shared/services/runtime/runtime-command.service.js +2 -2
- package/dist/shared/services/runtime/service-managed-startup.service.js +1 -1
- package/dist/shared/services/ui/companion-runtime.service.js +1 -1
- package/dist/shared/services/workspace/workspace-manager.service.js +8 -10
- package/dist/shared/utils/cli.utils.js +1 -1
- package/package.json +20 -20
- package/dist/cli/commands/usage/services/llm-usage-query.service.d.ts +0 -43
- package/dist/cli/commands/usage/services/llm-usage-query.service.js +0 -85
- package/dist/commands/plugin/development-source/dev-plugin-overrides.utils.d.ts +0 -18
- package/dist/commands/plugin/development-source/dev-plugin-overrides.utils.js +0 -111
- package/dist/commands/plugin/development-source/first-party-plugin-load-paths.utils.d.ts +0 -9
- package/dist/commands/plugin/development-source/first-party-plugin-load-paths.utils.js +0 -183
- package/dist/commands/plugin/plugin-extension-registry.d.ts +0 -10
- package/dist/commands/plugin/plugin-extension-registry.js +0 -35
- package/dist/commands/plugin/plugin-registry-loader.utils.d.ts +0 -15
- package/dist/commands/plugin/plugin-registry-loader.utils.js +0 -43
- package/dist/commands/plugin/plugin-reload.d.ts +0 -13
- package/dist/commands/plugin/plugin-reload.js +0 -42
- package/dist/shared/services/extensions/extension-lifecycle.service.d.ts +0 -63
- package/dist/shared/services/extensions/extension-lifecycle.service.js +0 -174
- package/dist/shared/services/extensions/service-extension-runtime.service.d.ts +0 -52
- package/dist/shared/services/extensions/service-extension-runtime.service.js +0 -325
- package/dist/shared/services/gateway/cron-job-handler.service.js +0 -100
- package/dist/shared/services/runtime/utils/skills-loader.utils.d.ts +0 -12
- package/dist/shared/services/runtime/utils/skills-loader.utils.js +0 -9
- package/dist/shared/services/session/service-deferred-ncp-agent.service.d.ts +0 -14
- package/dist/shared/services/session/service-deferred-ncp-agent.service.js +0 -85
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { applyDevFirstPartyPluginLoadPaths, resolveDevFirstPartyPluginInstallRoots } from "./first-party-plugin-load-paths.utils.js";
|
|
2
|
-
import { getPackageManifestExtensions, loadPluginManifest } from "@nextclaw/openclaw-compat";
|
|
3
|
-
import fs from "node:fs";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
//#region src/commands/plugin/development-source/dev-plugin-overrides.utils.ts
|
|
6
|
-
const DEV_PLUGIN_OVERRIDES_ENV = "NEXTCLAW_DEV_PLUGIN_OVERRIDES";
|
|
7
|
-
function isRecord(value) {
|
|
8
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9
|
-
}
|
|
10
|
-
function readOptionalString(value) {
|
|
11
|
-
if (typeof value !== "string") return;
|
|
12
|
-
return value.trim() || void 0;
|
|
13
|
-
}
|
|
14
|
-
function readPackageManifest(pluginPath) {
|
|
15
|
-
const packageJsonPath = path.join(pluginPath, "package.json");
|
|
16
|
-
if (!fs.existsSync(packageJsonPath)) return null;
|
|
17
|
-
try {
|
|
18
|
-
return JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
19
|
-
} catch {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function assertOverridePluginReadable(override) {
|
|
24
|
-
if (!fs.existsSync(override.pluginPath)) throw new Error(`[dev-plugin-override] plugin path does not exist for "${override.pluginId}": ${override.pluginPath}`);
|
|
25
|
-
const packageManifest = readPackageManifest(override.pluginPath);
|
|
26
|
-
if (!packageManifest) throw new Error(`[dev-plugin-override] package.json is missing or invalid for "${override.pluginId}": ${override.pluginPath}`);
|
|
27
|
-
const pluginManifest = loadPluginManifest(override.pluginPath);
|
|
28
|
-
if (!pluginManifest.ok) throw new Error(`[dev-plugin-override] ${pluginManifest.error} for "${override.pluginId}": ${override.pluginPath}`);
|
|
29
|
-
if (pluginManifest.manifest.id !== override.pluginId) throw new Error(`[dev-plugin-override] plugin id mismatch: expected "${override.pluginId}" but found "${pluginManifest.manifest.id}" at ${override.pluginPath}`);
|
|
30
|
-
if (getPackageManifestExtensions(packageManifest, override.source).length === 0) {
|
|
31
|
-
const missingEntry = override.source === "development" ? "openclaw.development.extensions" : "openclaw.extensions";
|
|
32
|
-
throw new Error(`[dev-plugin-override] ${missingEntry} is missing for "${override.pluginId}" at ${override.pluginPath}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function readOverrideRecord(value, index) {
|
|
36
|
-
if (!isRecord(value)) throw new Error(`[dev-plugin-override] override[${index}] must be an object`);
|
|
37
|
-
const pluginId = readOptionalString(value.pluginId);
|
|
38
|
-
const pluginPath = readOptionalString(value.pluginPath);
|
|
39
|
-
const source = value.source === "development" ? "development" : "production";
|
|
40
|
-
if (!pluginId || !pluginPath) throw new Error(`[dev-plugin-override] override[${index}] requires pluginId and pluginPath`);
|
|
41
|
-
const normalized = {
|
|
42
|
-
pluginId,
|
|
43
|
-
pluginPath: path.resolve(pluginPath),
|
|
44
|
-
source
|
|
45
|
-
};
|
|
46
|
-
assertOverridePluginReadable(normalized);
|
|
47
|
-
return normalized;
|
|
48
|
-
}
|
|
49
|
-
function resolveDevPluginOverrides(rawEnv = process.env[DEV_PLUGIN_OVERRIDES_ENV]) {
|
|
50
|
-
if (typeof rawEnv !== "string" || rawEnv.trim().length === 0) return [];
|
|
51
|
-
let parsed;
|
|
52
|
-
try {
|
|
53
|
-
parsed = JSON.parse(rawEnv);
|
|
54
|
-
} catch (error) {
|
|
55
|
-
throw new Error(`[dev-plugin-override] failed to parse ${DEV_PLUGIN_OVERRIDES_ENV}: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
-
}
|
|
57
|
-
if (!Array.isArray(parsed)) throw new Error(`[dev-plugin-override] ${DEV_PLUGIN_OVERRIDES_ENV} must be a JSON array`);
|
|
58
|
-
const seenPluginIds = /* @__PURE__ */ new Set();
|
|
59
|
-
const overrides = parsed.map((entry, index) => readOverrideRecord(entry, index));
|
|
60
|
-
for (const entry of overrides) {
|
|
61
|
-
if (seenPluginIds.has(entry.pluginId)) throw new Error(`[dev-plugin-override] duplicate plugin override for "${entry.pluginId}"`);
|
|
62
|
-
seenPluginIds.add(entry.pluginId);
|
|
63
|
-
}
|
|
64
|
-
return overrides;
|
|
65
|
-
}
|
|
66
|
-
function mergeLoadPaths(existingLoadPaths, overrideLoadPaths) {
|
|
67
|
-
const merged = [...overrideLoadPaths];
|
|
68
|
-
for (const entry of existingLoadPaths) if (!merged.includes(entry)) merged.push(entry);
|
|
69
|
-
return merged;
|
|
70
|
-
}
|
|
71
|
-
function applyExplicitDevPluginOverrides(config, overrides) {
|
|
72
|
-
if (overrides.length === 0) return config;
|
|
73
|
-
const nextEntries = { ...config.plugins.entries ?? {} };
|
|
74
|
-
for (const override of overrides) nextEntries[override.pluginId] = {
|
|
75
|
-
...nextEntries[override.pluginId] ?? {},
|
|
76
|
-
source: override.source
|
|
77
|
-
};
|
|
78
|
-
const existingLoadPaths = Array.isArray(config.plugins.load?.paths) ? config.plugins.load.paths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
79
|
-
return {
|
|
80
|
-
...config,
|
|
81
|
-
plugins: {
|
|
82
|
-
...config.plugins,
|
|
83
|
-
entries: nextEntries,
|
|
84
|
-
load: {
|
|
85
|
-
...config.plugins.load,
|
|
86
|
-
paths: mergeLoadPaths(existingLoadPaths, overrides.map((entry) => entry.pluginPath))
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function resolveDevPluginOverrideInstallRoots(config, overrides) {
|
|
92
|
-
const installRoots = [];
|
|
93
|
-
for (const override of overrides) {
|
|
94
|
-
const installRecord = config.plugins.installs?.[override.pluginId];
|
|
95
|
-
const installPath = readOptionalString(installRecord?.installPath);
|
|
96
|
-
if (!installPath || installRoots.includes(installPath)) continue;
|
|
97
|
-
installRoots.push(installPath);
|
|
98
|
-
}
|
|
99
|
-
return installRoots;
|
|
100
|
-
}
|
|
101
|
-
function resolveDevPluginLoadingContext(config, workspaceExtensionsDir, rawOverridesEnv = process.env[DEV_PLUGIN_OVERRIDES_ENV]) {
|
|
102
|
-
const configWithFirstPartyOverrides = applyDevFirstPartyPluginLoadPaths(config, workspaceExtensionsDir);
|
|
103
|
-
const overrides = resolveDevPluginOverrides(rawOverridesEnv);
|
|
104
|
-
return {
|
|
105
|
-
configWithDevPluginOverrides: applyExplicitDevPluginOverrides(configWithFirstPartyOverrides, overrides),
|
|
106
|
-
excludedRoots: [...resolveDevFirstPartyPluginInstallRoots(config, workspaceExtensionsDir), ...resolveDevPluginOverrideInstallRoots(config, overrides)].filter((entry, index, list) => list.indexOf(entry) === index),
|
|
107
|
-
overrides
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
//#endregion
|
|
111
|
-
export { DEV_PLUGIN_OVERRIDES_ENV, resolveDevPluginLoadingContext, resolveDevPluginOverrides };
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Config } from "@nextclaw/core";
|
|
2
|
-
|
|
3
|
-
//#region src/commands/plugin/development-source/first-party-plugin-load-paths.utils.d.ts
|
|
4
|
-
declare const resolveDevFirstPartyPluginDir: (explicitDir: string | undefined, moduleDir?: string) => string | undefined;
|
|
5
|
-
declare const resolveDevFirstPartyPluginLoadPaths: (config: Config, workspaceExtensionsDir: string | undefined) => string[];
|
|
6
|
-
declare const resolveDevFirstPartyPluginInstallRoots: (config: Config, workspaceExtensionsDir: string | undefined) => string[];
|
|
7
|
-
declare const applyDevFirstPartyPluginLoadPaths: (config: Config, workspaceExtensionsDir: string | undefined) => Config;
|
|
8
|
-
//#endregion
|
|
9
|
-
export { applyDevFirstPartyPluginLoadPaths, resolveDevFirstPartyPluginDir, resolveDevFirstPartyPluginInstallRoots, resolveDevFirstPartyPluginLoadPaths };
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { getDataPath } from "@nextclaw/core";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
//#region src/commands/plugin/development-source/first-party-plugin-load-paths.utils.ts
|
|
6
|
-
const readJsonFile = (filePath) => {
|
|
7
|
-
try {
|
|
8
|
-
const raw = fs.readFileSync(filePath, "utf-8");
|
|
9
|
-
const parsed = JSON.parse(raw);
|
|
10
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
11
|
-
} catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
const readString = (value) => {
|
|
16
|
-
if (typeof value !== "string") return;
|
|
17
|
-
return value.trim() || void 0;
|
|
18
|
-
};
|
|
19
|
-
const toPluginIdFromPackageName = (packageName) => {
|
|
20
|
-
const trimmed = packageName.trim();
|
|
21
|
-
if (!trimmed) return "";
|
|
22
|
-
return trimmed.includes("/") ? trimmed.split("/").pop() ?? trimmed : trimmed;
|
|
23
|
-
};
|
|
24
|
-
const normalizeInstallRecordPath = (value) => {
|
|
25
|
-
const filePath = readString(value);
|
|
26
|
-
return filePath ? path.resolve(filePath) : void 0;
|
|
27
|
-
};
|
|
28
|
-
const resolveDevFirstPartyPluginDir = (explicitDir, moduleDir = path.dirname(fileURLToPath(import.meta.url))) => {
|
|
29
|
-
const configured = explicitDir?.trim();
|
|
30
|
-
if (configured) return configured;
|
|
31
|
-
const inferred = path.resolve(moduleDir, "../../../../../extensions");
|
|
32
|
-
return fs.existsSync(inferred) ? inferred : void 0;
|
|
33
|
-
};
|
|
34
|
-
const hasOpenClawExtensions = (pkg) => {
|
|
35
|
-
const openclaw = pkg.openclaw;
|
|
36
|
-
if (!openclaw || typeof openclaw !== "object" || Array.isArray(openclaw)) return false;
|
|
37
|
-
const extensions = openclaw.extensions;
|
|
38
|
-
return Array.isArray(extensions) && extensions.some((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
39
|
-
};
|
|
40
|
-
const hasOpenClawDevelopmentExtensions = (pkg) => {
|
|
41
|
-
const openclaw = pkg.openclaw;
|
|
42
|
-
if (!openclaw || typeof openclaw !== "object" || Array.isArray(openclaw)) return false;
|
|
43
|
-
const development = openclaw.development;
|
|
44
|
-
if (!development || typeof development !== "object" || Array.isArray(development)) return false;
|
|
45
|
-
const extensions = development.extensions;
|
|
46
|
-
return Array.isArray(extensions) && extensions.some((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
47
|
-
};
|
|
48
|
-
const normalizePackageSpec = (spec) => {
|
|
49
|
-
const trimmed = spec.trim();
|
|
50
|
-
if (!trimmed) return;
|
|
51
|
-
if (trimmed.startsWith("@")) {
|
|
52
|
-
const slashIndex = trimmed.indexOf("/");
|
|
53
|
-
if (slashIndex < 0) return;
|
|
54
|
-
const secondAtIndex = trimmed.indexOf("@", slashIndex + 1);
|
|
55
|
-
return secondAtIndex < 0 ? trimmed : trimmed.slice(0, secondAtIndex);
|
|
56
|
-
}
|
|
57
|
-
const versionIndex = trimmed.indexOf("@");
|
|
58
|
-
return versionIndex < 0 ? trimmed : trimmed.slice(0, versionIndex);
|
|
59
|
-
};
|
|
60
|
-
const readWorkspacePluginPackages = (workspaceExtensionsDir) => {
|
|
61
|
-
if (!workspaceExtensionsDir.trim() || !fs.existsSync(workspaceExtensionsDir)) return [];
|
|
62
|
-
const entries = fs.readdirSync(workspaceExtensionsDir, { withFileTypes: true });
|
|
63
|
-
const packages = [];
|
|
64
|
-
for (const entry of entries) {
|
|
65
|
-
if (!entry.isDirectory()) continue;
|
|
66
|
-
const packageDir = path.join(workspaceExtensionsDir, entry.name);
|
|
67
|
-
const pkg = readJsonFile(path.join(packageDir, "package.json"));
|
|
68
|
-
if (!pkg || !hasOpenClawExtensions(pkg)) continue;
|
|
69
|
-
const packageName = readString(pkg.name);
|
|
70
|
-
if (!packageName?.startsWith("@nextclaw/")) continue;
|
|
71
|
-
packages.push({
|
|
72
|
-
pluginId: toPluginIdFromPackageName(packageName),
|
|
73
|
-
packageName,
|
|
74
|
-
dir: packageDir,
|
|
75
|
-
supportsDevelopmentSource: hasOpenClawDevelopmentExtensions(pkg)
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
return packages;
|
|
79
|
-
};
|
|
80
|
-
const readInstalledFirstPartyPluginMatches = (workspaceExtensionsDir) => {
|
|
81
|
-
const workspacePackages = readWorkspacePluginPackages(workspaceExtensionsDir);
|
|
82
|
-
if (workspacePackages.length === 0) return [];
|
|
83
|
-
const globalExtensionsDir = path.join(getDataPath(), "extensions");
|
|
84
|
-
if (!fs.existsSync(globalExtensionsDir)) return [];
|
|
85
|
-
const workspacePackageByName = new Map(workspacePackages.map((entry) => [entry.packageName, entry]));
|
|
86
|
-
const entries = fs.readdirSync(globalExtensionsDir, { withFileTypes: true });
|
|
87
|
-
const matches = [];
|
|
88
|
-
for (const entry of entries) {
|
|
89
|
-
if (!entry.isDirectory()) continue;
|
|
90
|
-
const packageDir = path.join(globalExtensionsDir, entry.name);
|
|
91
|
-
const packageName = readString(readJsonFile(path.join(packageDir, "package.json"))?.name);
|
|
92
|
-
if (!packageName) continue;
|
|
93
|
-
const workspacePackage = workspacePackageByName.get(packageName);
|
|
94
|
-
if (!workspacePackage) continue;
|
|
95
|
-
matches.push({
|
|
96
|
-
packageName,
|
|
97
|
-
workspaceDir: workspacePackage.dir,
|
|
98
|
-
installPath: packageDir
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
return matches;
|
|
102
|
-
};
|
|
103
|
-
const mergeLoadPaths = (existingLoadPaths, devLoadPaths) => {
|
|
104
|
-
const mergedLoadPaths = [...devLoadPaths];
|
|
105
|
-
for (const entry of existingLoadPaths) if (!mergedLoadPaths.includes(entry)) mergedLoadPaths.push(entry);
|
|
106
|
-
return mergedLoadPaths;
|
|
107
|
-
};
|
|
108
|
-
const findWorkspacePackageForInstallRecord = (installRecord, workspacePackages, packageByName) => {
|
|
109
|
-
const packageName = normalizePackageSpec(readString(installRecord.spec) ?? "");
|
|
110
|
-
if (packageName) {
|
|
111
|
-
const matchedByPackageName = packageByName.get(packageName);
|
|
112
|
-
if (matchedByPackageName) return matchedByPackageName;
|
|
113
|
-
}
|
|
114
|
-
const installPathCandidates = new Set([installRecord.sourcePath, installRecord.installPath].map(normalizeInstallRecordPath).filter((entry) => Boolean(entry)));
|
|
115
|
-
if (installPathCandidates.size === 0) return;
|
|
116
|
-
return workspacePackages.find((workspacePackage) => installPathCandidates.has(path.resolve(workspacePackage.dir)));
|
|
117
|
-
};
|
|
118
|
-
const resolveDevFirstPartyPluginLoadPaths = (config, workspaceExtensionsDir) => {
|
|
119
|
-
const rootDir = resolveDevFirstPartyPluginDir(workspaceExtensionsDir);
|
|
120
|
-
if (!rootDir) return [];
|
|
121
|
-
const workspacePackages = readWorkspacePluginPackages(rootDir);
|
|
122
|
-
if (workspacePackages.length === 0) return [];
|
|
123
|
-
const installedPluginMatches = readInstalledFirstPartyPluginMatches(rootDir);
|
|
124
|
-
const packageDirByName = new Map(workspacePackages.map((entry) => [entry.packageName, entry.dir]));
|
|
125
|
-
const packageByName = new Map(workspacePackages.map((entry) => [entry.packageName, entry]));
|
|
126
|
-
const loadPaths = [];
|
|
127
|
-
const installs = config.plugins.installs ?? {};
|
|
128
|
-
for (const installRecord of Object.values(installs)) {
|
|
129
|
-
const matchedWorkspacePackage = findWorkspacePackageForInstallRecord(installRecord, workspacePackages, packageByName);
|
|
130
|
-
const packageDir = matchedWorkspacePackage ? matchedWorkspacePackage.dir : packageDirByName.get(normalizePackageSpec(readString(installRecord.spec) ?? "") ?? "");
|
|
131
|
-
if (!packageDir || loadPaths.includes(packageDir)) continue;
|
|
132
|
-
loadPaths.push(packageDir);
|
|
133
|
-
}
|
|
134
|
-
for (const installedPlugin of installedPluginMatches) {
|
|
135
|
-
if (loadPaths.includes(installedPlugin.workspaceDir)) continue;
|
|
136
|
-
loadPaths.push(installedPlugin.workspaceDir);
|
|
137
|
-
}
|
|
138
|
-
return loadPaths;
|
|
139
|
-
};
|
|
140
|
-
const resolveDevFirstPartyPluginInstallRoots = (config, workspaceExtensionsDir) => {
|
|
141
|
-
const rootDir = resolveDevFirstPartyPluginDir(workspaceExtensionsDir);
|
|
142
|
-
if (!rootDir) return [];
|
|
143
|
-
const workspacePackages = readWorkspacePluginPackages(rootDir);
|
|
144
|
-
if (workspacePackages.length === 0) return [];
|
|
145
|
-
const packageNames = new Set(workspacePackages.map((entry) => entry.packageName));
|
|
146
|
-
const packageByName = new Map(workspacePackages.map((entry) => [entry.packageName, entry]));
|
|
147
|
-
const installRoots = [];
|
|
148
|
-
const installedPluginMatches = readInstalledFirstPartyPluginMatches(rootDir);
|
|
149
|
-
for (const installedPlugin of installedPluginMatches) {
|
|
150
|
-
if (installRoots.includes(installedPlugin.installPath)) continue;
|
|
151
|
-
installRoots.push(installedPlugin.installPath);
|
|
152
|
-
}
|
|
153
|
-
for (const installRecord of Object.values(config.plugins.installs ?? {})) {
|
|
154
|
-
const workspacePackage = findWorkspacePackageForInstallRecord(installRecord, workspacePackages, packageByName);
|
|
155
|
-
const packageName = normalizePackageSpec(readString(installRecord.spec) ?? "");
|
|
156
|
-
if (!workspacePackage && (!packageName || !packageNames.has(packageName))) continue;
|
|
157
|
-
const installPath = readString(installRecord.installPath);
|
|
158
|
-
if (!installPath || installRoots.includes(installPath)) continue;
|
|
159
|
-
if (workspacePackage && path.resolve(installPath) === path.resolve(workspacePackage.dir)) continue;
|
|
160
|
-
installRoots.push(installPath);
|
|
161
|
-
}
|
|
162
|
-
return installRoots;
|
|
163
|
-
};
|
|
164
|
-
const applyDevFirstPartyPluginLoadPaths = (config, workspaceExtensionsDir) => {
|
|
165
|
-
const rootDir = resolveDevFirstPartyPluginDir(workspaceExtensionsDir);
|
|
166
|
-
if (!rootDir) return config;
|
|
167
|
-
if (readWorkspacePluginPackages(rootDir).length === 0) return config;
|
|
168
|
-
const devLoadPaths = resolveDevFirstPartyPluginLoadPaths(config, rootDir);
|
|
169
|
-
if (devLoadPaths.length === 0) return config;
|
|
170
|
-
const mergedLoadPaths = mergeLoadPaths(Array.isArray(config.plugins.load?.paths) ? config.plugins.load.paths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [], devLoadPaths);
|
|
171
|
-
return {
|
|
172
|
-
...config,
|
|
173
|
-
plugins: {
|
|
174
|
-
...config.plugins,
|
|
175
|
-
load: {
|
|
176
|
-
...config.plugins.load,
|
|
177
|
-
paths: mergedLoadPaths
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
};
|
|
182
|
-
//#endregion
|
|
183
|
-
export { applyDevFirstPartyPluginLoadPaths, resolveDevFirstPartyPluginDir, resolveDevFirstPartyPluginInstallRoots, resolveDevFirstPartyPluginLoadPaths };
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ExtensionRegistry } from "@nextclaw/core";
|
|
2
|
-
import { PluginNcpAgentRuntimeRegistration, PluginRegistry } from "@nextclaw/openclaw-compat";
|
|
3
|
-
|
|
4
|
-
//#region src/commands/plugin/plugin-extension-registry.d.ts
|
|
5
|
-
type NextclawExtensionRegistry = ExtensionRegistry & {
|
|
6
|
-
ncpAgentRuntimes: PluginNcpAgentRuntimeRegistration[];
|
|
7
|
-
};
|
|
8
|
-
declare function toExtensionRegistry(pluginRegistry: PluginRegistry): NextclawExtensionRegistry;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { NextclawExtensionRegistry, toExtensionRegistry };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
//#region src/commands/plugin/plugin-extension-registry.ts
|
|
2
|
-
function toExtensionRegistry(pluginRegistry) {
|
|
3
|
-
return {
|
|
4
|
-
tools: pluginRegistry.tools.map((tool) => ({
|
|
5
|
-
extensionId: tool.pluginId,
|
|
6
|
-
factory: tool.factory,
|
|
7
|
-
names: tool.names,
|
|
8
|
-
optional: tool.optional,
|
|
9
|
-
source: tool.source
|
|
10
|
-
})),
|
|
11
|
-
channels: pluginRegistry.channels.map((channel) => ({
|
|
12
|
-
extensionId: channel.pluginId,
|
|
13
|
-
channel: channel.channel,
|
|
14
|
-
source: channel.source
|
|
15
|
-
})),
|
|
16
|
-
ncpAgentRuntimes: pluginRegistry.ncpAgentRuntimes.map((runtime) => ({
|
|
17
|
-
pluginId: runtime.pluginId,
|
|
18
|
-
kind: runtime.kind,
|
|
19
|
-
label: runtime.label,
|
|
20
|
-
createRuntime: runtime.createRuntime,
|
|
21
|
-
createRuntimeForEntry: runtime.createRuntimeForEntry,
|
|
22
|
-
describeSessionType: runtime.describeSessionType,
|
|
23
|
-
describeSessionTypeForEntry: runtime.describeSessionTypeForEntry,
|
|
24
|
-
source: runtime.source
|
|
25
|
-
})),
|
|
26
|
-
diagnostics: pluginRegistry.diagnostics.map((diag) => ({
|
|
27
|
-
level: diag.level,
|
|
28
|
-
message: diag.message,
|
|
29
|
-
extensionId: diag.pluginId,
|
|
30
|
-
source: diag.source
|
|
31
|
-
}))
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
export { toExtensionRegistry };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Config } from "@nextclaw/core";
|
|
2
|
-
import * as _$_nextclaw_openclaw_compat0 from "@nextclaw/openclaw-compat";
|
|
3
|
-
import { PluginRegistry } from "@nextclaw/openclaw-compat";
|
|
4
|
-
|
|
5
|
-
//#region src/commands/plugin/plugin-registry-loader.utils.d.ts
|
|
6
|
-
declare function loadPluginRegistryProgressively(config: Config, workspaceDir: string, options?: {
|
|
7
|
-
onPluginProcessed?: (params: {
|
|
8
|
-
loadedPluginCount: number;
|
|
9
|
-
pluginId?: string;
|
|
10
|
-
}) => void;
|
|
11
|
-
}): Promise<PluginRegistry>;
|
|
12
|
-
declare function discoverPluginRegistryStatus(config: Config, workspaceDir: string): _$_nextclaw_openclaw_compat0.PluginStatusReport;
|
|
13
|
-
declare function createEmptyPluginRegistry(): PluginRegistry;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { createEmptyPluginRegistry, discoverPluginRegistryStatus, loadPluginRegistryProgressively };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { buildReservedPluginLoadOptions } from "./plugin-command-utils.js";
|
|
2
|
-
import { resolveDevFirstPartyPluginDir } from "./development-source/first-party-plugin-load-paths.utils.js";
|
|
3
|
-
import { resolveDevPluginLoadingContext } from "./development-source/dev-plugin-overrides.utils.js";
|
|
4
|
-
import { getAppLogger } from "@nextclaw/core";
|
|
5
|
-
import { discoverPluginStatusReport, loadOpenClawPluginsProgressively } from "@nextclaw/openclaw-compat";
|
|
6
|
-
//#region src/commands/plugin/plugin-registry-loader.utils.ts
|
|
7
|
-
function createPluginLogger() {
|
|
8
|
-
return getAppLogger("plugin.registry_loader");
|
|
9
|
-
}
|
|
10
|
-
function withDevFirstPartyPluginPaths(config) {
|
|
11
|
-
return resolveDevPluginLoadingContext(config, resolveDevFirstPartyPluginDir(process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR));
|
|
12
|
-
}
|
|
13
|
-
async function loadPluginRegistryProgressively(config, workspaceDir, options = {}) {
|
|
14
|
-
const { configWithDevPluginOverrides, excludedRoots } = withDevFirstPartyPluginPaths(config);
|
|
15
|
-
return await loadOpenClawPluginsProgressively({
|
|
16
|
-
config: configWithDevPluginOverrides,
|
|
17
|
-
workspaceDir,
|
|
18
|
-
excludeRoots: excludedRoots,
|
|
19
|
-
...buildReservedPluginLoadOptions(),
|
|
20
|
-
onPluginProcessed: options.onPluginProcessed,
|
|
21
|
-
logger: createPluginLogger()
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function discoverPluginRegistryStatus(config, workspaceDir) {
|
|
25
|
-
const { configWithDevPluginOverrides } = withDevFirstPartyPluginPaths(config);
|
|
26
|
-
return discoverPluginStatusReport({
|
|
27
|
-
config: configWithDevPluginOverrides,
|
|
28
|
-
workspaceDir
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
function createEmptyPluginRegistry() {
|
|
32
|
-
return {
|
|
33
|
-
plugins: [],
|
|
34
|
-
tools: [],
|
|
35
|
-
channels: [],
|
|
36
|
-
providers: [],
|
|
37
|
-
ncpAgentRuntimes: [],
|
|
38
|
-
diagnostics: [],
|
|
39
|
-
resolvedTools: []
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
//#endregion
|
|
43
|
-
export { createEmptyPluginRegistry, discoverPluginRegistryStatus, loadPluginRegistryProgressively };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ExtensionChannelRegistration } from "@nextclaw/core";
|
|
2
|
-
import { PluginChannelBinding } from "@nextclaw/openclaw-compat";
|
|
3
|
-
|
|
4
|
-
//#region src/commands/plugin/plugin-reload.d.ts
|
|
5
|
-
declare function shouldRestartChannelsForPluginReload(params: {
|
|
6
|
-
changedPaths: readonly string[];
|
|
7
|
-
currentPluginChannelBindings: readonly PluginChannelBinding[];
|
|
8
|
-
nextPluginChannelBindings: readonly PluginChannelBinding[];
|
|
9
|
-
currentExtensionChannels: readonly ExtensionChannelRegistration[];
|
|
10
|
-
nextExtensionChannels: readonly ExtensionChannelRegistration[];
|
|
11
|
-
}): boolean;
|
|
12
|
-
//#endregion
|
|
13
|
-
export { shouldRestartChannelsForPluginReload };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
//#region src/commands/plugin/plugin-reload.ts
|
|
2
|
-
function buildPluginChannelBindingSignature(binding) {
|
|
3
|
-
return `${binding.pluginId}:${binding.channelId}`;
|
|
4
|
-
}
|
|
5
|
-
function buildSortedBindingSignatures(bindings) {
|
|
6
|
-
return bindings.map(buildPluginChannelBindingSignature).sort();
|
|
7
|
-
}
|
|
8
|
-
function buildSortedExtensionChannelIds(channels) {
|
|
9
|
-
return channels.map((registration) => registration.channel.id).filter((id) => typeof id === "string" && id.trim().length > 0).sort();
|
|
10
|
-
}
|
|
11
|
-
function areSortedStringListsEqual(left, right) {
|
|
12
|
-
if (left.length !== right.length) return false;
|
|
13
|
-
for (let index = 0; index < left.length; index += 1) if (left[index] !== right[index]) return false;
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
function readPluginIdFromPluginsEntryPath(path) {
|
|
17
|
-
if (!path.startsWith("plugins.entries.")) return null;
|
|
18
|
-
const [pluginId] = path.slice(16).split(".");
|
|
19
|
-
return pluginId?.trim() ? pluginId.trim() : null;
|
|
20
|
-
}
|
|
21
|
-
function readChannelIdFromChannelPath(path) {
|
|
22
|
-
if (!path.startsWith("channels.")) return null;
|
|
23
|
-
const [channelId] = path.slice(9).split(".");
|
|
24
|
-
return channelId?.trim() ? channelId.trim() : null;
|
|
25
|
-
}
|
|
26
|
-
function shouldRestartChannelsForPluginReload(params) {
|
|
27
|
-
if (!areSortedStringListsEqual(buildSortedBindingSignatures(params.currentPluginChannelBindings), buildSortedBindingSignatures(params.nextPluginChannelBindings))) return true;
|
|
28
|
-
if (!areSortedStringListsEqual(buildSortedExtensionChannelIds(params.currentExtensionChannels), buildSortedExtensionChannelIds(params.nextExtensionChannels))) return true;
|
|
29
|
-
const channelPluginIds = /* @__PURE__ */ new Set();
|
|
30
|
-
for (const binding of params.currentPluginChannelBindings) channelPluginIds.add(binding.pluginId);
|
|
31
|
-
for (const binding of params.nextPluginChannelBindings) channelPluginIds.add(binding.pluginId);
|
|
32
|
-
for (const path of params.changedPaths) {
|
|
33
|
-
const pluginId = readPluginIdFromPluginsEntryPath(path);
|
|
34
|
-
if (pluginId && channelPluginIds.has(pluginId)) return true;
|
|
35
|
-
const channelId = readChannelIdFromChannelPath(path);
|
|
36
|
-
if (!channelId) continue;
|
|
37
|
-
if (params.currentPluginChannelBindings.some((binding) => binding.channelId === channelId) || params.nextPluginChannelBindings.some((binding) => binding.channelId === channelId)) return true;
|
|
38
|
-
}
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { shouldRestartChannelsForPluginReload };
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { ChildProcess, spawn } from "node:child_process";
|
|
2
|
-
|
|
3
|
-
//#region src/shared/services/extensions/extension-lifecycle.service.d.ts
|
|
4
|
-
type ExtensionServerConfig = {
|
|
5
|
-
type: "stdio";
|
|
6
|
-
command: string;
|
|
7
|
-
args?: string[];
|
|
8
|
-
env?: Record<string, string>;
|
|
9
|
-
};
|
|
10
|
-
type ExtensionManifest = {
|
|
11
|
-
id: string;
|
|
12
|
-
name?: string;
|
|
13
|
-
version?: string;
|
|
14
|
-
rootDir: string;
|
|
15
|
-
server: ExtensionServerConfig;
|
|
16
|
-
contributes?: {
|
|
17
|
-
channels?: Array<{
|
|
18
|
-
id: string;
|
|
19
|
-
name?: string;
|
|
20
|
-
description?: string;
|
|
21
|
-
meta?: Record<string, unknown>;
|
|
22
|
-
configSchema?: Record<string, unknown>;
|
|
23
|
-
configUiHints?: Record<string, Record<string, unknown>>;
|
|
24
|
-
auth?: boolean | Record<string, unknown>;
|
|
25
|
-
outbound?: {
|
|
26
|
-
text?: boolean;
|
|
27
|
-
};
|
|
28
|
-
}>;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
type RunningExtensionProcess = {
|
|
32
|
-
manifest: ExtensionManifest;
|
|
33
|
-
process: ChildProcess;
|
|
34
|
-
};
|
|
35
|
-
type ExtensionLifecycleServiceOptions = {
|
|
36
|
-
endpoint: string;
|
|
37
|
-
token: string;
|
|
38
|
-
spawnProcess?: typeof spawn;
|
|
39
|
-
logger?: Pick<Console, "warn">;
|
|
40
|
-
};
|
|
41
|
-
declare class ExtensionManifestDiscoveryService {
|
|
42
|
-
readonly discover: (roots: string[]) => Promise<ExtensionManifest[]>;
|
|
43
|
-
readonly discoverSync: (roots: string[]) => ExtensionManifest[];
|
|
44
|
-
private readonly discoverRoot;
|
|
45
|
-
private readonly discoverRootSync;
|
|
46
|
-
private readonly readManifestIfExists;
|
|
47
|
-
private readonly readManifestIfExistsSync;
|
|
48
|
-
private readonly readDirectoriesSync;
|
|
49
|
-
}
|
|
50
|
-
declare class ExtensionLifecycleService {
|
|
51
|
-
private readonly options;
|
|
52
|
-
private readonly processes;
|
|
53
|
-
private readonly spawnProcess;
|
|
54
|
-
private readonly logger;
|
|
55
|
-
constructor(options: ExtensionLifecycleServiceOptions);
|
|
56
|
-
readonly startAll: (manifests: ExtensionManifest[]) => Promise<RunningExtensionProcess[]>;
|
|
57
|
-
readonly start: (manifest: ExtensionManifest) => RunningExtensionProcess;
|
|
58
|
-
readonly stopAll: () => Promise<void>;
|
|
59
|
-
readonly list: () => RunningExtensionProcess[];
|
|
60
|
-
private readonly stopProcess;
|
|
61
|
-
}
|
|
62
|
-
//#endregion
|
|
63
|
-
export { ExtensionLifecycleService, ExtensionLifecycleServiceOptions, ExtensionManifest, ExtensionManifestDiscoveryService, ExtensionServerConfig, RunningExtensionProcess };
|