Check ClawHub trust before plugin installs (#81307)

Merged via squash.

Prepared head SHA: 273fd7c20e
Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
Reviewed-by: @jesse-merhi
This commit is contained in:
Jesse Merhi
2026-05-13 16:31:52 +10:00
committed by GitHub
parent cf68115e6e
commit 87eb450047
23 changed files with 832 additions and 43 deletions

View File

@@ -55,6 +55,7 @@ import {
resolvePnpmGlobalDirFromGlobalRoot,
} from "../../infra/update-global.js";
import { runGatewayUpdate, type UpdateRunResult } from "../../infra/update-runner.js";
import type { ClawHubRiskAcknowledgementRequest } from "../../plugins/clawhub.js";
import { normalizePluginsConfig, resolveEffectiveEnableState } from "../../plugins/config-state.js";
import {
loadInstalledPluginIndexInstallRecords,
@@ -173,6 +174,29 @@ type MissingPluginInstallPayload = {
type PostUpdatePluginWarning = NonNullable<PostCorePluginUpdateResult["warnings"]>[number];
function resolveUpdateClawHubRiskAcknowledgementOptions(opts: UpdateCommandOptions): {
acknowledgeClawHubRisk?: boolean;
onClawHubRisk?: (request: ClawHubRiskAcknowledgementRequest) => Promise<boolean>;
} {
if (opts.acknowledgeClawHubRisk) {
return { acknowledgeClawHubRisk: true };
}
if (opts.json || !process.stdin.isTTY) {
return {};
}
return {
onClawHubRisk: async (request) => {
const ok = await confirm({
message: stylePromptMessage(
`Continue updating ClawHub package "${request.packageName}@${request.version}" despite this warning?`,
),
initialValue: false,
});
return !isCancel(ok) && ok;
},
};
}
function pickUpdateQuip(): string {
return UPDATE_QUIPS[Math.floor(Math.random() * UPDATE_QUIPS.length)] ?? "Update complete.";
}
@@ -1185,6 +1209,9 @@ export async function updatePluginsAfterCoreUpdate(params: {
}
const warnings: PostUpdatePluginWarning[] = [];
const clawHubRiskAcknowledgementOptions = resolveUpdateClawHubRiskAcknowledgementOptions(
params.opts,
);
const pluginInstallRecords =
params.pluginInstallRecords ?? (await loadInstalledPluginIndexInstallRecords());
const syncConfig = withPluginInstallRecords(
@@ -1198,6 +1225,7 @@ export async function updatePluginsAfterCoreUpdate(params: {
externalizedBundledPluginBridges: await listPersistedBundledPluginLocationBridges({
workspaceDir: params.root,
}),
...clawHubRiskAcknowledgementOptions,
logger: pluginLogger,
});
for (const error of syncResult.summary.errors) {
@@ -1271,6 +1299,7 @@ export async function updatePluginsAfterCoreUpdate(params: {
disableOnFailure: true,
logger: pluginLogger,
onIntegrityDrift: onPluginIntegrityDrift,
...clawHubRiskAcknowledgementOptions,
});
pluginConfig = repairResult.config;
pluginsChanged ||= repairResult.changed;
@@ -1291,6 +1320,7 @@ export async function updatePluginsAfterCoreUpdate(params: {
disableOnFailure: true,
logger: pluginLogger,
onIntegrityDrift: onPluginIntegrityDrift,
...clawHubRiskAcknowledgementOptions,
});
pluginConfig = npmResult.config;
pluginsChanged ||= npmResult.changed;
@@ -1949,6 +1979,9 @@ async function continuePostCoreUpdateInFreshProcess(params: {
if (params.opts.yes) {
argv.push("--yes");
}
if (params.opts.acknowledgeClawHubRisk) {
argv.push("--acknowledge-clawhub-risk");
}
if (params.opts.timeout) {
argv.push("--timeout", params.opts.timeout);
}