mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
Install ClawHub packages for new Claw agents (#102228)
* Install ClawHub packages for new Claw agents * test(claws): cover skill and plugin installation * docs(claws): document package artifacts * fix(claws): bind package trust preflight * fix(claws): bind package capability consent * fix(claws): satisfy package type guards * test(claws): update package installer fixtures * test(claws): complete package plan fixtures * test(claws): model complete ClawHub results * fix(claws): serialize plugin ownership changes * fix(claws): cover legacy plugin lifecycle updates * fix(claws): preserve legacy ClawHub update selectors * test(claws): type lifecycle lease mock * refactor(claws): isolate plugin update lifecycle * fix(claws): declare managed installer coordination * test(claws): preserve partial collision result * test(claws): clean installer temp dirs --------- Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
This commit is contained in:
@@ -45,6 +45,8 @@ import {
|
||||
import { resolveCatalogOfficialExternalInstallPlan } from "../plugins/official-external-install-trust.js";
|
||||
import { tracePluginLifecyclePhaseAsync } from "../plugins/plugin-lifecycle-trace.js";
|
||||
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
|
||||
import { markClawPackageIndependentlyOwned } from "../state/claw-package-adoption.js";
|
||||
import { withClawPackageLifecycleLease } from "../state/claw-package-lifecycle-lease.js";
|
||||
import { resolveUserPath, shortenHomePath } from "../utils.js";
|
||||
import { resolveClawHubRiskAcknowledgementCliOptions } from "./clawhub-risk-acknowledgement.js";
|
||||
import { formatCliCommand } from "./command-format.js";
|
||||
@@ -759,12 +761,15 @@ export async function runPluginInstallCommand(params: {
|
||||
raw: string;
|
||||
opts: InstallSafetyOverrides & {
|
||||
acknowledgeClawHubRisk?: boolean;
|
||||
expectedIntegrity?: string;
|
||||
expectedPluginId?: string;
|
||||
force?: boolean;
|
||||
link?: boolean;
|
||||
pin?: boolean;
|
||||
marketplace?: string;
|
||||
};
|
||||
invalidateRuntimeCache?: boolean;
|
||||
clawManaged?: boolean;
|
||||
runtime?: RuntimeEnv;
|
||||
}) {
|
||||
assertConfigWriteAllowedInCurrentMode();
|
||||
@@ -1215,36 +1220,69 @@ export async function runPluginInstallCommand(params: {
|
||||
}
|
||||
|
||||
if (clawhubSpec) {
|
||||
const result = await installPluginFromClawHub({
|
||||
...safetyOverrides,
|
||||
...resolveClawHubRiskAcknowledgementCliOptions({
|
||||
acknowledgeClawHubRisk: opts.acknowledgeClawHubRisk,
|
||||
action: "installing",
|
||||
}),
|
||||
mode: installMode,
|
||||
spec: raw,
|
||||
extensionsDir,
|
||||
logger: createPluginInstallLogger(runtime),
|
||||
});
|
||||
if (!result.ok) {
|
||||
if (!isClawHubBlockedCliFailure(result)) {
|
||||
runtime.error(result.error);
|
||||
}
|
||||
return runtime.exit(1);
|
||||
}
|
||||
|
||||
await persistPluginInstall({
|
||||
snapshot,
|
||||
pluginId: result.pluginId,
|
||||
install: {
|
||||
...buildClawHubPluginInstallRecordFields(result.clawhub),
|
||||
const installFromClawHub = async (
|
||||
installSnapshot = snapshot,
|
||||
installSafetyOverrides = safetyOverrides,
|
||||
) => {
|
||||
const result = await installPluginFromClawHub({
|
||||
...installSafetyOverrides,
|
||||
...resolveClawHubRiskAcknowledgementCliOptions({
|
||||
acknowledgeClawHubRisk: opts.acknowledgeClawHubRisk,
|
||||
action: "installing",
|
||||
}),
|
||||
mode: installMode,
|
||||
spec: raw,
|
||||
installPath: result.targetDir,
|
||||
...(opts.expectedIntegrity ? { expectedIntegrity: opts.expectedIntegrity } : {}),
|
||||
...(opts.expectedPluginId ? { expectedPluginId: opts.expectedPluginId } : {}),
|
||||
extensionsDir,
|
||||
logger: createPluginInstallLogger(runtime),
|
||||
});
|
||||
if (!result.ok) {
|
||||
if (!isClawHubBlockedCliFailure(result)) {
|
||||
runtime.error(result.error);
|
||||
}
|
||||
return runtime.exit(1);
|
||||
}
|
||||
|
||||
await persistPluginInstall({
|
||||
snapshot: installSnapshot,
|
||||
pluginId: result.pluginId,
|
||||
install: {
|
||||
...buildClawHubPluginInstallRecordFields(result.clawhub),
|
||||
spec: raw,
|
||||
installPath: result.targetDir,
|
||||
},
|
||||
invalidateRuntimeCache,
|
||||
runtime,
|
||||
});
|
||||
if (!params.clawManaged && result.clawhub.version) {
|
||||
markClawPackageIndependentlyOwned({
|
||||
kind: "plugin",
|
||||
source: "clawhub",
|
||||
ref: result.clawhub.clawhubPackage,
|
||||
version: result.clawhub.version,
|
||||
});
|
||||
}
|
||||
};
|
||||
if (params.clawManaged) {
|
||||
return await installFromClawHub();
|
||||
}
|
||||
return await withClawPackageLifecycleLease(
|
||||
{ kind: "plugin", source: "clawhub", ref: clawhubSpec.name },
|
||||
async () => {
|
||||
const leasedSnapshot = await loadConfigForInstall(request).catch((error: unknown) => {
|
||||
runtime.error(formatErrorMessage(error));
|
||||
return null;
|
||||
});
|
||||
if (!leasedSnapshot) {
|
||||
return runtime.exit(1);
|
||||
}
|
||||
return await installFromClawHub(
|
||||
leasedSnapshot,
|
||||
resolveInstallSafetyOverrides({ ...opts, config: leasedSnapshot.config }),
|
||||
);
|
||||
},
|
||||
invalidateRuntimeCache,
|
||||
runtime,
|
||||
});
|
||||
return;
|
||||
);
|
||||
}
|
||||
|
||||
const trustedNpmInstall = resolveOpenClawTrustedNpmPackageInstall(raw);
|
||||
|
||||
Reference in New Issue
Block a user