Skip to content

feat(web): show current-provider usage in the chat box - #8445

Open
Aditya190803 wants to merge 17 commits into
pingdotgg:mainfrom
Aditya190803:feat/usage-in-chat
Open

feat(web): show current-provider usage in the chat box#8445
Aditya190803 wants to merge 17 commits into
pingdotgg:mainfrom
Aditya190803:feat/usage-in-chat

Conversation

@Aditya190803

@Aditya190803 Aditya190803 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Stacked on #1732. Unique changes vs that branch: remaining session/weekly usage for the current thread's provider next to the chat box.

Review only this stack

  • Off by default: Settings → General → Show usage in chat
  • Hidden on a new thread until the first message is sent
  • Codex thread shows Codex only; switching providers switches the meter
  • If a context-window ring is visible, the bars live in that hover (not mixed into the ring number)
  • If there is no ring after a turn, a compact percent control appears next to send
  • Providers without a usable quota snapshot hide the meter

Settings (opt-in, default off)

Show usage in chat setting

Chat box hover after a turn

Session and weekly usage in the context-window hover

Test plan

  • Toggle remains off by default; empty new thread does not show a percent next to send
  • After enabling the setting and sending a message, context-window hover shows Usage bars for the current provider
  • Switching the thread's provider switches the meter; providers without quota hide it

Note

Medium Risk
Touches provider status checks and PTY subprocess probing on every refresh, but failures degrade to “usage unavailable” rather than blocking auth or chat.

Overview
Adds usageLimits to provider status snapshots across Claude, Codex, Cursor, Grok, and OpenCode (Go/Zen), using PTY CLI probes, Codex app-server account/rateLimits/read, OpenCode inventory fields, and Grok ACP auth plus TUI /usage. Snapshots carry structured windows (percent used, reset times, unavailable reasons for API-key/Bedrock/free tiers).

Server lifecycle: makeManagedServerProvider gains applyUsageLimits so live account.rate-limits.updated events (via ProviderUsageLimitsIngestion) patch quotas without waiting for the next health refresh, with merge logic so in-flight probes/enrichment do not stomp fresher runtime updates. Claude/Cursor/Grok drivers optionally inject PtyAdapter from the registry layer so probes work in full server runtimes.

Clients: Mobile Usage gets a Provider limits section with progress bars per environment/provider. Desktop settings test expects showProviderUsageInComposer: true (feeds the stacked chat-box meter). .claude-work-test/ is gitignored to avoid committing test session files.

Reviewed by Cursor Bugbot for commit e464240. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add provider usage meter to chat composer and provider usage probes

  • Adds a showProviderUsageInComposer setting and a ComposerUsageMeter component to display current provider usage in the chat box.
  • Adds server-side usage probes for Claude, Codex, Cursor, Grok, and OpenCode to gather usage limits from CLI output or ACP.
  • Adds a ProviderUsageLimitsIngestionLive layer to apply live usage updates to provider snapshots.
  • Improves PTY adapters: Windows kill uses taskkill /T, and onExit replays the last event to late subscribers.
  • Risk: NodePtyProcess.kill on Windows now spawns taskkill via node:child_process.spawn; check fallback behavior in NodePtyAdapter.ts if taskkill fails.
📊 Macroscope summarized 3168a0c. 40 files reviewed, 16 issues evaluated, 8 issues filtered, 8 comments posted

🗂️ Filtered Issues

apps/mobile/src/features/usage/UsageRouteScreen.tsx — 1 comment posted, 2 evaluated, 1 filtered
  • line 602: When a provider reports usageLimits.available: true with an empty windows array, this branch renders only the provider name and no meter or explanation. Empty windows are a valid decoded outcome when all received windows have invalid percentages, so the mobile Usage screen presents a misleading blank provider row instead of treating usage as unavailable or hiding it. [ Out of scope (post-validation triage) ]
apps/server/src/provider/Layers/CursorProvider.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 1113: The new probeCursorUsageLimits call exposes an immediate-exit cleanup bug in collectPtyProbeOutput: its replayed onExit callback can settle the promise before that helper installs its timeout, after which it still installs an uncleared 25-second timer. Thus, when the usage PTY exits immediately (for example, an interactive Cursor launch failure), this successful status check leaves a referenced Node timer behind and can delay server-process shutdown by 25 seconds. [ Out of scope (triage) ]
apps/server/src/provider/Layers/GrokProvider.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 453: The new probeGrokUsageLimits call exposes an immediate-exit cleanup bug in collectPtyProbeOutput: its replayed onExit callback can settle before the helper creates its timeout, but the helper then creates an uncleared 10-second timer. A Grok usage PTY that exits immediately (such as an interactive-launch failure) therefore leaves a referenced timer that can delay server-process shutdown despite the status probe having returned. [ Out of scope (triage) ]
apps/server/src/provider/Layers/ProviderUsageLimitsIngestion.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 62: Effect.forkScoped schedules the entire Stream.runForEach at line 62, while providerService.streamEvents is backed by Stream.fromPubSub, whose subscription is acquired only when that fork begins running. A rate-limit event published in that gap has no subscriber and is dropped, so the first live Claude/Codex usage update can remain stale until a later status refresh. [ Out of scope (post-validation triage) ]
apps/server/src/provider/opencodeRuntime.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 138: providerId in OPENCODE_MANAGED_PROVIDER_DESCRIPTORS also accepts inherited Object.prototype names such as constructor or toString. A configured/returned provider with one of those IDs is therefore treated as a managed Go/Zen provider, but the returned value is the inherited function rather than a descriptor; downstream usage extraction reads descriptor.label as undefined and can emit a malformed usage window for that unrelated provider. Check own keys (for example, Object.hasOwn) instead. [ Out of scope (post-validation triage) ]
apps/web/src/components/usage/ProviderQuotaLimits.tsx — 1 comment posted, 4 evaluated, 3 filtered
  • line 73: isGrokFreeTier recognizes only "free", but the server classifies "none" and "unpaid" subscription tiers as non-paying tiers too and deliberately omits their quota snapshots. Consequently those authenticated Grok accounts reach providerQuotaNotice as the generic "Usage data unavailable" rather than the intended paid-tier-only explanation. [ Out of scope (post-validation triage) ]
  • line 86: providerQuotaNotice reports no notice for an available snapshot even when its windows array is empty. This is reachable for a forward-compatible payload: the contract deliberately drops unrecognized window kinds while retaining available: true. QuotaEnvironmentGroup then renders the provider header but ProviderUsageBars returns null for that empty array, leaving a blank provider card instead of hiding it or explaining that no supported quota windows are available. [ Out of scope (post-validation triage) ]
  • line 248: showEnvironmentLabels is based on every entry in configs, rather than on the quota groups that survive filtering. With two connected configurations but quota-capable providers in only one, collectQuotaGroups returns one group while assigning it an unnecessary environment heading, contradicting the intended single-environment-with-quota-data presentation. [ Out of scope (post-validation triage) ]

Aditya190803 and others added 16 commits August 16, 2026 15:05
Show session and weekly quota on each provider in Settings, from status probes and live rate-limit events. Replays the existing feature onto current main so the PR is the real 43-file change instead of a merge-commit dump of unrelated history.

Co-authored-by: Cursor <cursoragent@cursor.com>
Match Claude live usage on claudeAgent, keep live patches across status refresh, format reset times with the user's clock setting, honor reduced motion on usage bars, and stop Codex rate-limit probing from swallowing interrupts.

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
Move subscription bars off Settings, parse Claude session resets without treating Last 7d stats as weekly quota, and wait for the Cursor composer (including the wide-PTY Run a command placeholder) before sending /usage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve conflict in UsagePage.tsx: keep upstream's redesigned page (WorkspacePageContainer + topbar controls) and re-add ProviderQuotaLimitsSection inside it.

Co-authored-by: Cursor <cursoragent@cursor.com>
Track which usage windows a live event patched so a periodic probe can no longer overwrite just those bars, and drop the settings-changed override that let an unavailable probe wipe last-good bars. Share the UTC date-only formatter for reset dates and tune the quota badge layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
…provider-usage-limits

# Conflicts:
#	apps/server/src/provider/Layers/ProviderRegistry.test.ts
…provider-usage-limits

# Conflicts:
#	apps/server/src/provider/Layers/GrokProvider.ts
#	apps/web/src/components/usage/UsagePage.tsx
#	docs/user/usage.md
Keep probes from hanging the rest of status checks, preserve last-good quota bars, and stop empty usage tiles from rendering without an explanation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replay last-exit on a microtask so Terminal Manager can assign session.process first. On Windows, kill the PTY tree with taskkill so cmd.exe-launched CLI children do not leak.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
Add an opt-in setting that shows session and weekly quota for the thread's current provider in the context-window hover, instead of mixing every provider into the chat UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
Empty new threads were showing a quota percent next to send. Keep the meter off until the thread has started a turn.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 49df763f-79db-490a-8fb0-56b2a5eb8058

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 27, 2026
if (!date) return null;
// Cursor's panel is date-only ("Resets 16 Sept"). We store that as UTC
// midnight; including a clock would invent a local time like 5:30 AM.
if (/T00:00:00(?:\.000)?Z$/.test(resetsAt)) {

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.

🟡 Medium usage/ProviderQuotaLimits.tsx:39

formatUsageResetDate renders every T00:00:00Z reset as a date-only UTC value, so real midnight-UTC instants from providers such as Claude lose their meaningful clock and display the wrong local calendar date for users west of UTC. The date-only classification must come from the provider/source (for example, via an explicit flag), rather than the timestamp shape alone.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/usage/ProviderQuotaLimits.tsx around line 39:

`formatUsageResetDate` renders every `T00:00:00Z` reset as a date-only UTC value, so real midnight-UTC instants from providers such as Claude lose their meaningful clock and display the wrong local calendar date for users west of UTC. The date-only classification must come from the provider/source (for example, via an explicit flag), rather than the timestamp shape alone.

if (isAuthoritativeUsageUnavailable(probed)) {
return probed;
}
if (published?.available === true && probed?.available !== true) {

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.

🟡 Medium provider/providerUsageLimits.ts:188

A successful Grok refresh that returns undefined leaves the previous paid-tier windows visible indefinitely when published.available is true. The published?.available === true && probed?.available !== true branch treats Grok's authenticated Free/None/Unpaid result as a transient probe failure and returns published; distinguish that authoritative no-usage result from a failed probe so the old bars are cleared.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/providerUsageLimits.ts around line 188:

A successful Grok refresh that returns `undefined` leaves the previous paid-tier windows visible indefinitely when `published.available` is `true`. The `published?.available === true && probed?.available !== true` branch treats Grok's authenticated Free/None/Unpaid result as a transient probe failure and returns `published`; distinguish that authoritative no-usage result from a failed probe so the old bars are cleared.

if (!kind || windows.has(kind)) continue;

const segmentLines = [line];
for (let cursor = index + 1; cursor < lines.length && segmentLines.length < 3; cursor += 1) {

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.

🟡 Medium provider/claudeUsageProbe.ts:264

For Claude's session-only output, extractWindowSegments returns a resetsAt converted using the probe host timezone instead of the account's IANA timezone (for example, Asia/Kolkata) when the hosts differ. The loop adds the following What's contributing... line to segmentLines, so segmentLines.join(" ") puts text after (Asia/Kolkata) and breaks the end-anchored IANA_TIMEZONE_PATTERN; stop collecting once the reset line has been included (or otherwise preserve the timezone suffix) before calling parseClaudeUsageWindowSegment.

-    for (let cursor = index + 1; cursor < lines.length && segmentLines.length < 3; cursor += 1) {
+    for (let cursor = index + 1; cursor < lines.length && segmentLines.length < 3 && !/\breset(?:s|ting)?(?:\s+(?:at|on|in))?/i.test(segmentLines[segmentLines.length - 1] ?? ""); cursor += 1) {
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/claudeUsageProbe.ts around line 264:

For Claude's session-only output, `extractWindowSegments` returns a `resetsAt` converted using the probe host timezone instead of the account's IANA timezone (for example, `Asia/Kolkata`) when the hosts differ. The loop adds the following `What's contributing...` line to `segmentLines`, so `segmentLines.join(" ")` puts text after `(Asia/Kolkata)` and breaks the end-anchored `IANA_TIMEZONE_PATTERN`; stop collecting once the reset line has been included (or otherwise preserve the timezone suffix) before calling `parseClaudeUsageWindowSegment`.

Comment thread docs/user/usage.md
Comment on lines +15 to +18
On web and desktop, **Settings → General → Show usage in chat** puts the current thread's provider
limits in the context-window hover next to the chat box. The bars stay hidden until that setting is
on and the thread has sent its first message, and they only show the provider selected for that
thread.

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.

🟢 Low user/usage.md:15

The documentation directs users to a context-window hover that does not exist for models/providers without a context-window ring, while omitting the ComposerUsageMeter shown next to Send; those users cannot find the provider limits described here. Document the ComposerUsageMeter fallback for that case.

Suggested change
On web and desktop, **Settings → General → Show usage in chat** puts the current thread's provider
limits in the context-window hover next to the chat box. The bars stay hidden until that setting is
on and the thread has sent its first message, and they only show the provider selected for that
thread.
On web and desktop, **Settings → General → Show usage in chat** puts the current thread's provider
limits in the context-window hover next to the chat box when a context-window ring is available.
For models/providers without a context-window ring, the `ComposerUsageMeter` appears next to
**Send** instead. The bars stay hidden until that setting is on and the thread has sent its first
message, and they only show the provider selected for that thread.
🤖 Copy this AI Prompt to have your agent fix this:
In file @docs/user/usage.md around lines 15-18:

The documentation directs users to a context-window hover that does not exist for models/providers without a context-window ring, while omitting the `ComposerUsageMeter` shown next to `Send`; those users cannot find the provider limits described here. Document the `ComposerUsageMeter` fallback for that case.

}

function shouldShowProviderQuota(provider: ServerProvider): boolean {
if (provider.driver === "opencode") return 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.

🟡 Medium usage/UsageRouteScreen.tsx:519

shouldShowProviderQuota hides every provider with driver === "opencode", so mobile users connected through OpenCode Go/Zen never see quota data even when the server snapshot has available opencodeManaged limits. Remove this unconditional exclusion so those providers pass the existing visibility checks.

-  if (provider.driver === "opencode") return false;
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/mobile/src/features/usage/UsageRouteScreen.tsx around line 519:

`shouldShowProviderQuota` hides every provider with `driver === "opencode"`, so mobile users connected through OpenCode Go/Zen never see quota data even when the server snapshot has available `opencodeManaged` limits. Remove this unconditional exclusion so those providers pass the existing visibility checks.

// Reuse the probe's window resolution so a rolling notification and a full
// `account/rateLimits/read` produce identical windows, then project back to
// raw inputs for the shared normalizer.
const resolved = resolveCodexRateLimitSnapshotUsageLimits({

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.

🟡 Medium provider/runtimeUsageLimits.ts:145

A sparse Codex update containing only a duration-less primary window is resolved as Weekly, so applyUsageLimits upserts it over the existing weekly bar and leaves the session bar stale for older two-window accounts. Passing the partial snapshot directly to resolveCodexRateLimitSnapshotUsageLimits triggers its lone-window fallback; preserve the window's positional identity or merge the update with the existing snapshot before resolving it.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/runtimeUsageLimits.ts around line 145:

A sparse Codex update containing only a duration-less `primary` window is resolved as `Weekly`, so `applyUsageLimits` upserts it over the existing weekly bar and leaves the session bar stale for older two-window accounts. Passing the partial snapshot directly to `resolveCodexRateLimitSnapshotUsageLimits` triggers its lone-window fallback; preserve the window's positional identity or merge the update with the existing snapshot before resolving it.

source: published.source,
available: true,
checkedAt: published.checkedAt,
windows: mergeUsageLimitWindows(probed.windows, livePatchedWindows),

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.

🟡 Medium provider/providerUsageLimits.ts:200

A concurrent runtime update can overwrite the probe's current resetsAt and windowDurationMins with stale values, so the published quota bar shows an obsolete reset time and duration. applyRuntimeUsageLimits has already filled those omitted fields into the live patch, and mergeUsageLimitWindows(probed.windows, livePatchedWindows) gives the patch precedence as if they were freshly reported. Preserve the probe's metadata while applying the live percentage-only update, or retain which fields were actually present in the runtime event.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/providerUsageLimits.ts around line 200:

A concurrent runtime update can overwrite the probe's current `resetsAt` and `windowDurationMins` with stale values, so the published quota bar shows an obsolete reset time and duration. `applyRuntimeUsageLimits` has already filled those omitted fields into the live patch, and `mergeUsageLimitWindows(probed.windows, livePatchedWindows)` gives the patch precedence as if they were freshly reported. Preserve the probe's metadata while applying the live percentage-only update, or retain which fields were actually present in the runtime event.

// "no usage". A hung `account/rateLimits/read` must not consume the outer
// 10s probe budget and discard account/models/skills already fetched.
// Rethrow interrupts so a cancelled probe cannot finish as success.
const rateLimitsResponse = yield* client.request("account/rateLimits/read", undefined).pipe(

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.

🟠 High Layers/CodexProvider.ts:411

A slow but successful provider probe now returns a timeout error when skills/list and paginated model/list consume most of the 10-second deadline: the sequential account/rateLimits/read call can wait another 3 seconds and trigger the outer timeout, discarding the fetched account, models, and skills. Start the optional rate-limit request concurrently with the other requests or bound it by the remaining probe deadline.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/CodexProvider.ts around line 411:

A slow but successful provider probe now returns a timeout error when `skills/list` and paginated `model/list` consume most of the 10-second deadline: the sequential `account/rateLimits/read` call can wait another 3 seconds and trigger the outer timeout, discarding the fetched account, models, and skills. Start the optional rate-limit request concurrently with the other requests or bound it by the remaining probe deadline.

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

Copy link
Copy Markdown

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: 3168a0c74c

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +411 to +414
const rateLimitsResponse = yield* client.request("account/rateLimits/read", undefined).pipe(
Effect.timeoutOption(Duration.millis(RATE_LIMITS_PROBE_TIMEOUT_MS)),
Effect.catchCause((cause) =>
Cause.hasInterrupts(cause) ? Effect.failCause(cause) : Effect.succeed(Option.none()),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep quota reading outside Codex's 10-second status deadline

When the existing account/models/skills requests consume most of AUTH_PROBE_TIMEOUT_MS, this new sequential request can still be pending when the outer timeout fires. That interrupt is deliberately rethrown here, so checkCodexProviderStatus returns its full error snapshot instead of retaining a healthy Codex status with usage omitted; this occurs for otherwise working accounts whenever account/rateLimits/read cannot finish in the remaining probe budget.

Useful? React with 👍 / 👎.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e464240. Configure here.

? window.windowDurationMins
: reported.length > 1 && index === 0
? CODEX_SESSION_WINDOW_DURATION_MINS
: CODEX_WEEKLY_WINDOW_DURATION_MINS;

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.

Sparse Codex updates mislabel session

Medium Severity

Live Codex account.rate-limits.updated payloads are run through resolveCodexRateLimitSnapshotUsageLimits, which treats a lone duration-less primary window as weekly. That heuristic is correct for a full snapshot after Codex dropped the session cap, but runtime notifications are documented as sparse. A primary-only event then upserts the weekly bar (via kind-keyed merge) with session utilization, so the chat meter and Usage page show the wrong window during a turn.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e464240. Configure here.

@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This is a cross-platform feature rather than a small UI tweak: it adds provider-specific subprocess/ACP probes, live snapshot ingestion, shared PTY lifecycle changes, new schema fields, and web/mobile surfaces. These changes alter routine provider refreshes and carry unresolved timeout, quota-merging, timezone, and platform-process risks that require human review.

Not approved because:

  • 7 blocking correctness issues found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant