chore: apply audit batch (lint repair + SEO/map + evaluator + docs)#5818
Merged
Conversation
Tackles five quick-win items from agentic/audits/latest.md:
1. Frontend lint CI repair (32 errors -> 0):
- eslint.config.js: add IdleRequestCallback/IdleDeadline,
IntersectionObserver* type aliases, FrameRequestCallback to
production globals; add Node `global` to test entry.
- 5x react-hooks/set-state-in-effect: refactor to React 19's
"adjust state on prop change" pattern (RelatedSpecs,
SpecDetailView, DebugPage, SpecsListPage).
- react-hooks/purity: extract Math.random call from
useFeaturedSpecs into module-level helper.
- DebugPage no-empty: comment the sessionStorage swallows.
- SpecOverview.test: use the previously-unused implNoPreview.
- MapPage.test: drop a now-stale eslint-disable directive.
2. SEO proxy: add /seo-proxy/map handler so bots get a real
<title>/<meta description> for the network map page.
3. evaluate-plot.py: replace the inline 5-category JSON template
with the canonical 6-category prompts/quality-evaluator.md +
prompts/quality-criteria.md (Visual Quality 30 / Design
Excellence 20 / Spec Compliance 15 / Data Quality 15 / Code
Quality 10 / Library Mastery 10). Update print_quality_result
keys + denominators to match. Bump core/config.py
claude_model default from claude-3-5-sonnet-20240620 to
claude-sonnet-4-6.
4. plausible.md: document FCP and TTFB events emitted by
reportWebVitals.ts (28 -> 30 client-side events). NOTE: also
needs registration in the Plausible dashboard before they
land.
5. CodeQL alert #101 (clear-text-storage in
plots/radar-basic/.../highcharts.py): already dismissed by
the repo owner on 2026-05-05 -- no action needed in this PR.
Broader path-exclude follow-up (advanced setup) not done
here.
Verification: yarn lint = 0 errors, yarn tsc --noEmit clean,
466/466 tests pass; ruff check + format clean on api/+core/
(scripts/ is excluded from ruff per pyproject.toml).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR applies a small batch of “audit quick wins” across the frontend, API SEO proxy, evaluation tooling, and documentation to reduce CI lint noise, improve bot-facing metadata, and align plot evaluation with the canonical quality rubric.
Changes:
- Fix frontend lint issues by updating ESLint globals and refactoring several “set state in effect” patterns to render-phase state adjustments.
- Add a bot-optimized
/seo-proxy/mapendpoint with correct title/description meta tags for the network map page. - Modernize
scripts/evaluate-plot.pyto composeprompts/quality-evaluator.md+prompts/quality-criteria.md, and update score printing to the 6-category rubric; bump the default Claude model in config. - Document additional Web Vitals custom events (FCP/TTFB) in Plausible reference docs.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/evaluate-plot.py | Switch evaluation prompt to canonical evaluator + criteria and update category printing. |
| core/config.py | Update default claude_model. |
| api/routers/seo.py | Add /seo-proxy/map handler for bot prerender metadata. |
| docs/reference/plausible.md | Document FCP/TTFB events and update event totals. |
| app/eslint.config.js | Add missing globals used by frontend code/tests. |
| app/src/pages/SpecsListPage.tsx | Refactor rotation index initialization to avoid effect-based state setting. |
| app/src/pages/DebugPage.tsx | Refactor loading/error reset behavior and annotate sessionStorage no-ops. |
| app/src/components/RelatedSpecs.tsx | Refactor loading/reset logic to avoid state-setting-in-effect lint issues. |
| app/src/components/SpecDetailView.tsx | Reset interactive size on library change using render-phase adjustment. |
| app/src/hooks/useFeaturedSpecs.ts | Extract random selection into a helper for hook purity. |
| app/src/components/SpecOverview.test.tsx | Use previously-unused test variable to fix lint. |
| app/src/pages/MapPage.test.tsx | Remove unused ESLint disable. |
Comment on lines
136
to
147
| "library_rules": PROJECT_ROOT / "prompts" / "library" / f"{library}.md", | ||
| "quality_criteria": PROJECT_ROOT / "prompts" / "quality-criteria.md", | ||
| "quality_evaluator": PROJECT_ROOT / "prompts" / "quality-evaluator.md", | ||
| } |
| ```markdown | ||
| {criteria_content} | ||
| ``` | ||
Comment on lines
+263
to
+276
| @router.get("/seo-proxy/map") | ||
| async def seo_map(): | ||
| """Bot-optimized network map page with correct og:tags.""" | ||
| return HTMLResponse( | ||
| BOT_HTML_TEMPLATE.format( | ||
| title="Network Map | anyplot.ai", | ||
| description=( | ||
| "Interactive network map of plot specifications grouped by visual similarity — " | ||
| "explore relationships across all anyplot.ai chart types." | ||
| ), | ||
| image=DEFAULT_HOME_IMAGE, | ||
| url="https://anyplot.ai/map", | ||
| ) | ||
| ) |
Three review-driven follow-ups:
1. evaluate-plot.py: paths now use the language-namespaced layout
(implementations/python/{library}.py + metadata/python/{library}.yaml),
matching the actual repo structure. Adds optional `language`
parameter (default "python"). Without this, the script silently
reads from non-existent paths and reports failure regardless of
the implementation.
2. evaluate-plot.py: prompt now declares "Local CLI Mode — Single
Render Only" so the canonical evaluator (which expects both
plot-light.png + plot-dark.png) does not deduct VQ-07 etc. for
the missing theme pair. paths dict gains image_light/image_dark
entries for future dual-render support.
3. tests: add test_seo_map mirroring test_seo_about /
test_seo_palette to cover the new /seo-proxy/map handler.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five quick-win items from
agentic/audits/latest.md(2026-05-05):/seo-proxy/map— bot prerender for the network map (audit Critical #5 partial).Detail
1. Lint repair (
yarn lint32→0 errors)app/eslint.config.js: addedIdleRequestCallback,IdleDeadline,IdleCallbackHandle,IdleRequestOptions,requestIdleCallback,cancelIdleCallback,FrameRequestCallback,IntersectionObserverCallback,IntersectionObserverInit,IntersectionObserverEntryto production globals; added Nodeglobalto test-entry globals.react-hooks/set-state-in-effect: refactored to React 19's "adjust state on prop change" pattern (if (prev !== current) { setPrev(current); ... }during render — no cascading re-render):RelatedSpecs.tsx— combinedsetExpanded(false)+setLoading(true)resets into a singleprevDepsguard.SpecDetailView.tsx— interactive size reset onselectedLibrarychange.DebugPage.tsx—setLoading(true)/setError(null)reset on[adminToken, reloadCounter]change.SpecsListPage.tsx— random rotation init driven byObject.keys(rotationIndex).length === 0guard (reference-compare onspecListwas attempted first but trips an infinite re-render in the test mock, which returns a freshspecsDataarray each call).react-hooks/purity:Math.randominuseFeaturedSpecs.tsextracted into a module-levelpickRandom<T>(items)helper.no-empty: sessionStorage swallows inDebugPage.tsxannotated with a comment.implNoPreview(SpecOverview.test.tsx): now used in the test (was a copy-paste oversight).MapPage.test.tsx:413) removed.2. SEO
/maphandlerMirrors the about/palette pattern in
api/routers/seo.py. Bots now get a real<title>(Network Map | anyplot.ai) and a meta description.3. evaluate-plot.py modernization
prompts/quality-evaluator.md+prompts/quality-criteria.md(Visual Quality 30 / Design Excellence 20 / Spec Compliance 15 / Data Quality 15 / Code Quality 10 / Library Mastery 10 = 100).print_quality_resultand the--verboseloop updated to the new keys + denominators (was readinglibrary_features/vq…/40etc., now readslibrary_mastery/vq…/30).core/config.py:claude_modeldefault bumped fromclaude-3-5-sonnet-20240620(18 months old) toclaude-sonnet-4-6.4. Plausible docs (FCP/TTFB)
docs/reference/plausible.md: added FCP and TTFB rows to Custom Events table + Implementation Checklist; bumped total client-side events from 28 → 30.5. CodeQL #101 — already dismissed
gh api repos/.../code-scanning/alerts/101showsstate: dismissedsince2026-05-05T21:38:46Z(dismissed by @MarkusNeusinger as "false positive — 'private' is a literal field name in a demo radar-chart axis dataset"). Audit was generated on the same day and listed it as still open. No code change in this PR for this item.The audit's broader recommendation — "exclude
plots/from CodeQL scan" — would require switching from default to advanced code-scanning setup (workflow file +.github/codeql/codeql-config.yml). Not done here; left as a future hygiene task.Test plan
yarn lint→ 0 errors (2 pre-existing react-refresh warnings unchanged)yarn tsc --noEmit→ cleanyarn test --run→ 466/466 passuv run ruff check api/ core/→ cleanuv run ruff format --check api/ core/→ clean🤖 Generated with Claude Code