Skip to content

fix(bricks): emit brand base token in CSS export + color overrides; de-dupe font collector - #230

Merged
jackgranatowski merged 3 commits into
mainfrom
audit/wp-plugin-cleanup
Jun 5, 2026
Merged

fix(bricks): emit brand base token in CSS export + color overrides; de-dupe font collector#230
jackgranatowski merged 3 commits into
mainfrom
audit/wp-plugin-cleanup

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

This pull request was created by @kiro-agent on behalf of @jackgranatowski 👻

Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro Web


WP plugin code audit — fixes

Focused re-audit of plugins/SLASHED-for-WP. Most prior High/Medium audit items were already resolved (CSS-generator allowlist validation, slashed.php cleanup + cron moved to the global layer, color defaults consolidated through Slashed_Token_Defaults). This PR fixes the two genuine bugs that remained, plus one duplication.

1. surfacebase regression (functional bug)

The framework's only source brand token is --sf-color-base-light; --sf-color-surface is a derived semantic alias (= var(--sf-color-base)) with no -light/-dark source. Commit 62b7337 partially reverted a base → surface rename but missed two spots that read the non-existent brand_surface key and emitted a phantom --sf-color-surface-light, silently dropping the user's brand_base override:

  • admin-app/src/lib/export.js — client-side "Export CSS" (bundle rebuilt)
  • includes/class-inventory.php get_admin_color_overrides() — wrong editor color-swatch preview; its own docblock says it mirrors the CSS generator, which uses base

Cross-checked against the source of truth (class-token-defaults.php, class-css-generator.php, ColorTab.svelte, color-model.js, LivePreview.svelte, and tests/color-model.test.js).

2. Bricks font collector de-duplicated (maintainability)

Slashed_Token_Page::get_bricks_fonts() and Slashed_Bricks_Fonts_REST::get_fonts() were ~110-line near-verbatim copies (shared slashed_bricks_cpt_fonts transient) that had started to drift. The collector now lives once in Slashed_Token_Page::get_bricks_fonts() (the always-loaded canonical owner, in both unified and standalone modes); the REST endpoint is a thin wrapper. Shared transient key is now a single constant Slashed_Token_Page::CPT_FONTS_TRANSIENT. No behavioural change.

Changed files

  • integrations/bricks/admin-app/src/lib/export.js (+ rebuilt assets/admin-app/app.js, 1-line bundle diff)
  • integrations/bricks/includes/class-inventory.php
  • includes/class-token-page.php (canonical font collector + shared transient constant)
  • integrations/bricks/includes/class-fonts-rest.php (now a thin wrapper)
  • CODE-AUDIT.md (documents this pass + remaining open items)

Testing

  • php -l clean on all changed PHP files
  • node --test64/64 pass
  • admin SPA rebuilds cleanly via Vite; verified the built app.js now emits ...neutral","base and no longer ...neutral","surface

Known limitations / left for follow-up

  • editor-app/src/lib/apply.js migrate path still reads a pre-batch globalClasses snapshot for the two-siblings-into-one-new-class edge case. It lives in the compiled editor bundle and needs a live Bricks editor to verify safely, so it was intentionally left unchanged here.
  • class-css-parser.php [^}]* regex is brittle on a } inside an @property initial-value (non-fatal: cached, editor-only).

Summary by CodeRabbit

  • Bug Fixes

    • Fixed color token sourcing for brand colors in CSS exports
    • Corrected admin color swatch preview rendering
    • Improved export CSS loop handling for light brand colors
  • Documentation

    • Updated code audit documentation with verification of prior fixes
  • Refactor

    • Consolidated Bricks font collection architecture for improved maintainability

Two spots missed by the partial base->surface rename revert (62b7337) still
read the non-existent `brand_surface` key and emitted a phantom
`--sf-color-surface-light`, silently dropping a user's `brand_base` override:

- admin-app export.js (client-side "Export CSS") — rebuilt the bundle
- class-inventory.php get_admin_color_overrides() — wrong editor swatch preview
  (its own docblock says it mirrors the CSS generator, which uses `base`)

Also de-duplicate the ~110-line Bricks font collector: the canonical
implementation now lives once in Slashed_Token_Page::get_bricks_fonts() and the
REST endpoint is a thin wrapper; the shared transient key is a single constant.
No behavioural change.

php -l clean; node --test 64/64; admin SPA rebuilds cleanly.

Co-authored-by: Jack Granatowski <contact@codeslash.net>
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jackgranatowski, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 4 minutes and 9 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1771b705-996f-4bd3-9474-224098e91042

📥 Commits

Reviewing files that changed from the base of the PR and between 6c49e17 and 2cd4947.

📒 Files selected for processing (9)
  • CODE-AUDIT.md
  • plugins/SLASHED-for-WP/includes/class-token-page.php
  • plugins/SLASHED-for-WP/integrations/bricks/assets/editor-app/app.js
  • plugins/SLASHED-for-WP/integrations/bricks/editor-app/src/components/ColorApp.svelte
  • plugins/SLASHED-for-WP/integrations/bricks/editor-app/src/components/ColorPanel.svelte
  • plugins/SLASHED-for-WP/integrations/bricks/editor-app/src/lib/color-swatches.js
  • plugins/SLASHED-for-WP/integrations/bricks/includes/class-fonts-rest.php
  • plugins/SLASHED-for-WP/integrations/bricks/includes/class-inventory.php
  • plugins/SLASHED-for-WP/integrations/bricks/slashed-bricks.php
📝 Walkthrough

Walkthrough

This PR consolidates Bricks font collection into a shared transient-cached method in Slashed_Token_Page, reducing code duplication and providing a single source of truth for font enumeration. It also corrects brand color token references from surface back to base across color generation and override paths, resolving earlier regressions noted in the audit.

Changes

Re-audit: Font collection and color token fixes

Layer / File(s) Summary
Font collection consolidation with transient caching
plugins/SLASHED-for-WP/includes/class-token-page.php, plugins/SLASHED-for-WP/integrations/bricks/includes/class-fonts-rest.php
CPT_FONTS_TRANSIENT constant is added and used by get_bricks_fonts() for transient-based caching of CPT font enumeration. Cache busting is updated to use the constant. The REST get_fonts() endpoint is refactored from a full enumeration/deduplication implementation into a thin wrapper that delegates to Slashed_Token_Page::get_bricks_fonts(), removing 119 net lines of duplication.
Brand color token corrections (surface → base)
plugins/SLASHED-for-WP/integrations/bricks/admin-app/src/lib/export.js, plugins/SLASHED-for-WP/integrations/bricks/includes/class-inventory.php
generateColorDeclarations() updates the light brand color family list to use base instead of surface, with a comment clarifying that surface is a derived token. get_admin_color_overrides() includes base in the brand color set for override mapping.
Audit documentation and minor cleanup
CODE-AUDIT.md, plugins/SLASHED-for-WP/integrations/bricks/assets/admin-app/app.js
Re-audit pass documentation details two straggler surface→base fixes, the font collector consolidation, and lists of items verified as already resolved; minor help text formatting adjustment in settings UI.

Sequence Diagram

sequenceDiagram
  participant REST as Bricks REST Handler
  participant Collector as Slashed_Token_Page
  participant Cache as Transient Cache
  REST->>Collector: get_bricks_fonts()
  Collector->>Cache: get_transient(CPT_FONTS_TRANSIENT)
  Cache-->>Collector: cached CPT fonts or null
  Collector->>Collector: enumerate CPT posts & deduplicate
  Collector->>Cache: set_transient(CPT_FONTS_TRANSIENT)
  Collector-->>REST: merged font list
  REST-->>REST: return fonts payload
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • codeslash-dev/SLASHED#202: Earlier PR that swapped brand token handling from base to surface; this PR reverts that change back to base in the same functions.
  • codeslash-dev/SLASHED#171: Related refactoring of Bricks fonts REST handler and CPT font collection logic.
  • codeslash-dev/SLASHED#151: Prior modifications to generateColorDeclarations() in the Bricks CSS emission path.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures both main changes: the surface→base token regression fix and the font collector de-duplication, using specific technical terms that clearly convey the changeset's primary objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch audit/wp-plugin-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/SLASHED-for-WP/integrations/bricks/includes/class-fonts-rest.php (1)

45-48: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Register CPT cache invalidation outside REST route registration.

save_post_{BRICKS_DB_CUSTOM_FONTS} is currently attached inside register_routes(), which runs via rest_api_init. On requests where REST isn’t initialized, the invalidation hook won’t be bound, so font cache can remain stale until TTL expiry. Move this hook registration to an always-loaded bootstrap path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/SLASHED-for-WP/integrations/bricks/includes/class-fonts-rest.php`
around lines 45 - 48, The save_post_{BRICKS_DB_CUSTOM_FONTS} hook is being
registered inside register_routes() (called via rest_api_init) so it won't be
bound on non-REST requests; move the add_action( 'save_post_' .
BRICKS_DB_CUSTOM_FONTS, array( $this, 'bust_cpt_cache' ) ) registration out of
register_routes() into an always-run bootstrap location (for example the class
constructor or an init hook that runs on every request) so bust_cpt_cache() is
always attached and CPT font cache invalidation runs regardless of REST
initialization.
🧹 Nitpick comments (1)
plugins/SLASHED-for-WP/integrations/bricks/includes/class-inventory.php (1)

241-241: ⚡ Quick win

Consider adding an inline comment explaining the base inclusion and surface exclusion.

The corresponding change in export.js includes a helpful comment clarifying that surface is a derived token without a -light source. Adding a similar note here would prevent future confusion and align the documentation quality across the client and server implementations.

📝 Suggested inline comment
 
-	$brand_colors  = array( 'primary', 'secondary', 'tertiary', 'action', 'neutral', 'base' );
+	// Brand families: 'base' is the source token (--sf-color-base-light);
+	// 'surface' is derived with no -light source, so it's excluded.
+	$brand_colors  = array( 'primary', 'secondary', 'tertiary', 'action', 'neutral', 'base' );
 	$status_colors = array( 'success', 'warning', 'error', 'info', 'danger' );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/SLASHED-for-WP/integrations/bricks/includes/class-inventory.php` at
line 241, Add an inline comment above the $brand_colors = array( 'primary',
'secondary', 'tertiary', 'action', 'neutral', 'base' ); declaration in
class-inventory.php that explains why 'base' is included and why 'surface' is
intentionally excluded (e.g., note that 'surface' is a derived token without a
-light source and thus not exported/handled here), mirroring the explanatory
note in export.js to prevent future confusion when reading the $brand_colors
list.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@plugins/SLASHED-for-WP/integrations/bricks/includes/class-fonts-rest.php`:
- Around line 45-48: The save_post_{BRICKS_DB_CUSTOM_FONTS} hook is being
registered inside register_routes() (called via rest_api_init) so it won't be
bound on non-REST requests; move the add_action( 'save_post_' .
BRICKS_DB_CUSTOM_FONTS, array( $this, 'bust_cpt_cache' ) ) registration out of
register_routes() into an always-run bootstrap location (for example the class
constructor or an init hook that runs on every request) so bust_cpt_cache() is
always attached and CPT font cache invalidation runs regardless of REST
initialization.

---

Nitpick comments:
In `@plugins/SLASHED-for-WP/integrations/bricks/includes/class-inventory.php`:
- Line 241: Add an inline comment above the $brand_colors = array( 'primary',
'secondary', 'tertiary', 'action', 'neutral', 'base' ); declaration in
class-inventory.php that explains why 'base' is included and why 'surface' is
intentionally excluded (e.g., note that 'surface' is a derived token without a
-light source and thus not exported/handled here), mirroring the explanatory
note in export.js to prevent future confusion when reading the $brand_colors
list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a7b8698-099c-4986-883c-042f878adde6

📥 Commits

Reviewing files that changed from the base of the PR and between dc3bc47 and 6c49e17.

📒 Files selected for processing (6)
  • CODE-AUDIT.md
  • plugins/SLASHED-for-WP/includes/class-token-page.php
  • plugins/SLASHED-for-WP/integrations/bricks/admin-app/src/lib/export.js
  • plugins/SLASHED-for-WP/integrations/bricks/assets/admin-app/app.js
  • plugins/SLASHED-for-WP/integrations/bricks/includes/class-fonts-rest.php
  • plugins/SLASHED-for-WP/integrations/bricks/includes/class-inventory.php

Behaviour-preserving cleanups found during a full read of editor-app
(~5.4k lines — no functional bugs found, only these nits):

- ColorPanel: remove dead `referenceMode` prop (mode is derived from
  `onPickValue`); drop the matching arg in ColorApp.
- ColorPanel: collapse the ~90-line Brand/Status palette duplication into
  one `{#snippet familyScanner}` rendered twice. app.css is byte-identical,
  confirming a pure structural refactor. Bundle rebuilt.
- color-swatches.js: collapse redundant else-if/else (both appendChild).
- slashed-bricks.php: extract the parser/resolver/inventory require_once
  trio shared by both bootstrap paths into slashed_bricks_require_data_classes().

Also expand CODE-AUDIT.md: document these fixes, the verified-already-resolved
items, and a "Remaining — needs a decision" list (triplicated DIST_SHA,
duplicated standalone bootstrap, apply.js migrate edge case, css-parser regex,
migrate-keys dual naming) — each intentional or needing a live-Bricks decision.

php -l clean; node --test 64/64; editor-app rebuilds cleanly.
@jackgranatowski

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Addresses CodeRabbit review on PR #230:

- Real fix: the save_post_{BRICKS_DB_CUSTOM_FONTS} cache-bust hook was
  registered inside Slashed_Bricks_Fonts_REST::register_routes(), which only
  runs on rest_api_init. A normal admin save of a custom-font post therefore
  left the slashed_bricks_cpt_fonts transient stale for up to an hour. Moved
  invalidation to Slashed_Token_Page::flush_bricks_fonts_cache() (the
  always-loaded canonical owner of the transient) and hooked it from
  slashed_bricks_data_init() (plugins_loaded, all request types). REST class
  no longer registers the hook.
- Nitpick: added the base/surface explanatory comment in class-inventory.php
  to mirror the note in export.js.

php -l clean on all changed files; PHP-only change, no bundle rebuild needed.
@jackgranatowski
jackgranatowski merged commit d24b257 into main Jun 5, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants