fix(plugins): avoid managed npm prefix on Windows

Fixes #78514.
This commit is contained in:
Vincent Koc
2026-05-09 07:51:49 +08:00
committed by GitHub
parent becfeb48b4
commit 3ba2ce6694
8 changed files with 5 additions and 25 deletions

View File

@@ -33,6 +33,7 @@ Docs: https://docs.openclaw.ai
- Discord/voice: include a bounded one-line STT transcript preview in verbose voice logs so live voice debugging shows what speakers said before the agent reply.
- Codex app-server: pin the managed Codex harness and Codex CLI smoke package to `@openai/codex@0.129.0`, defer OpenClaw integration dynamic tools behind Codex tool search by default, and accept current Codex service-tier values so legacy `fast` settings survive the stable harness upgrade as `priority`.
- Codex app-server: default implicit local stdio app-server permissions to guardian when Codex system requirements disallow the YOLO approval, reviewer, or sandbox value, including hostname-scoped remote sandbox entries, avoiding turn-start failures on managed hosts that permit only reviewed approval or narrower sandboxes.
- Plugins/install: run managed npm-root install, uninstall, prune, and repair commands from the managed root without a redundant `--prefix .`, avoiding npm 10.9.3 Arborist crashes on native Windows WhatsApp plugin installs. Fixes #78514. (#78902) Thanks @melihselamett-stack.
- Discord/voice: stream ElevenLabs TTS directly into Discord playback and send ElevenLabs latency optimization as the documented query parameter so spoken replies can start sooner.
- Discord/voice: keep TTS playback running when another user starts speaking, ignore new capture during playback to avoid feedback loops, and downgrade expected receive-stream aborts to verbose diagnostics.
- iMessage: expose native private-API message actions through `imsg rpc` for reactions, edits, unsends, replies, rich sends, attachments, and group management when `imsg status --json` reports the required bridge capabilities.

View File

@@ -41,7 +41,8 @@ OpenClaw uses stable per-source roots:
npm installs run in the npm root with:
```bash
npm install --prefix ~/.openclaw/npm <spec> --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts --no-audit --no-fund
cd ~/.openclaw/npm
npm install --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts --no-audit --no-fund
```
`openclaw plugins install npm-pack:<path.tgz>` uses that same managed npm root

View File

@@ -398,8 +398,6 @@ describe("managed npm root", () => {
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
"openclaw",
],
expect.objectContaining({

View File

@@ -245,8 +245,6 @@ export async function repairManagedNpmRootOpenClawPeer(params: {
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
"openclaw",
]
: [
@@ -257,8 +255,6 @@ export async function repairManagedNpmRootOpenClawPeer(params: {
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
];
try {
const result = await command(npmArgs, {

View File

@@ -69,8 +69,6 @@ function expectNpmInstallIntoRoot(params: { calls: unknown[][]; npmRoot: string
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
]);
}
@@ -290,9 +288,7 @@ function mockNpmViewAndInstallMany(packages: MockNpmPackage[]) {
);
}
if (argv[0] === "npm" && argv[1] === "install") {
const prefixIndex = argv.indexOf("--prefix");
const prefixValue = prefixIndex >= 0 ? argv[prefixIndex + 1] : undefined;
const npmRoot = prefixValue === "." ? options?.cwd : prefixValue;
const npmRoot = options?.cwd;
if (!npmRoot) {
throw new Error(`unexpected npm install command: ${argv.join(" ")}`);
}
@@ -345,9 +341,7 @@ function mockNpmViewAndInstallMany(packages: MockNpmPackage[]) {
if (argv[0] === "npm" && argv[1] === "uninstall") {
const packageName = argv.at(-1);
if (packageName === "openclaw") {
const prefixIndex = argv.indexOf("--prefix");
const prefixValue = prefixIndex >= 0 ? argv[prefixIndex + 1] : undefined;
const npmRoot = prefixValue === "." ? options?.cwd : prefixValue;
const npmRoot = options?.cwd;
if (!npmRoot) {
throw new Error(`unexpected npm uninstall command: ${argv.join(" ")}`);
}

View File

@@ -328,8 +328,6 @@ async function rollbackManagedNpmPluginInstall(params: {
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
params.packageName,
],
{
@@ -499,8 +497,6 @@ async function installPluginFromManagedNpmRoot(
noAudit: true,
noFund: true,
}),
"--prefix",
".",
],
{
cwd: npmRoot,

View File

@@ -992,8 +992,6 @@ describe("uninstallPlugin", () => {
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
"@openclaw/kitchen-sink",
],
expect.objectContaining({
@@ -1128,8 +1126,6 @@ describe("uninstallPlugin", () => {
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
"missing-plugin",
],
expect.objectContaining({

View File

@@ -611,8 +611,6 @@ export async function applyPluginUninstallDirectoryRemoval(
"--ignore-scripts",
"--no-audit",
"--no-fund",
"--prefix",
".",
removal.cleanup.packageName,
],
{