






















@@ -325,7 +325,7 @@ describe("installPackageDir", () => {
325325326326expect(result).toEqual({ ok: true });
327327expect(vi.mocked(runCommandWithTimeout)).toHaveBeenCalledWith(
328-["npm", "install", "--omit=dev", "--silent", "--ignore-scripts"],
328+["npm", "install", "--omit=dev", "--loglevel=error", "--ignore-scripts"],
329329expect.objectContaining({
330330cwd: expect.stringContaining(".openclaw-install-stage-"),
331331}),
@@ -433,7 +433,7 @@ describe("installPackageDir", () => {
433433434434expect(result).toEqual({ ok: true });
435435expect(vi.mocked(runCommandWithTimeout)).toHaveBeenCalledWith(
436-["npm", "install", "--omit=dev", "--silent", "--ignore-scripts"],
436+["npm", "install", "--omit=dev", "--loglevel=error", "--ignore-scripts"],
437437expect.objectContaining({
438438env: expect.objectContaining({
439439npm_config_global: "false",
@@ -455,4 +455,52 @@ describe("installPackageDir", () => {
455455}),
456456);
457457});
458+459+it("surfaces npm stderr when dependency install fails", async () => {
460+await fixtureRootTracker.setup();
461+const fixtureRoot = await fixtureRootTracker.make("case");
462+const sourceDir = path.join(fixtureRoot, "source");
463+const targetDir = path.join(fixtureRoot, "plugins", "demo");
464+await fs.mkdir(sourceDir, { recursive: true });
465+await fs.writeFile(
466+path.join(sourceDir, "package.json"),
467+JSON.stringify({
468+name: "demo-plugin",
469+version: "1.0.0",
470+dependencies: {
471+bad: "workspace:^",
472+},
473+}),
474+"utf-8",
475+);
476+477+// Mirrors the Blacksmith repro: npm 11 preserved this stderr with
478+// `--loglevel=error`, while `--silent` returned empty output.
479+vi.mocked(runCommandWithTimeout).mockResolvedValue({
480+stdout: "",
481+stderr:
482+'npm error code EUNSUPPORTEDPROTOCOL\nnpm error Unsupported URL Type "workspace:": workspace:^\n',
483+code: 1,
484+signal: null,
485+killed: false,
486+termination: "exit",
487+});
488+489+const result = await installPackageDir({
490+ sourceDir,
491+ targetDir,
492+mode: "install",
493+timeoutMs: 1_000,
494+copyErrorPrefix: "failed to copy plugin",
495+hasDeps: true,
496+depsLogMessage: "Installing deps…",
497+});
498+499+expect(result.ok).toBe(false);
500+if (!result.ok) {
501+expect(result.error).toContain("npm install failed:");
502+expect(result.error).toContain("EUNSUPPORTEDPROTOCOL");
503+expect(result.error).toContain("workspace:");
504+}
505+});
458506});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。