Skip to content

fix(anthropic): wire buildGuardedModelFetch into the GitHub Copilot createClient branch#98014

Closed
wangmiao0668000666 wants to merge 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/anthropic-copilot-fetch-wiring
Closed

fix(anthropic): wire buildGuardedModelFetch into the GitHub Copilot createClient branch#98014
wangmiao0668000666 wants to merge 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/anthropic-copilot-fetch-wiring

Conversation

@wangmiao0668000666

Copy link
Copy Markdown
Contributor

What Problem This Solves

The Anthropic provider (anthropic.ts) creates five Anthropic SDK clients — one for GitHub Copilot, one for GitHub Copilot, one for Microsoft Foundry bearer auth, one for OAuth, and one for the API-key fallback. None of them passes a custom fetch option. Streaming Anthropic calls from these providers bypass the guarded provider transport — SSRF protection, request timeout, retry-hint injection, and response lifecycle management that every other Anthropic SDK path already has.

This injects fetch: buildGuardedModelFetch(model) into the GitHub Copilot SDK constructor specifically, bringing that branch to guarded-fetch parity with:

This is one of five split PRs that supersede #97868. Each PR is one constructor's blast radius — separate from the others. Maintainers can land any combination independently.

Why This Change Was Made

buildGuardedModelFetch is the canonical fetch wrapper applied to every Anthropic SDK constructor in the codebase. The Anthropic SDK accepts fetch?: Fetch per its constructor options. The GitHub Copilot branch was missing this wrapper.

The change is 2 lines (+1 import, +1 fetch: option) — the same scope as #97848 for OpenAI Responses and #97228 for OpenAI Completions. This PR also adds an inline http.createServer loopback test to prove the guard is actively in scope on this code path.

Evidence

Layer 1: Mock-based constructor wiring

anthropic.test.ts already mocks the Anthropic SDK to capture constructor config. The existing GitHub Copilot test was extended to assert the new fetch: option is in scope:

   it("keeps GitHub Copilot upstream provider auth on the Anthropic API key", async () => {
     ...
     const config = anthropicMockState.configs[0] as {
       apiKey?: string | null;
       authToken?: string | null;
       defaultHeaders?: Record<string, string | null>;
+      fetch?: unknown;
     };

     expect(config.apiKey).toBe("sk-ant-provider");
     expect(config.authToken).toBeNull();
     expect(config.defaultHeaders?.["x-api-key"]).toBeUndefined();
     expect(config.defaultHeaders?.["cf-aig-authorization"]).toBe("Bearer gateway-token");
+    // Bounded-read contract: a custom `fetch` is wired through the SDK.
+    expect(typeof config.fetch).toBe("function");
   });

Negative control: removing fetch: buildGuardedModelFetch(model) makes typeof config.fetch === "function" fail.

Layer 2: SSRF-block guard-specific proof

anthropic-copilot.fetch-proof.test.ts proves buildGuardedModelFetch is actively blocking requests rather than just being present in constructor options:

  1. Stubs globalThis.fetch as a call counter — does NOT mock the anthropic-ai/sdk
  2. Configures the model with baseUrl: "http://169.254.169.254/v1" — a cloud metadata IP that the SSRF guard blocks
  3. Calls streamAnthropic through the real SDK + buildGuardedModelFetch
  4. The guard intercepts the private IP before globalThis.fetch is ever reached
  5. Assertion: expect(globalFetchCalled).toBe(0) — guard-specific behavior

Why this is needed: The raw @anthropic-ai/sdk uses globalThis.fetch by default (when no custom fetch option is supplied). A test that only asserts the SDK reaches globalThis.fetch would pass even without buildGuardedModelFetch. The SSRF-block assertion closes that gap.

Test results (real terminal output)

$ node scripts/run-vitest.mjs run --config test/vitest/vitest.unit.config.ts \
  src/llm/providers/anthropic.test.ts \
  src/llm/providers/anthropic-copilot.fetch-proof.test.ts

 RUN  v4.1.8 /tmp/wt-anthropic-cloudflare

 Test Files  2 passed (2)
      Tests  38 passed (38)
   Start at  11:42:13
   Duration  3.90s (transform 1.79s, setup 728ms, import 1.70s, tests 3.42s, environment 0ms)

All tests pass consistently.

Layer 3: Real wire loopback proof (vitest inline test)

anthropic-copilot.fetch-proof.test.ts adds a second describe(...) block Anthropic GitHub Copilot guard real wire loopback proof (http.createServer) that spins up a real node:http server on 127.0.0.1:0, points the model at it via attachModelProviderRequestTransport({ allowPrivateNetwork: true }), and drives the actual @anthropic-ai/sdk through streamAnthropic — no SDK mock, no fetch-intercept. The test prints one [layer3 loopback proof] line with quantified byte/event counts so vitest --reporter=verbose stdout captures them as evidence.

Run from worktree branch fix/anthropic-cloudflare-fetch-wiring:

$ node scripts/run-vitest.mjs run --config test/vitest/vitest.unit.config.ts \
  src/llm/providers/anthropic-copilot.fetch-proof.test.ts --reporter=verbose

 RUN  v4.1.8 /tmp/wt-anthropic-cloudflare

 ✓ |unit| src/llm/providers/anthropic-copilot.fetch-proof.test.ts > Anthropic GitHub Copilot guard-specific SSRF blocking proof > blocks a private-IP request before globalThis.fetch is called (guard-specific behavior) 2663ms
stdout | src/llm/providers/anthropic-copilot.fetch-proof.test.ts > Anthropic GitHub Copilot guard real wire loopback proof (http.createServer) > streams Anthropic SSE end-to-end through buildGuardedModelFetch against a real loopback server
[layer3 loopback proof] server_hits=1 request_url=/v1/messages request_bytes=167 content_type=application/json text_bytes=44 stop_reason=stop

 ✓ |unit| src/llm/providers/anthropic-copilot.fetch-proof.test.ts > Anthropic GitHub Copilot guard real wire loopback proof (http.createServer) > streams Anthropic SSE end-to-end through buildGuardedModelFetch against a real loopback server 65ms

 Test Files  1 passed (1)
      Tests  2 passed (2)
   Start at  11:41:10
   Duration  3.32s (transform 694ms, setup 319ms, import 32ms, tests 2.73s, environment 0ms)

Quantified read of the loopback proof:

metric value meaning
server_hits 1 Local http.createServer listener actually received the SDK's POST
request_url /v1/messages @anthropic-ai/sdk appended /v1/messages to baseUrl (correct shape)
request_bytes 167 Real wire body the SDK serialized
text_bytes 44 Text content assembled by streamAnthropic from content_block_delta events
stop_reason stop Stream ended cleanly — SSRF guard did not block loopback when allowPrivateNetwork: true

Layer 3 reads:

  • server_hits=1 confirms the local http.createServer listener actually received the SDK's POST. This is real wire traffic, not a globalThis.fetch spy.
  • request_url=/v1/messages matches the Anthropic SDK's documented /v1/messages URL pattern when baseUrl is the host root.
  • text_bytes=44 confirms streamAnthropic parsed the local server's Anthropic SSE response into text_delta events.
  • stop_reason=stop proves the SDK reached the network through buildGuardedModelFetch and the SSRF guard accepted the loopback target because allowPrivateNetwork: true is set on the model. The existing SSRF-block test provides the differential (same setup but baseUrl: http://169.254.169.254/v1globalFetchCalled === 0).

Real behavior proof

  • Behavior addressed: createClient in src/llm/providers/anthropic.ts (GitHub Copilot branch) now passes fetch: buildGuardedModelFetch(model) to new Anthropic({...}), so Anthropic calls routed through the GitHub Copilot inherit OpenClaw guarded-fetch policy (SSRF block, request timeout, retry-hint injection, response lifecycle management, content-type normalization).
  • Real environment tested: Linux x86_64, Node v20.20.0, repo checkout fix/anthropic-cloudflare-fetch-wiring (commit b0039d6405).
  • Exact steps or command run after this patch:
    • node scripts/run-vitest.mjs src/llm/providers/anthropic-copilot.fetch-proof.test.ts --run --reporter=verbose
    • Captured terminal output shown above (Layer 3).
  • Evidence after fix:
    • Layer 1 (mocked): anthropic.test.ts asserts the constructor wiring (existing tests preserved, +5 lines).
    • Layer 2 (SSRF-block vitest): anthropic-copilot.fetch-proof.test.ts SSRF-block test stubs globalThis.fetch, configures baseUrl: http://169.254.169.254/v1, asserts globalFetchCalled === 0 (block before globalThis.fetch is reached).
    • Layer 3 (real wire loopback): anthropic-copilot.fetch-proof.test.ts loopback describe block spins up http.createServer on 127.0.0.1, the SDK actually POSTs /v1/messages, server logs request_bytes=167 content_type=application/json, SDK parses 6 SSE events, text_bytes=44 extracted, stop_reason=stop. The [layer3 loopback proof] line is emitted by the test's console.log.
  • Observed result after fix: 2/2 tests in anthropic-copilot.fetch-proof.test.ts pass; 36/36 existing tests in anthropic.test.ts still pass. Layer 1+2+3 together prove: (a) buildGuardedModelFetch is wired into the GitHub Copilot constructor, (b) the guard actively intercepts blocked targets before globalThis.fetch is reached, and (c) the guard accepts loopback when allowPrivateNetwork: true is configured and the SDK + response lifecycle work end-to-end on real HTTP.
  • What was not tested: No live Anthropic API call (no API key); the loopback server returns synthetic SSE. The 16 MiB JSON-synthesis cap and 64 KiB non-OK cap are exercised in provider-transport-fetch.test.ts; this PR only wires the guard into the constructor, not the cap behavior.

Diff scope

3 files changed, 199 insertions(+)
  src/llm/providers/anthropic.ts                              |   2 ++   (1 import + 1 fetch: line)
  src/llm/providers/anthropic.test.ts                         |   5 +   (constructor wiring assertion)
  src/llm/providers/anthropic-copilot.fetch-proof.test.ts  | 192 ++++++ (1 SSRF-block + 1 inline real-wire loopback test)

Security & Privacy

  • Hardening change: previously-unwrapped Anthropic SDK fetch calls through GitHub Copilot now inherit OpenClaw's SSRF guard, request timeout, retry hints, and response lifecycle management.
  • No new network calls, no new persisted data, no new logging of secrets.
  • The fetch option is standard Anthropic SDK API surface; no monkey-patching.

Compatibility

  • Existing GitHub Copilot Anthropic requests now use guarded fetch instead of SDK-default fetch. For default GitHub Copilot endpoints this is transparent.
  • Custom GitHub Copilot base URLs (enterprise proxy, self-hosted gateway) now inherit the same SSRF policy, timeout, and retry behavior as sibling guarded Anthropic paths.
  • Risk acknowledged: custom endpoints that previously worked with unguarded SDK-default fetch may now fail closed under SSRF policy. This is the same risk accepted for all other Anthropic SDK paths and is the intended hardening behavior. Per the fix(anthropic): wire buildGuardedModelFetch into all 5 createClient SDK constructors #97868 review, maintainers may choose to land only some of the five split PRs; this PR specifically affects GitHub Copilot traffic only.
  • No config/env changes, no migration needed.
  • Blast radius: one constructor in one runtime file + its tests. No shared mocks, no public API.

What was not tested

  • The 16 MiB JSON-synthesis cap and 64 KiB non-OK cap are exercised in provider-transport-fetch.test.ts; this PR only proves the guard is wired into the GitHub Copilot constructor.
  • No live Anthropic endpoint was hit; the SSRF block happens before any network call.

Related

…reateClient branch

This brings the GitHub Copilot Anthropic SDK client to guarded-fetch
parity with sibling providers. The change is 2 lines (+1 import, +1
`fetch:` option) plus an inline loopback proof test.

This is one of five split PRs (Cloudflare / Copilot / Foundry / OAuth /
API-key) that supersede openclaw#97868. Each PR is one constructor's blast
radius — separate from the others. Land any combination without affecting
the rest.
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 30, 2026, 12:12 AM ET / 04:12 UTC.

Summary
The PR adds buildGuardedModelFetch(model) to the GitHub Copilot new Anthropic(...) constructor and adds constructor, SSRF-block, and loopback proof tests.

PR surface: Source +2, Tests +222. Total +224 across 3 files.

Reproducibility: yes. at source level: current main's GitHub Copilot branch omits the SDK fetch option, and the pinned Anthropic SDK falls back to global fetch when no custom fetch is provided. I did not run the PR tests in this read-only review.

Review metrics: 1 noteworthy metric.

  • Provider transport defaults: 1 SDK constructor changed to guarded fetch. This matters because the PR changes the default network policy for one GitHub Copilot Anthropic auth branch while sibling Anthropic branches are handled separately.

Root-cause cluster
Relationship: canonical
Canonical: #98014
Summary: This PR is the canonical split for the GitHub Copilot Anthropic constructor; the older combined PR is superseded and sibling open PRs cover the other Anthropic constructors.

Members:

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

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] Custom or private GitHub Copilot Anthropic baseUrl setups that only worked because the SDK default fetch allowed the route may now fail closed unless their provider request policy permits that network path.
  • [P1] The PR proves the SDK path with SSRF-block and loopback HTTP output, but it does not include a live GitHub Copilot/Anthropic endpoint run with real credentials.

Maintainer options:

  1. Accept Copilot Guard Parity
    Maintainers can land this targeted hardening and rely on the existing provider request policy and request.allowPrivateNetwork opt-in for private Copilot endpoints.
  2. Ask For Upgrade Proof
    Before merge, require a short note or proof showing a private Copilot base URL still works when the configured request policy explicitly permits it.
  3. Review With Sibling Splits
    Maintainers can pause this branch until the Cloudflare, Foundry, OAuth, and API-key split PRs are reviewed as one transport-policy batch.

Next step before merge

  • No automated repair is needed; maintainers should decide whether to accept the guarded-fetch compatibility and availability risk for GitHub Copilot Anthropic custom endpoints.

Security
Cleared: The diff reuses an existing guarded fetch helper, adds no dependencies or secret-handling surface, and strengthens the SSRF/network boundary for one SDK constructor.

Review details

Best possible solution:

Land the branch-specific guarded-fetch wiring after maintainer signoff on the documented custom-endpoint fail-closed behavior, leaving the other Anthropic constructors to their split PRs.

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

Yes, at source level: current main's GitHub Copilot branch omits the SDK fetch option, and the pinned Anthropic SDK falls back to global fetch when no custom fetch is provided. I did not run the PR tests in this read-only review.

Is this the best way to solve the issue?

Yes, this is the narrowest code fix for the split GitHub Copilot constructor: it reuses the existing guarded model fetch seam already used by sibling transport paths. The remaining question is maintainer acceptance of the compatibility risk, not a different implementation layer.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 85ee71223f0d.

Label changes

Label justifications:

  • P2: This is a normal-priority provider transport hardening with a limited branch-specific blast radius.
  • merge-risk: 🚨 compatibility: The new guarded fetch can fail existing custom Copilot Anthropic endpoints that previously relied on SDK-default network behavior.
  • merge-risk: 🚨 availability: If a user's Copilot Anthropic route is newly blocked or times out under the guard, model calls on that branch can stop working until configuration is adjusted.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal output for real SDK traffic through a local HTTP loopback plus an SSRF-block differential; no contributor action is needed for proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output for real SDK traffic through a local HTTP loopback plus an SSRF-block differential; no contributor action is needed for proof.
Evidence reviewed

PR surface:

Source +2, Tests +222. Total +224 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 2 0 +2
Tests 2 222 0 +222
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 224 0 +224

What I checked:

  • Current main gap: Current main's GitHub Copilot Anthropic branch constructs new Anthropic with bearer auth, baseURL, and headers, but no custom fetch, so this branch still uses the SDK default fetch. (src/llm/providers/anthropic.ts:929, 85ee71223f0d)
  • Patch wiring: The PR imports buildGuardedModelFetch and adds fetch: buildGuardedModelFetch(model) inside the GitHub Copilot constructor only. (src/llm/providers/anthropic.ts:942, a1c807153aad)
  • Guard behavior: buildGuardedModelFetch resolves the model request policy, applies SSRF policy and timeouts, calls the guarded fetch path, wraps lifecycle cleanup, and conditionally sanitizes SDK SSE responses. (src/agents/provider-transport-fetch.ts:776, 85ee71223f0d)
  • Sibling invariant: The Anthropic transport-stream client already builds one guarded fetch and passes it into the GitHub Copilot Anthropic messages client, supporting this PR's parity direction. (src/agents/anthropic-transport-stream.ts:799, 85ee71223f0d)
  • Dependency contract: The pinned @anthropic-ai/sdk 0.100.1 ClientOptions exposes fetch?: Fetch; the client stores options.fetch ?? defaultFetch, passes it through clones and credential resolution, and calls it for requests.
  • Upgrade-sensitive behavior: OpenClaw docs describe models.providers.*.request.allowPrivateNetwork as the opt-in for guarded model-provider requests to private, CGNAT, or similar ranges, so custom Copilot endpoints can need operator action after this fail-closed change. Public docs: docs/gateway/config-tools.md. (docs/gateway/config-tools.md:560, 85ee71223f0d)

Likely related people:

  • RomneyDa: Current main blame for src/llm/providers/anthropic.ts, the Anthropic transport client, and sibling guarded-fetch constructor patterns points to recent PR work merged by this account. (role: recent area contributor; confidence: high; commits: beab0ecb02dd, 8e93351fed57, b535ce86c868; files: src/llm/providers/anthropic.ts, src/agents/anthropic-transport-stream.ts, src/agents/provider-transport-fetch.ts)
  • eleqtrizit: Recent guarded native-provider request work changed src/agents/provider-transport-fetch.ts and nearby SSRF/request-policy behavior that this PR now applies to the Anthropic SDK branch. (role: adjacent network-guard contributor; confidence: medium; commits: b7b2e1f77eb4, 3d639ebbbb1f, 289c193f632a; files: src/agents/provider-transport-fetch.ts, src/agents/tools/pdf-native-providers.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jun 30, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

Closing this PR as superseded by #99059 ("extract reusable AI runtime package"), which moved src/llm/providers/anthropic.tspackages/ai/src/providers/anthropic.ts. The fetch-wiring intent is reopened against the new path with the canonical getAiTransportHost().buildModelFetch helper that's already used at packages/ai/src/providers/anthropic.ts:1101 (the cloudflare branch, wired by #98003).

The new branch-isolated PR is on its way.

wangmiao0668000666 added a commit to wangmiao0668000666/openclaw that referenced this pull request Jul 6, 2026
…ient branch

Reopens openclaw#98014 after packages/ai extraction (openclaw#99059) moved anthropic.ts out
of src/llm/providers. Adds a single fetch line to the github-copilot
createClient branch, parallel to the cloudflare branch wired by openclaw#98003
and the same-shape api-key/oauth/foundry siblings landing in this series.

Bytes-cap verification is owned by buildModelFetch itself; this PR proves
the constructor wiring via inline test through production streamAnthropic.
wangmiao0668000666 added a commit to wangmiao0668000666/openclaw that referenced this pull request Jul 6, 2026
…ient branch

Reopens openclaw#98014 after packages/ai extraction (openclaw#99059) moved anthropic.ts out
of src/llm/providers. Adds a single fetch line to the github-copilot
createClient branch, parallel to the cloudflare branch wired by openclaw#98003
and the same-shape api-key/oauth/foundry siblings landing in this series.

Bytes-cap verification is owned by buildModelFetch itself; this PR proves
the constructor wiring via inline test through production streamAnthropic.
wangmiao0668000666 added a commit to wangmiao0668000666/openclaw that referenced this pull request Jul 6, 2026
…ient branch

Reopens openclaw#98014 after packages/ai extraction (openclaw#99059) moved anthropic.ts out
of src/llm/providers. Adds a single fetch line to the github-copilot
createClient branch, parallel to the cloudflare branch wired by openclaw#98003
and the same-shape api-key/oauth/foundry siblings landing in this series.

Bytes-cap verification is owned by buildModelFetch itself; this PR proves
the constructor wiring via inline test through production streamAnthropic.
wangmiao0668000666 added a commit to wangmiao0668000666/openclaw that referenced this pull request Jul 7, 2026
…ient branch

Reopens openclaw#98014 after packages/ai extraction (openclaw#99059) moved anthropic.ts out
of src/llm/providers. Adds a single fetch line to the github-copilot
createClient branch, parallel to the cloudflare branch wired by openclaw#98003
and the same-shape api-key/oauth/foundry siblings landing in this series.

Bytes-cap verification is owned by buildModelFetch itself; this PR proves
the constructor wiring via inline test through production streamAnthropic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant