Skip to content

Add per-provider accent color override - #2972

Merged
steipete merged 1 commit into
steipete:mainfrom
urda:feat/provider-accent-colors
Aug 16, 2026
Merged

Add per-provider accent color override#2972
steipete merged 1 commit into
steipete:mainfrom
urda:feat/provider-accent-colors

Conversation

@urda

@urda urda commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Each provider settings card gets an Accent color row. The row shows a swatch, a hex
field, and a color well. A Reset button appears only when an override exists.

Provider descriptors keep the shipped color as a compile-time constant. This feature
never writes over that constant, so a reset always restores the original color.

What changes

The override applies to every surface that paints the provider brand color:

  • Usage bars in the menu and the inline dashboard.
  • Cost history and plan utilization charts.
  • The provider switcher tab indicator.
  • The widget.
  • The codexbar serve web dashboard.

Out of scope: burnDownWidgetColor, confettiPalette, and all bar styling other than
color.

Storage

ProviderConfig.accentColor holds the value as #RRGGBB in ~/.codexbar/config.json.
That file reaches the app and the codexbar serve dashboard directly.

The widget runs in a sandbox and cannot read that file. The app therefore mirrors the
resolved map into the App Group defaults, and reloads widget timelines when a color
moves.

Overrides travel between Macs through ProviderIntentPayload, with the same semantics
as the other fields in that payload.

Implementation notes

  • A hex value that does not parse degrades to the shipped color. A hand-edited config
    file cannot break the load.
  • The color well can return a wide-gamut color. The view pins the value to sRGB before
    it stores the hex.
  • An accent change uses affectsBackgroundWork: false. Open menus and status items
    rebuild, but no provider refresh occurs.
  • updateQuotaIndicators() now refreshes the indicator color outside the ratio guard.
    The switcher view outlives a menu update, so a new color must not wait for usage to
    move.

Commands run

  • swift build
  • swift test --filter ProviderAccentColorTests (12 tests, all pass)
  • make check
  • make test

Screenshots

The row on a provider card, with no override. The hex field shows the shipped color.

accent-color-row-default

The same row with an override. Reset appears only in this state.

accent-color-row-override

Usage bars in the shipped color and in the override.

accent-color-bars-before-after

These are rendered components, not captures of the running Settings window.
ProviderAccentColorScreenshotRenderTests produces them, and it is skipped by default:

CODEXBAR_ACCENT_SCREENSHOT_DIR=~/Downloads swift test --filter ProviderAccentColorScreenshotRenderTests

Notes for review

The 22 non-English catalogs carry machine-generated translations. They pass the token
and coverage checks, but a native speaker should review the wording.

ProviderArchitectureGatekeeperTests pins one allowlist entry by line number. This
branch adds lines to SettingsStore.swift, so that entry moves from 1048 to 1058. Only
the line number changes.

@clawsweeper

clawsweeper Bot commented Aug 16, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@urda

urda commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

@steipete this should let you make edits going forward now.

@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: 6be3c4d328

ℹ️ 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".

Comment thread Sources/CodexBarCore/Config/CodexBarConfig.swift
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. P2 Normal priority bug or improvement with limited blast radius. 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 Aug 16, 2026
@clawsweeper

clawsweeper Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 16, 2026, 4:17 AM ET / 08:17 UTC.

ClawSweeper review

What this changes

Adds a per-provider accent-color override stored in configuration and applied across native usage views, widgets, sync, and the served dashboard.

Merge readiness

Blocked until stronger real behavior proof is added - 5 items remain

Keep open. Current main still uses fixed provider branding colors, while this PR adds a new persisted and synced setting; VISION.md requires sign-off for that feature and the supplied screenshots are not live runtime proof.

Priority: P2
Reviewed head: 099bf56f71fcae8b56e66984817d3608cc0a1811
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The patch appears coherent and resolves the prior source finding, but the real-behavior proof gate remains unmet.
Proof confidence 🦪 silver shellfish (2/6) Needs stronger real behavior proof before merge: The PR describes its images as isolated component renders, not after-fix behavior in the running app; provide redacted live evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Needs proof Needs stronger real behavior proof before merge: The PR describes its images as isolated component renders, not after-fix behavior in the running app; provide redacted live evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 5 items Current main lacks overrides: Current menu switcher and cost-history rendering obtain color directly from immutable provider branding, so the requested user setting is not already implemented.
Prior finding resolved: The current PR head observes configuration revisions and refreshes the editor unless a user is actively editing, addressing the previous external-update finding.
Sync ownership history: The existing opt-in iCloud sync feature introduced provider configuration synchronization and the config watcher, making it the relevant compatibility boundary.
Findings None None.
Security None None.

How this fits together

CodexBar reads provider configuration to render status in the menu bar, settings, widgets, and web dashboard. This feature adds a cosmetic setting that flows from local config through sync and display-specific color resolution.

flowchart LR
  A[Provider settings] --> B[Local configuration]
  B --> C[Accent color resolver]
  C --> D[Menu and charts]
  C --> E[Widget shared defaults]
  B --> F[Cross-device sync]
  B --> G[Web dashboard]
Loading

Decision needed

Question Recommendation
Should CodexBar support a persistent, cross-device per-provider visual customization setting? Sponsor the setting: Approve the persistent synced override after live proof demonstrates save, reset, and consumer propagation.

Why: VISION.md requires sign-off for new features and data-storage behavior; the code review cannot determine whether this extra long-term settings surface is desired.

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The PR describes its images as isolated component renders, not after-fix behavior in the running app; provide redacted live evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Resolve merge risk (P1) - A persisted provider field synchronized between Macs needs explicit owner approval and live upgrade/runtime verification before it becomes a supported setting.
  • Resolve merge risk (P1) - The presented screenshots do not prove save, reset, widget mirroring, or dashboard propagation in a running bundle.
  • Complete next step (P2) - A maintainer must decide whether this new stored, synced customization belongs in the product; contributor runtime proof is also still required.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Changed surface 47 files, +806 / -13 lines The feature crosses configuration, synchronization, native UI, widget, dashboard, tests, and 23 localization/release files.

Merge-risk options

Maintainer options:

  1. Require live proof and feature sign-off (recommended)
    Before merge, obtain owner approval plus redacted running-app proof of persistence, reset, and one downstream display surface.
  2. Pause the new setting
    Do not merge if maintainers prefer provider branding to remain a fixed descriptor-owned value.

Technical review

Best possible solution:

Ship the setting only after owner sign-off and redacted live evidence of changing and resetting a color, including at least one affected consumer surface.

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

Not applicable: this PR proposes a feature, not a reported defect; live validation is still needed for its stated behavior.

Is this the best way to solve the issue?

Unclear: the implementation follows existing configuration and sync patterns, but VISION.md requires maintainer sign-off before accepting this new persistent setting.

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P2: This is a bounded user-facing customization with no demonstrated urgent regression.
  • merge-risk: 🚨 compatibility: The PR introduces a persisted provider field and cross-device synchronization behavior for existing installations.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR describes its images as isolated component renders, not after-fix behavior in the running app; provide redacted live evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR describes its images as isolated component renders, not after-fix behavior in the running app; provide redacted live evidence before merge.

Evidence

What I checked:

Likely related people:

  • steipete: Introduced the current iCloud sync, configuration-watcher, and provider-intent infrastructure used by this change. (role: introduced sync boundary; confidence: high; commits: 01b6dad78274; files: Sources/CodexBarCore/Sync/SyncModels.swift, Sources/CodexBar/SettingsStore+ConfigPersistence.swift)
  • dylanstieri: Recently changed provider settings, localized catalogs, SettingsStore observation, and sync-model coverage on the same user-settings surface. (role: recent adjacent contributor; confidence: medium; commits: a55b92ec3082; files: Sources/CodexBar/PreferencesProviderDetailView.swift, Sources/CodexBarCore/Sync/SyncModels.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Add redacted running-app proof of a saved color and reset, including a menu, widget, or dashboard consumer.
  • Obtain maintainer sign-off for the new persistent synced setting.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (4 earlier review cycles)
  • reviewed 2026-08-16T06:52:11.147Z sha 6be3c4d :: needs real behavior proof before merge. :: [P1] Version the sync payload before adding accent overrides | [P2] Exclude the accent from provider refresh revisions
  • reviewed 2026-08-16T06:59:53.260Z sha 8a09453 :: needs real behavior proof before merge. :: [P1] Version and preserve legacy sync payloads | [P2] Keep accent updates out of refresh generations
  • reviewed 2026-08-16T07:04:41.419Z sha 8a09453 :: needs real behavior proof before merge. :: [P1] Version the sync payload before adding accent overrides | [P2] Exclude accent color from provider refresh revisions
  • reviewed 2026-08-16T07:37:54.717Z sha 7445026 :: needs real behavior proof before merge. :: [P2] Sync the editor with external accent updates

@urda
urda force-pushed the feat/provider-accent-colors branch from 6be3c4d to 8a09453 Compare August 16, 2026 06:55
@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. and removed merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Aug 16, 2026
@urda
urda force-pushed the feat/provider-accent-colors branch 2 times, most recently from 62c1ac7 to 7445026 Compare August 16, 2026 07:35
@urda

urda commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author
image

@steipete should def be setup correct now.

Every provider settings card gets an accent color row: swatch, hex field, color well,
and a reset shown only when an override exists. Descriptor colors stay compile-time constants,
so a reset restores the shipped color.

Overrides persist as ProviderConfig.accentColor in ~/.codexbar/config.json,
which reaches the app and the codexbar serve dashboard, and mirror
into App Group defaults for the widget, which cannot read that file.
Overrides sync across Macs via ProviderIntentPayload.

Translations for the 22 non-English catalogs are machine-generated and want a native-speaker pass.
@urda
urda force-pushed the feat/provider-accent-colors branch from 7445026 to 099bf56 Compare August 16, 2026 08:12
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Aug 16, 2026
@steipete
steipete merged commit 20aee7c into steipete:main Aug 16, 2026
9 checks passed
@urda
urda deleted the feat/provider-accent-colors branch August 16, 2026 08:40
Finesssee added a commit to nesszer/Win-CodexBar that referenced this pull request Aug 18, 2026
… per-provider accent color

Item 1 — Mistral PAYG current-month API spend (steipete#2821, steipete#2947):
- Add MonthlyPlan variant to MetricPreference enum
- Add currency_symbol field to CostSnapshot with with_currency_symbol builder
- Set currency_symbol from Mistral billing API response
- Add MonthlyPlan to bridge label/parse, tray selected_metric_percent (None = no bar)
- Show formatted cost amount in provider_status_label for MonthlyPlan
- Add format_cost_amount helper in bridge.rs
- Add Mistral monthly spend row in MenuCardDetails
- Add monthlyPlan option to MenuBarMetricSection for Mistral

Item 2 — Menu cost-summary display style per provider (steipete#2976):
- Add CostSummaryDisplayStyle enum (Compact/Detailed/Hidden) in types.rs
- Add cost_summary_display_style field to Settings + Default + RawSettings round-trip
- Add to SettingsSnapshot bridge + SettingsUpdate + apply in Tauri commands
- Add bridge label/parse functions
- Apply in MenuCardDetails: hidden hides cost section, compact shows used/limit only
- Update describeCard to filter hasCost for hidden style
- Add Select control in UsageSpendTab

Item 3 — Per-provider accent color override (steipete#2972):
- Add accent_color field to ProviderConfig
- Add brand_color(ProviderId) function in provider.rs (mirrors frontend registry)
- Add accent_color/set_accent_color/effective_accent_color accessors in Settings
- Add set/get/get_effective Tauri commands + normalize_hex_accent_color validator
- Add providerAccentColors map to SettingsSnapshot bridge
- Add setProviderAccentColor/getProviderAccentColor/getProviderEffectiveAccentColor to tauri.ts
- Create AccentColorSection component (hex input, color picker, reset button)
- Inject --provider-accent CSS variable on MenuCard article and ChartsSection
- Update menu-metric__bar-fill and chart colors to use --provider-accent fallback
- Update chartPalette providerCostColor/providerCreditsColor fallback chain
- Pass providerAccentColors through TrayPanel/PopOutPanel/ProvidersTab/ProviderDetailPane

Also:
- Add 11 new locale keys to all 7 .ftl files + keys.ts
- Add costSummaryDisplayStyle + providerAccentColors to all test mock SettingsSnapshot
- Update chartPalette tests for --provider-accent fallback
Finesssee added a commit to nesszer/Win-CodexBar that referenced this pull request Aug 18, 2026
… per-provider accent color

Item 1 — Mistral PAYG current-month API spend (steipete#2821, steipete#2947):
- Add MonthlyPlan variant to MetricPreference enum
- Add currency_symbol field to CostSnapshot with with_currency_symbol builder
- Set currency_symbol from Mistral billing API response
- Add MonthlyPlan to bridge label/parse, tray selected_metric_percent (None = no bar)
- Show formatted cost amount in provider_status_label for MonthlyPlan
- Add format_cost_amount helper in bridge.rs
- Add Mistral monthly spend row in MenuCardDetails
- Add monthlyPlan option to MenuBarMetricSection for Mistral

Item 2 — Menu cost-summary display style per provider (steipete#2976):
- Add CostSummaryDisplayStyle enum (Compact/Detailed/Hidden) in types.rs
- Add cost_summary_display_style field to Settings + Default + RawSettings round-trip
- Add to SettingsSnapshot bridge + SettingsUpdate + apply in Tauri commands
- Add bridge label/parse functions
- Apply in MenuCardDetails: hidden hides cost section, compact shows used/limit only
- Update describeCard to filter hasCost for hidden style
- Add Select control in UsageSpendTab

Item 3 — Per-provider accent color override (steipete#2972):
- Add accent_color field to ProviderConfig
- Add brand_color(ProviderId) function in provider.rs (mirrors frontend registry)
- Add accent_color/set_accent_color/effective_accent_color accessors in Settings
- Add set/get/get_effective Tauri commands + normalize_hex_accent_color validator
- Add providerAccentColors map to SettingsSnapshot bridge
- Add setProviderAccentColor/getProviderAccentColor/getProviderEffectiveAccentColor to tauri.ts
- Create AccentColorSection component (hex input, color picker, reset button)
- Inject --provider-accent CSS variable on MenuCard article and ChartsSection
- Update menu-metric__bar-fill and chart colors to use --provider-accent fallback
- Update chartPalette providerCostColor/providerCreditsColor fallback chain
- Pass providerAccentColors through TrayPanel/PopOutPanel/ProvidersTab/ProviderDetailPane

Also:
- Add 11 new locale keys to all 7 .ftl files + keys.ts
- Add costSummaryDisplayStyle + providerAccentColors to all test mock SettingsSnapshot
- Update chartPalette tests for --provider-accent fallback
Finesssee added a commit to nesszer/Win-CodexBar that referenced this pull request Aug 18, 2026
* Port upstream 0.50.1: Cursor rename + Ollama cookie stripping (steipete#2951, steipete#2949)

* Port upstream 0.50.1: OpenCode Go session+weekly pace in CLI (steipete#2957)

* Port upstream 0.50.1: chart axis label centering (steipete#2974)

* Port upstream 0.50.1: Kiro re-authenticate via kiro-cli login (steipete#2340)

* Port upstream 0.50.1: serve identity follows app redaction per-request (steipete#2960)

* Port upstream 0.50.1: Codex routed pricing, auth.json read-only, known-zero history, Antigravity dashboard lanes, Claude OAuth revoked detection

steipete#2946 Codex routed models pricing — codex_routed_provider() + strip_route_prefix()
    in cost_pricing.rs; deepseek/, kimi/, opencode/ routes price against
    matching models.dev provider; unknown provider/ prefixes return None.
steipete#2944 Codex auth.json read-only during refresh — codex_external_oauth_sources_allowed
    setting (default OFF); is_external_oauth + last_refresh fields on
    CodexCredentials; enforce_external_oauth_gate (8-day staleness window).
steipete#2932 Codex known-zero history — known_zero field on CostSummary; set in both
    cache-debounce and full-scan paths (history_coverage_established &&
    sessions_count == 0); knownZero JSON field + CLI text update.
steipete#2963 Antigravity dashboard lanes — quota-bucket dedup in parse_user_status;
    models sharing the same (remaining_fraction, reset_time) collapse to one
    lane.
steipete#2516 Claude revoked vs missing OAuth — ProviderError::OAuthRevoked variant;
    revocation detection (401/403 with revoked/invalid_grant/token_revoked);
    15-min CLI result cache (LazyLock<Mutex<Option<CachedCliResult>>>);
    fetch_via_auto returns cached CLI result when OAuth revoked, and stale
    cache when all live sources fail.

* Port upstream 0.50.1: Mistral PAYG spend, cost-summary display style, per-provider accent color

Item 1 — Mistral PAYG current-month API spend (steipete#2821, steipete#2947):
- Add MonthlyPlan variant to MetricPreference enum
- Add currency_symbol field to CostSnapshot with with_currency_symbol builder
- Set currency_symbol from Mistral billing API response
- Add MonthlyPlan to bridge label/parse, tray selected_metric_percent (None = no bar)
- Show formatted cost amount in provider_status_label for MonthlyPlan
- Add format_cost_amount helper in bridge.rs
- Add Mistral monthly spend row in MenuCardDetails
- Add monthlyPlan option to MenuBarMetricSection for Mistral

Item 2 — Menu cost-summary display style per provider (steipete#2976):
- Add CostSummaryDisplayStyle enum (Compact/Detailed/Hidden) in types.rs
- Add cost_summary_display_style field to Settings + Default + RawSettings round-trip
- Add to SettingsSnapshot bridge + SettingsUpdate + apply in Tauri commands
- Add bridge label/parse functions
- Apply in MenuCardDetails: hidden hides cost section, compact shows used/limit only
- Update describeCard to filter hasCost for hidden style
- Add Select control in UsageSpendTab

Item 3 — Per-provider accent color override (steipete#2972):
- Add accent_color field to ProviderConfig
- Add brand_color(ProviderId) function in provider.rs (mirrors frontend registry)
- Add accent_color/set_accent_color/effective_accent_color accessors in Settings
- Add set/get/get_effective Tauri commands + normalize_hex_accent_color validator
- Add providerAccentColors map to SettingsSnapshot bridge
- Add setProviderAccentColor/getProviderAccentColor/getProviderEffectiveAccentColor to tauri.ts
- Create AccentColorSection component (hex input, color picker, reset button)
- Inject --provider-accent CSS variable on MenuCard article and ChartsSection
- Update menu-metric__bar-fill and chart colors to use --provider-accent fallback
- Update chartPalette providerCostColor/providerCreditsColor fallback chain
- Pass providerAccentColors through TrayPanel/PopOutPanel/ProvidersTab/ProviderDetailPane

Also:
- Add 11 new locale keys to all 7 .ftl files + keys.ts
- Add costSummaryDisplayStyle + providerAccentColors to all test mock SettingsSnapshot
- Update chartPalette tests for --provider-accent fallback

* Resolve merge conflicts and fix gate checks

* Thermo-nuclear: extract ollama cookies, codex pricing, simplify accent color

* fix: correct serde attribute placement on currency_symbol after rebase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants