fix(update): Suppress Corepack prompts during update preflight (#61456)

Merged via squash.

Prepared head SHA: da1b791ce6
Co-authored-by: p6l-richard <18185649+p6l-richard@users.noreply.github.com>
Co-authored-by: osolmaz <2453968+osolmaz@users.noreply.github.com>
Reviewed-by: @osolmaz
This commit is contained in:
Richard Poelderl
2026-04-12 13:59:36 +02:00
committed by GitHub
parent 766954d9a1
commit 6fec1ec2d6
3 changed files with 33 additions and 2 deletions

View File

@@ -693,6 +693,7 @@ Docs: https://docs.openclaw.ai
- Gateway/OpenAI HTTP: restore default operator scopes for bearer-authenticated requests that omit `x-openclaw-scopes`, so headless `/v1/chat/completions` and session-history callers work again after the recent method-scope hardening. (#57596) Thanks @openperf.
- Gateway/attachments: offload large inbound images without leaking `media://` markers into text-only runs, preserve mixed attachment order for model input/transcripts, and fail closed when model image capability cannot be resolved. (#55513) Thanks @Syysean.
- Telegram/outbound chunking: use static markdown chunking when Telegram runtime state is unavailable so long outbound Telegram messages still split correctly after cold starts. (#57816) Thanks @ForestDengHK.
- Update/Corepack: disable interactive Corepack download prompts during update preflight install unless `COREPACK_ENABLE_DOWNLOAD_PROMPT` is already explicitly set, so `openclaw update` can fetch the repo-pinned pnpm version non-interactively. (#61456) Thanks @p6l-richard.
## 2026.4.2

View File

@@ -11,6 +11,7 @@ import {
cleanupGlobalRenameDirs,
detectGlobalInstallManagerByPresence,
detectGlobalInstallManagerForRoot,
createGlobalInstallEnv,
globalInstallArgs,
globalInstallFallbackArgs,
isExplicitPackageInstallSpec,
@@ -89,6 +90,20 @@ describe("update global helpers", () => {
).toBe("https://example.com/openclaw-main.tgz");
});
it("defaults corepack download prompts off for global install env", async () => {
await expect(createGlobalInstallEnv({})).resolves.toMatchObject({
COREPACK_ENABLE_DOWNLOAD_PROMPT: "0",
});
await expect(
createGlobalInstallEnv({
COREPACK_ENABLE_DOWNLOAD_PROMPT: "1",
}),
).resolves.toMatchObject({
COREPACK_ENABLE_DOWNLOAD_PROMPT: "1",
});
});
it("classifies main and raw install specs separately from registry selectors", () => {
expect(isMainPackageTarget("main")).toBe(true);
expect(isMainPackageTarget(" MAIN ")).toBe(true);

View File

@@ -29,6 +29,7 @@ const PRIMARY_PACKAGE_NAME = "openclaw";
const ALL_PACKAGE_NAMES = [PRIMARY_PACKAGE_NAME] as const;
const GLOBAL_RENAME_PREFIX = ".";
export const OPENCLAW_MAIN_PACKAGE_SPEC = "github:openclaw/openclaw#main";
const COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT = "0";
const NPM_GLOBAL_INSTALL_QUIET_FLAGS = ["--no-fund", "--no-audit", "--loglevel=error"] as const;
const NPM_GLOBAL_INSTALL_OMIT_OPTIONAL_FLAGS = [
"--omit=optional",
@@ -140,6 +141,13 @@ function applyWindowsPackageInstallEnv(env: Record<string, string>) {
env.NODE_LLAMA_CPP_SKIP_DOWNLOAD = "1";
}
function applyCorepackDownloadPromptEnv(env: Record<string, string>) {
const current = env.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim();
if (!current) {
env.COREPACK_ENABLE_DOWNLOAD_PROMPT = COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT;
}
}
export function resolveGlobalInstallSpec(params: {
packageName: string;
tag: string;
@@ -165,16 +173,23 @@ export async function createGlobalInstallEnv(
env?: NodeJS.ProcessEnv,
): Promise<NodeJS.ProcessEnv | undefined> {
const pathPrepend = await resolvePortableGitPathPrepend(env);
if (pathPrepend.length === 0 && process.platform !== "win32") {
const sourceEnv = env ?? process.env;
const hasCorepackDownloadPromptSetting = Boolean(
sourceEnv.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim(),
);
const requiresMergedEnv =
pathPrepend.length > 0 || process.platform === "win32" || !hasCorepackDownloadPromptSetting;
if (!requiresMergedEnv) {
return env;
}
const merged = Object.fromEntries(
Object.entries(env ?? process.env)
Object.entries(sourceEnv)
.filter(([, value]) => value != null)
.map(([key, value]) => [key, String(value)]),
) as Record<string, string>;
applyPathPrepend(merged, pathPrepend);
applyWindowsPackageInstallEnv(merged);
applyCorepackDownloadPromptEnv(merged);
return merged;
}