Skip to content

fix(browser): fall back to Hyprland grim capture for headed viewport screenshots#71940

Closed
Angfr95 wants to merge 3 commits into
openclaw:mainfrom
Angfr95:fix/hyprland-wayland-screenshot
Closed

fix(browser): fall back to Hyprland grim capture for headed viewport screenshots#71940
Angfr95 wants to merge 3 commits into
openclaw:mainfrom
Angfr95:fix/hyprland-wayland-screenshot

Conversation

@Angfr95

@Angfr95 Angfr95 commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

Closes #54470

Problem

On native Windows, openclaw webhooks gmail setup --account crashed immediately with
Error: spawn gcloud ENOENT. Node's child_process.spawn with shell: false does not
consult PATHEXT, so bare gcloud, gog, and tailscale are not found even when
where.exe resolves them to valid .cmd / .exe paths.

Solution

Add resolveExecutable(cmd) in src/infra/executable-path.ts:

  • No-op on non-Windows (single comparison, zero side-effects)
  • No-op if cmd already carries a known extension (.com, .exe, .bat, .cmd)
  • On win32: calls where.exe via execFileSync, prefers .cmd.exe → first result,
    falls back to original cmd on throw
  • No shell: true anywhere

Thread the resolved binary through every affected spawn site:

  • gcloudBin: module-level ??= in runGcloudCommand — one where.exe for the entire setup sequence
  • tailscaleBin: local variable in ensureTailscaleEndpoint — one where.exe for both runCommandWithTimeout calls
  • gogBin: module-level ??= shared by startGmailWatch and spawnGogServe — one where.exe for the process lifetime, zero extra calls on watcher restarts

Files changed

  • src/infra/executable-path.ts — new file, resolveExecutable
  • src/hooks/gmail-setup-utils.tsgcloudBin + tailscaleBin
  • src/hooks/gmail-watcher.tsgogBin
  • src/infra/executable-path.test.ts — 10 unit tests (all 5 resolution branches + lines[0] fallback)
  • src/hooks/gmail-setup-utils.test.ts — 3 tests covering the new cached resolution

Test results

pnpm test src/hooks/gmail-setup-utils.test.ts src/hooks/gmail.test.ts src/hooks/gmail-watcher-lifecycle.test.ts ✅
pnpm test src/process/exec.windows.test.ts src/process/windows-command.test.ts src/infra/executable-path.test.ts ✅
pnpm check:changed ✅

Notes

  • src/process/exec.ts is untouched — existing package-manager shim is unaffected
  • Fix is fully inert on macOS and Linux
  • Tested against reporter evidence: where.exe gcloud resolving to C:\Tools\gcloud\gcloud.cmd

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: XL labels Apr 26, 2026
@Angfr95
Angfr95 force-pushed the fix/hyprland-wayland-screenshot branch from 95b6abb to ada551d Compare April 26, 2026 04:04
@greptile-apps

greptile-apps Bot commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds an opt-in Hyprland/Wayland screenshot fallback using grim and a virtual Hyprland output, wiring it into the CDP screenshot route with a graceful fallback. It also includes an unrelated fix that caches external preferOver catalog lookups within each plugin auto-enable pass to reduce CPU usage on large agents.list configs.

  • Missing SIGTERM handler (hyprland-capture.ts lines 80–84): process.once("exit") does not fire on SIGTERM (used by systemd/Docker/kill). Every normal service stop leaves the HEADLESS-N virtual output on the compositor; a SIGTERM handler mirroring the existing SIGINT handler is needed.

Confidence Score: 3/5

Functional for the Hyprland capture path, but the missing SIGTERM handler leaks a virtual display output on every normal service stop — needs a one-line fix before merging.

One P1 defect (SIGTERM not handled → leaked virtual output on every systemd/Docker stop), plus two P2 style/correctness issues. The rest of the code is well-structured with thorough tests. P1 ceiling is 4; one clear P1 in a new feature path pulls the score to 3.

extensions/browser/src/browser/hyprland-capture.ts — the registerExitCleanup function needs a SIGTERM handler to match the SIGINT handler.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/hyprland-capture.ts
Line: 80-84

Comment:
**SIGTERM not handled — virtual output leaked on service stop**

`process.once("exit")` only fires when Node exits via `process.exit()` or natural completion; it does **not** fire when the process is terminated by a signal. `SIGTERM` is the default stop signal used by `kill`, systemd (`systemctl stop`), and Docker, so every normal service stop will leave the `HEADLESS-N` virtual output behind on the Hyprland compositor. Users would need to manually run `hyprctl output remove HEADLESS-N` after each restart.

```ts
  process.once("exit", cleanup);
  process.once("SIGINT", () => {
    cleanup();
    process.exit(130);
  });
+  process.once("SIGTERM", () => {
+    cleanup();
+    process.exit(143);
+  });
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/browser/src/browser/hyprland-capture.ts
Line: 218-224

Comment:
**Test reset accumulates `process.once` listeners across test runs**

`_cleanupRegistered = false` causes the next call to `registerExitCleanup` to register fresh `process.once("exit")` and `process.once("SIGINT")` handlers on top of the ones still live from the previous test run. With 10 test runs that each successfully set up capture, the process accumulates up to 10 of each listener, which will trigger Node's `MaxListenersExceededWarning`. The reset should also remove the previously registered listeners — store references to them (or use `removeAllListeners` on the specific events) before the reset clears the closures.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/browser/src/browser/routes/agent.snapshot.ts
Line: 377

Comment:
**Global `resolved.headless` used instead of per-profile headless flag**

`ctx.state().resolved.headless` reflects the top-level browser config's `headless` setting. If a specific profile overrides headless at the profile level (e.g., a profile's own `headless: true`), this check passes and Hyprland capture is attempted against a headless browser process. `grim` cannot capture a headless window, so it will fail and fall back to CDP, but it adds unnecessary latency on every screenshot for that profile.

Consider using `profileCtx.profile.headless` instead, which is the resolved per-profile value already available in scope.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: cache external plugin catalog looku..." | Re-trigger Greptile

Comment on lines +80 to +84
process.once("exit", cleanup);
process.once("SIGINT", () => {
cleanup();
process.exit(130);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 SIGTERM not handled — virtual output leaked on service stop

process.once("exit") only fires when Node exits via process.exit() or natural completion; it does not fire when the process is terminated by a signal. SIGTERM is the default stop signal used by kill, systemd (systemctl stop), and Docker, so every normal service stop will leave the HEADLESS-N virtual output behind on the Hyprland compositor. Users would need to manually run hyprctl output remove HEADLESS-N after each restart.

  process.once("exit", cleanup);
  process.once("SIGINT", () => {
    cleanup();
    process.exit(130);
  });
+  process.once("SIGTERM", () => {
+    cleanup();
+    process.exit(143);
+  });
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/hyprland-capture.ts
Line: 80-84

Comment:
**SIGTERM not handled — virtual output leaked on service stop**

`process.once("exit")` only fires when Node exits via `process.exit()` or natural completion; it does **not** fire when the process is terminated by a signal. `SIGTERM` is the default stop signal used by `kill`, systemd (`systemctl stop`), and Docker, so every normal service stop will leave the `HEADLESS-N` virtual output behind on the Hyprland compositor. Users would need to manually run `hyprctl output remove HEADLESS-N` after each restart.

```ts
  process.once("exit", cleanup);
  process.once("SIGINT", () => {
    cleanup();
    process.exit(130);
  });
+  process.once("SIGTERM", () => {
+    cleanup();
+    process.exit(143);
+  });
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +218 to +224
export function _resetHyprlandCaptureForTests(): void {
_state = null;
_setupInFlight = null;
_cleanupOutputName = null;
_cleanupHyprctl = null;
_cleanupRegistered = false;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test reset accumulates process.once listeners across test runs

_cleanupRegistered = false causes the next call to registerExitCleanup to register fresh process.once("exit") and process.once("SIGINT") handlers on top of the ones still live from the previous test run. With 10 test runs that each successfully set up capture, the process accumulates up to 10 of each listener, which will trigger Node's MaxListenersExceededWarning. The reset should also remove the previously registered listeners — store references to them (or use removeAllListeners on the specific events) before the reset clears the closures.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/hyprland-capture.ts
Line: 218-224

Comment:
**Test reset accumulates `process.once` listeners across test runs**

`_cleanupRegistered = false` causes the next call to `registerExitCleanup` to register fresh `process.once("exit")` and `process.once("SIGINT")` handlers on top of the ones still live from the previous test run. With 10 test runs that each successfully set up capture, the process accumulates up to 10 of each listener, which will trigger Node's `MaxListenersExceededWarning`. The reset should also remove the previously registered listeners — store references to them (or use `removeAllListeners` on the specific events) before the reset clears the closures.

How can I resolve this? If you propose a fix, please make it concise.

!fullPage &&
!element &&
process.platform === "linux" &&
!ctx.state().resolved.headless &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Global resolved.headless used instead of per-profile headless flag

ctx.state().resolved.headless reflects the top-level browser config's headless setting. If a specific profile overrides headless at the profile level (e.g., a profile's own headless: true), this check passes and Hyprland capture is attempted against a headless browser process. grim cannot capture a headless window, so it will fail and fall back to CDP, but it adds unnecessary latency on every screenshot for that profile.

Consider using profileCtx.profile.headless instead, which is the resolved per-profile value already available in scope.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/routes/agent.snapshot.ts
Line: 377

Comment:
**Global `resolved.headless` used instead of per-profile headless flag**

`ctx.state().resolved.headless` reflects the top-level browser config's `headless` setting. If a specific profile overrides headless at the profile level (e.g., a profile's own `headless: true`), this check passes and Hyprland capture is attempted against a headless browser process. `grim` cannot capture a headless window, so it will fail and fall back to CDP, but it adds unnecessary latency on every screenshot for that profile.

Consider using `profileCtx.profile.headless` instead, which is the resolved per-profile value already available in scope.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95b6abb8d5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

* Fixes Page.captureScreenshot timeouts on Hyprland. Requires hyprctl and grim.
* Default: false (opt-in).
*/
hyprlandCapture?: boolean;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept hyprlandCapture in validated browser schema

This adds browser.hyprlandCapture to config types and runtime resolution, but it is not added to the strict runtime schema, so users cannot actually enable it through config. OpenClawSchema validates browser with a strict object in src/config/zod-schema.ts, and that shape does not include hyprlandCapture; setting the new key will be rejected as an unknown property instead of activating the Hyprland capture fallback.

Useful? React with 👍 / 👎.

Comment on lines +81 to +83
process.once("SIGINT", () => {
cleanup();
process.exit(130);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid forcing process exit from Hyprland SIGINT handler

The new cleanup registration unconditionally calls process.exit(130) on SIGINT. In runtime contexts that already install SIGINT handlers for graceful shutdown (for example the gateway run loop), this helper will force abrupt termination once Hyprland capture has been used, which can bypass normal async stop/flush behavior. This module should not hard-exit the process from inside a feature-specific signal handler.

Useful? React with 👍 / 👎.

Comment on lines +210 to +212
// Capture error → invalidate cache so the next call re-creates the output.
_state = null;
_setupInFlight = null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Tear down virtual output when grim capture fails

On grim failure, the catch path only clears _state and _setupInFlight without removing the previously created virtual output. Subsequent attempts re-run setup and create additional outputs, while exit cleanup tracks only the latest output name, so repeated capture failures can leave orphan Hyprland virtual outputs for the life of the process.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep this PR open because current main still lacks a Hyprland/Wayland native viewport screenshot fallback and the branch contains a relevant implementation direction, but it is not merge-ready: live Hyprland proof is missing, GitHub reports conflicts, and the patch still has native-capture cleanup/isolation and public SDK-surface blockers.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #64317
Summary: The Hyprland screenshot timeout behavior is the central root cause for this PR; the Windows Gmail issue linked in the stale PR body is adjacent and already fixed elsewhere.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

Do we have a high-confidence way to reproduce the issue?

Partly. Current main still routes ordinary viewport screenshots through CDP only, and the linked Hyprland issue has concrete live timeout and downstream workaround evidence, but I did not reproduce the failure on a real Hyprland desktop.

Is this the best way to solve the issue?

No, not yet. The grim -o fallback is a plausible fix direction, but this implementation still needs setup cleanup, dedicated workspace and focus restoration, SDK/config contract alignment, branch refresh, and live Hyprland proof.

Security review:

Security review needs attention: The diff introduces a native compositor screenshot path that can capture unintended pixels unless workspace isolation and live proof are tightened.

  • [medium] Whole-output capture can cross the browser boundary — extensions/browser/src/browser/hyprland-capture.ts:108
    The PR captures an entire Hyprland virtual output after moving a browser PID to that output's active workspace. Without a dedicated capture workspace and focus restoration, the native path can return pixels from an unintended client or leave focus on the hidden output.
    Confidence: 0.76

AGENTS.md: found and applied where relevant.

What I checked:

  • stale F-rated PR: PR was opened 2026-04-26T04:02:21Z, is older than 60 days, and the latest review rated it F.
  • proof blocker: real behavior proof is missing and proof tier is F, so this branch is not merge-ready without contributor follow-up.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • steipete: History shows many browser route/config commits, including switching browser ownership to a bundled plugin and later route refactors around the affected screenshot path. (role: introduced browser plugin route/config boundary and heavy area contributor; confidence: high; commits: 8eeb7f082975, cc919db83b83, daaebb8558b3; files: extensions/browser/src/browser/routes/agent.snapshot.ts, extensions/browser/src/browser/config.ts)
  • vincentkoc: History shows recent work in plugin SDK/config-related surfaces and shortlog shows substantial contribution across the PR's SDK/config paths. (role: recent SDK/config adjacent contributor; confidence: medium; commits: aa69b12d0086, 745f1c981234; files: src/plugin-sdk/entrypoints.ts, scripts/lib/plugin-sdk-entrypoints.json, src/config/zod-schema.ts)
  • Pavan Kumar Gondhi: A recent browser route fix changed snapshot/screenshot route policy handling in the same route surface touched by this PR. (role: adjacent browser screenshot route contributor; confidence: medium; commits: b75ad800a590; files: extensions/browser/src/browser/routes/agent.snapshot.ts)

Codex review notes: model internal, reasoning high; reviewed against 47d3d1b1f1b2.

@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Apr 30, 2026
拐爷&&老拐瘦 and others added 3 commits April 30, 2026 06:25
…6246) (thanks @yfge)

* fix: cache external plugin catalog lookups in auto-enable

Fixes openclaw#66159

* test: restore readFileSync spy in plugin auto-enable test

* refactor: distill plugin auto-enable cache path

* fix: cache external plugin catalog lookups in auto-enable (openclaw#66246) (thanks @yfge)

---------

Co-authored-by: Ayaan Zaidi <[email protected]>
Add focused openclaw/plugin-sdk/resolve-system-bin subpath so bundled
extensions avoid importing the broad infra-runtime barrel flagged by
the newer boundary check. Regenerate schema snapshot with title and
description for hyprlandCapture so the config snapshot test stays green.
@Angfr95
Angfr95 force-pushed the fix/hyprland-wayland-screenshot branch from fdcb510 to e30d5bd Compare April 30, 2026 04:28
@Angfr95

Angfr95 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review. This PR was superseded by #71940 which addresses all the blockers raised here — cc @steipete for routing.

  1. Tests — 10 unit tests in hyprland-capture.test.ts cover non-Hyprland fallback, concurrent setup, cache reset on failure, and teardown. 14 route-level tests in agent.snapshot.test.ts cover path selection including the per-profile headless guard.
  2. Binary resolverhyprland-capture.ts imports resolveSystemBin from src/plugin-sdk/infra-runtime.ts (the existing helper), not a parallel trusted-dir list.
  3. Explicit opt-in — the feature is gated behind browser.hyprlandCapture: true in config and only activates when HYPRLAND_INSTANCE_SIGNATURE is set and the profile is not headless. It is not automatic.
  4. Cleanup/lifecycle — SIGINT, SIGTERM, and process exit handlers are registered with named refs. teardownHyprlandCapture() is called on grim failure to remove orphan virtual outputs. _resetHyprlandCaptureForTests removes all listeners before resetting state.

The PNG-only behavior on the Hyprland path and the troubleshooting doc are also included in #71940.

Also cc @steipete —I want to flag a serious attribution issue with PR #74690 merged today.

Full timeline:

1 - I opened #66395 two weeks ago fixing #65522 with the correct guard + 6 browser render tests
2 - @vΛL 🦞 requested changes asking me to remove unrelated Slack edits
3 - I fixed it in 30 minutes — PR was clean and ready for re-review
4 - While my PR was waiting, BunsDev had already opened #74690 with the same fix and merged it, explicitly writing "I am superseding the UI fix with a clean local maintainer patch"
5 - By linking the same issue #65522, she triggered the bot to auto-close my PR as superseded

This is not a coincidence. A writer used their review position to stall my PR, copied the fix, and used the issue link to trigger the bot closure. Everything is timestamped and verifiable on GitHub.

I am the original author of this fix. I am not asking for co-authorship — I am asking maintainers to revert #74690 and merge #66395 or #74819 so the commit is correctly attributed.

Refs: #65522, #66395, #74690, #74819

@Angfr95 Angfr95 changed the title fix(browser): fall back to Hyprland grim capture for headed viewport screenshots fix(windows): resolve gcloud/gog/tailscale PATHEXT shims before spawn to fix ENOENT on Windows Apr 30, 2026
@Angfr95
Angfr95 force-pushed the fix/hyprland-wayland-screenshot branch from 066e6a7 to e30d5bd Compare April 30, 2026 05:28
@Angfr95 Angfr95 changed the title fix(windows): resolve gcloud/gog/tailscale PATHEXT shims before spawn to fix ENOENT on Windows fix(browser): fall back to Hyprland grim capture for headed viewport screenshots Apr 30, 2026
@dougvk

dougvk commented May 20, 2026

Copy link
Copy Markdown
Contributor

Adding implementation feedback from a live downstream Omarchy/Arch/Hyprland validation pass.

This PR is pointed in the right direction, especially the use of grim -o <output> rather than depending on CDP for the affected headed viewport path. The local downstream fix still needed two extra pieces to make the path reliable in practice:

  1. Use a dedicated named capture workspace on the virtual output.

In the local proof, relying only on the virtual output's current active workspace was not enough. The robust setup was:

  • create/reuse the headless output,
  • create/reuse a named workspace such as openclaw-capture-<profile>,
  • move that workspace to the headless output,
  • move only the target Chromium window to that named workspace,
  • capture the output with grim -o.

This reduces wrong-window risk if the compositor places another client on the same output/workspace.

  1. Restore focus after setup and after every capture.

Creating/selecting the capture workspace and later opening/navigating tabs can focus the hidden output. In the local proof, restoring focus during setup was not sufficient by itself; the screenshot path also had to restore focus after grim returned or failed.

Suggested merge proof for this PR:

  • live headed Hyprland screenshot returns quickly via the native path,
  • coredumpctl list grim --since <test-start> shows no new grim coredumps,
  • gateway logs show no Hyprland capture/setup warnings in the proof window,
  • no virtual output or capture workspace is leaked after stop,
  • focus returns to the real monitor after capture,
  • route tests cover fallback if native capture throws.

No private config or local paths are needed for the proof; the above can be shown with redacted command output.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 20, 2026
@clawsweeper clawsweeper Bot added P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 20, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 14, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. label Jun 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 15, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 17, 2026
@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. scripts Repository scripts size: L status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: openclaw webhooks gmail setup fails on native Windows with Error: spawn gcloud ENOENT

3 participants