惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
Microsoft Azure Blog
Microsoft Azure Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog
Y
Y Combinator Blog
博客园_首页
有赞技术团队
有赞技术团队
博客园 - Franky
腾讯CDC
G
Google Developers Blog
Recent Announcements
Recent Announcements
博客园 - 【当耐特】
D
Docker
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
V
V2EX
U
Unit 42
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix: explain missing git during plugin install · openclaw...
steipete · 2026-05-05 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -80,6 +80,7 @@ Docs: https://docs.openclaw.ai

8080

- Gateway/watch: suppress sync-I/O trace output during `pnpm gateway:watch --benchmark` unless explicitly requested, so CPU profiling no longer floods the terminal with stack traces.

8181

- Gateway/watch: when benchmark sync-I/O tracing is explicitly enabled, tee trace blocks to the benchmark output log and filter them from the terminal pane while keeping normal Gateway logs visible.

8282

- Plugins/runtime-deps: include `json5` in the memory-core plugin runtime dependency set so packaged `memory_search` sandboxes can resolve generated OpenClaw runtime chunks that parse JSON5 config. Fixes #77461.

83+

- Plugins/Windows: show a Git install hint when npm plugin installation fails with `spawn git ENOENT`, and document the WhatsApp plugin's Git-on-PATH requirement for Baileys/libsignal installs.

8384

- Codex harness: preserve app-server usage-limit reset details and deliver OpenClaw-owned runtime failure notices through tool-only source-reply mode, so Telegram and other chat channels tell users when Codex subscription limits or API failures block a turn instead of going silent. (#77557) Thanks @pashpashpash.

8485

- Agents/OpenAI: default direct OpenAI Responses models to the SSE transport instead of WebSocket auto-selection, preventing pi runtime chat turns from hanging on servers where the WebSocket path stalls while the OpenAI HTTP stream works. Thanks @vincentkoc.

8586

- Plugins/update: repair missing plugin-local `openclaw` peer links before skipping unchanged npm plugin updates, so current external Codex installs can recover `openclaw/plugin-sdk/*` resolution during OTA repair. (#77544) Thanks @ProspectOre.

Original file line numberDiff line numberDiff line change

@@ -26,6 +26,16 @@ openclaw plugins install @openclaw/whatsapp

2626

Use the bare package to follow the current official release tag. Pin an exact

2727

version only when you need a reproducible install.

2828
29+

On Windows, the WhatsApp plugin needs Git on `PATH` during npm install because

30+

one of its Baileys/libsignal dependencies is fetched from a git URL. Install

31+

Git for Windows, then restart the shell and rerun the install:

32+
33+

```powershell

34+

winget install --id Git.Git -e

35+

```

36+
37+

Portable Git also works if its `bin` directory is on `PATH`.

38+
2939

<CardGroup cols={3}>

3040

<Card title="Pairing" icon="link" href="/channels/pairing">

3141

Default DM policy is pairing for unknown senders.

Original file line numberDiff line numberDiff line change

@@ -18,6 +18,16 @@ Adds the WhatsApp channel surface for sending and receiving OpenClaw messages.

1818
1919

channels: whatsapp

2020
21+

## Windows install note

22+
23+

On Windows, the WhatsApp plugin needs Git on `PATH` during npm install because one of its Baileys/libsignal dependencies is fetched from a git URL. Install Git for Windows, then restart the shell and rerun the install:

24+
25+

```powershell

26+

winget install --id Git.Git -e

27+

```

28+
29+

Portable Git also works if its `bin` directory is on `PATH`.

30+
2131

## Related docs

2232
2333

- [whatsapp](/channels/whatsapp)

Original file line numberDiff line numberDiff line change

@@ -28,6 +28,20 @@ const PLUGIN_DOC_ALIASES = new Map([

2828

["tavily", "/tools/tavily"],

2929

["tokenjuice", "/tools/tokenjuice"],

3030

]);

31+

const PLUGIN_REFERENCE_EXTRA_SECTIONS = new Map([

32+

[

33+

"whatsapp",

34+

`## Windows install note

35+
36+

On Windows, the WhatsApp plugin needs Git on \`PATH\` during npm install because one of its Baileys/libsignal dependencies is fetched from a git URL. Install Git for Windows, then restart the shell and rerun the install:

37+
38+

\`\`\`powershell

39+

winget install --id Git.Git -e

40+

\`\`\`

41+
42+

Portable Git also works if its \`bin\` directory is on \`PATH\`.`,

43+

],

44+

]);

3145
3246

function readJson(relativePath) {

3347

return JSON.parse(fs.readFileSync(path.join(ROOT, relativePath), "utf8"));

@@ -376,6 +390,7 @@ ${record.docs.map((link) => `- ${docLink(link)}`).join("\n")}`;

376390
377391

function renderReferencePage(record) {

378392

const relatedDocs = renderRelatedDocs(record);

393+

const extraSections = PLUGIN_REFERENCE_EXTRA_SECTIONS.get(record.id);

379394

return `---

380395

summary: "${record.description.replaceAll('"', '\\"')}"

381396

read_when:

@@ -394,7 +409,7 @@ ${record.description}

394409
395410

## Surface

396411
397-

${record.surface}${relatedDocs ? `\n\n${relatedDocs}` : ""}

412+

${record.surface}${extraSections ? `\n\n${extraSections}` : ""}${relatedDocs ? `\n\n${relatedDocs}` : ""}

398413

`;

399414

}

400415
Original file line numberDiff line numberDiff line change

@@ -1096,6 +1096,34 @@ describe("plugins cli install", () => {

10961096

expect(runtimeErrors.at(-1)).toContain("npm install failed");

10971097

});

10981098
1099+

it("adds a Git PATH hint when npm plugin dependency install cannot spawn git", async () => {

1100+

loadConfig.mockReturnValue({} as OpenClawConfig);

1101+

installPluginFromNpmSpec.mockResolvedValue({

1102+

ok: false,

1103+

error: [

1104+

"npm install failed:",

1105+

"npm error code ENOENT",

1106+

"npm error syscall spawn git",

1107+

"npm error path git",

1108+

].join("\n"),

1109+

});

1110+

installHooksFromNpmSpec.mockResolvedValue({

1111+

ok: false,

1112+

error: "package.json missing openclaw.hooks",

1113+

});

1114+
1115+

await expect(

1116+

runPluginsCommand(["plugins", "install", "npm:@openclaw/whatsapp"]),

1117+

).rejects.toThrow("__exit__:1");

1118+
1119+

expect(installPluginFromClawHub).not.toHaveBeenCalled();

1120+

expect(runtimeErrors.at(-1)).toContain(

1121+

"one of this plugin's npm dependencies is fetched from a git URL",

1122+

);

1123+

expect(runtimeErrors.at(-1)).toContain("winget install --id Git.Git -e");

1124+

expect(runtimeErrors.at(-1)).toContain("Also not a valid hook pack");

1125+

});

1126+
10991127

it("does not resolve npm: prefixed bundled plugin ids through bundled installs", async () => {

11001128

loadConfig.mockReturnValue({ plugins: { load: { paths: [] } } } as OpenClawConfig);

11011129

installPluginFromNpmSpec.mockResolvedValue({

Original file line numberDiff line numberDiff line change

@@ -176,16 +176,36 @@ export function formatPluginInstallWithHookFallbackError(

176176

pluginError: string,

177177

hookError: string,

178178

): string {

179+

const formattedPluginError = formatPluginInstallAttemptError(pluginError);

180+

const formattedHookError = formatPluginInstallAttemptError(hookError);

179181

if (/plugin already exists: .+ \(delete it first\)/.test(pluginError)) {

180-

return `${pluginError}\nUse \`openclaw plugins update <id-or-npm-spec>\` to upgrade the tracked plugin, or rerun install with \`--force\` to replace it.`;

182+

return `${formattedPluginError}\nUse \`openclaw plugins update <id-or-npm-spec>\` to upgrade the tracked plugin, or rerun install with \`--force\` to replace it.`;

181183

}

182184

if (

183185

pluginError.startsWith("Invalid extensions directory:") ||

184186

pluginError === "Invalid path: must stay within extensions directory"

185187

) {

186-

return pluginError;

188+

return formattedPluginError;

187189

}

188-

return `${pluginError}\nAlso not a valid hook pack: ${hookError}`;

190+

return `${formattedPluginError}\nAlso not a valid hook pack: ${formattedHookError}`;

191+

}

192+
193+

const MISSING_GIT_FOR_NPM_DEPENDENCY_HINT =

194+

"Git is required because one of this plugin's npm dependencies is fetched from a git URL, but `git` was not found on PATH. Install Git and rerun the install. On Windows, use `winget install --id Git.Git -e` or add a portable Git `bin` directory to PATH.";

195+
196+

function formatPluginInstallAttemptError(error: string): string {

197+

if (!isMissingGitForNpmDependencyError(error)) {

198+

return error;

199+

}

200+

if (error.includes(MISSING_GIT_FOR_NPM_DEPENDENCY_HINT)) {

201+

return error;

202+

}

203+

return `${error}\n\n${MISSING_GIT_FOR_NPM_DEPENDENCY_HINT}`;

204+

}

205+
206+

function isMissingGitForNpmDependencyError(error: string): boolean {

207+

const normalized = normalizeLowercaseStringOrEmpty(error);

208+

return /\bspawn\s+git\b/u.test(normalized) && /\benoent\b/u.test(normalized);

189209

}

190210
191211

export function logHookPackRestartHint(runtime: RuntimeEnv = defaultRuntime) {