diff --git a/scripts/package-openclaw-for-docker.mts b/scripts/package-openclaw-for-docker.mts index 51dc9b1151e0..21defce661f1 100644 --- a/scripts/package-openclaw-for-docker.mts +++ b/scripts/package-openclaw-for-docker.mts @@ -723,7 +723,15 @@ export async function prepareBundledAiRuntimePackage( try { await runCaptureImpl( "pnpm", - ["--dir", "packages/ai", "pack", "--silent", "--pack-destination", outputDir], + [ + "--dir", + "packages/ai", + "pack", + "--loglevel=error", + "--use-stderr", + "--pack-destination", + outputDir, + ], sourceDir, { deferForwardedSignalExit: true, diff --git a/test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts b/test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts index 3e39240ad791..38efd090f6fb 100644 --- a/test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts +++ b/test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts @@ -495,7 +495,15 @@ describe("package-openclaw-for-docker", () => { outputDir, async (command: string, args: string[], cwd: string) => { expect({ args, command, cwd }).toEqual({ - args: ["--dir", "packages/ai", "pack", "--silent", "--pack-destination", outputDir], + args: [ + "--dir", + "packages/ai", + "pack", + "--loglevel=error", + "--use-stderr", + "--pack-destination", + outputDir, + ], command: "pnpm", cwd: sourceDir, }); @@ -549,6 +557,37 @@ describe("package-openclaw-for-docker", () => { } }); + it("keeps real AI runtime pack failures visible for installer diagnostics", async () => { + const sourceDir = tempDirs.make("openclaw-docker-ai-failure-source-"); + const outputDir = tempDirs.make("openclaw-docker-ai-failure-output-"); + const packageJsonPath = path.join(sourceDir, "package.json"); + const originalPackageJson = `${JSON.stringify({ + dependencies: { "@openclaw/ai": "workspace:*" }, + name: "openclaw", + })}\n`; + fs.mkdirSync(path.join(sourceDir, "packages", "ai"), { recursive: true }); + fs.writeFileSync( + path.join(sourceDir, "packages", "ai", "package.json"), + '{"name":"@openclaw/ai"}\n', + ); + fs.writeFileSync(packageJsonPath, originalPackageJson); + let stderr = ""; + const stderrWrite = vi.spyOn(process.stderr, "write").mockImplementation((chunk) => { + stderr += String(chunk); + return true; + }); + + try { + await expect(prepareBundledAiRuntimePackage(sourceDir, outputDir)).rejects.toThrow( + "pnpm --dir packages/ai pack --loglevel=error --use-stderr", + ); + expect(stderr).toContain("ERR_PNPM_PACKAGE_VERSION_NOT_FOUND"); + expect(fs.readFileSync(packageJsonPath, "utf8")).toBe(originalPackageJson); + } finally { + stderrWrite.mockRestore(); + } + }); + it("reuses the source manifest lifecycle for ignore-scripts package artifacts", async () => { const sourceDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-docker-manifest-source-")); const outputDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-docker-manifest-output-"));