fix(debug): preserve language in plot links so R/ggplot2 deep-links work#7066
Merged
Conversation
DebugPage hardcoded 'python' when building plot-detail URLs (recent
activity + spec matrix, desktop and mobile). For ggplot2 (R) this
produced /spec/python/ggplot2; SpecPage then validated that an impl
exists with language=python AND library=ggplot2, found none, and
redirected to the Python-filtered hub overview — exactly the symptom
reported (lands on overview, plot missing).
Fixes alongside, all triggered by the same R-language rollout:
- /debug/status RecentActivity now carries language_id so the frontend
doesn't have to guess
- SpecStatusItem gains a ggplot2 column (was silently missing — the
matrix column was always empty)
- coverage = total / (specs * len(SUPPORTED_LIBRARIES)) instead of *9
- library_names map includes ggplot2
- Hardcoded 9s in DebugPage replaced with LIBRARIES.length
(filter, count display, grid template)
- /specs/{id}/images and /libraries/{id}/images now expose language too,
so external API consumers can build the same deep links
Frontend constants gain LIB_TO_LANG (mirror of LIB_ABBREV) so the matrix
grid can resolve a column's language without waiting for /libraries to
load.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes broken deep-links for non-Python implementations (notably R/ggplot2) by preserving the correct implementation language when building links from the debug dashboard, and extends a couple of image-list API responses to include language so external consumers can build the same links.
Changes:
- Debug dashboard now uses the real implementation language (
language_id) for recent-activity links, and uses a library→language map for the spec matrix where onlylibrary_idis available. /debug/statusrecent-activity payload now includeslanguage_id, and ggplot2 is added to the spec status matrix model/column set; coverage calculation is no longer hardcoded to 9 libraries./specs/{id}/imagesand/libraries/{id}/imagesnow includelanguagein each image entry; API docs updated accordingly; unit tests updated for the new debug payload and dynamic library count.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/api/test_debug.py | Updates debug endpoint unit tests for language_id in recent activity and for dynamic coverage computation. |
| docs/reference/api.md | Documents the new language field in images responses. |
| app/src/pages/DebugPage.tsx | Fixes debug-page deep-links to preserve language; replaces hardcoded 9 with LIBRARIES.length; adds ggplot2 support in the matrix type. |
| app/src/pages/DebugPage.test.tsx | Adjusts mock debug payload shape to include the new ggplot2 column. |
| app/src/constants/index.ts | Adds LIB_TO_LANG mapping to build correct links from library-only contexts. |
| api/routers/specs.py | Adds language to /specs/{id}/images response entries. |
| api/routers/libraries.py | Adds language to /libraries/{id}/images response entries. |
| api/routers/debug.py | Adds language_id to recent activity items, adds ggplot2 column, and replaces hardcoded library-count coverage math. |
Comment on lines
+31
to
+32
| // only know a library id (e.g. the debug-page spec matrix and recent-activity | ||
| // list, which would otherwise have to wait for /libraries to load). |
| """recent_activity should return impls sorted by updated DESC, capped at 15.""" | ||
| """recent_activity should return impls sorted by updated DESC, capped at 15, | ||
| and surface each impl's language so the frontend can build correct deep links | ||
| (regression: Python + R impls were both linked as /spec/python/... before). |
- ruff format collapsed two over-wrapped literals (api/routers/specs.py
spec-images dict and the recent-activity test impl_r construction).
- Narrow the LIB_TO_LANG comment to the spec-matrix use case — once
recent activity started carrying language_id from /debug/status it
no longer relies on the static map.
- Update the recent-activity regression docstring so the URL shape
matches the real specPath output ({specId}/{language}/{library},
not /spec/python/...).
This was referenced May 22, 2026
MarkusNeusinger
added a commit
that referenced
this pull request
May 22, 2026
) Closes #7612. Adds **Julia** as anyplot's third language with **Makie.jl** (CairoMakie backend) as its first library entry. Generalizes the multi-language plumbing introduced for R/ggplot2 in #6944 + follow-ups (#6947, #6961, #7066) so every `python | r` dispatch now handles `python | r | julia` uniformly. ## Phase ordering — heads-up This ships **Phase 5 (Julia) before Phases 1+2 (JavaScript family)**, which the issue called out explicitly. The multi-language pipeline is already proven on R; shipping Julia next provides a cheap second non-Python validation that surfaces multi-language gaps the JS work would otherwise hit cold. The JavaScript phases remain planned in unchanged order. See `docs/concepts/library-expansion.md` §9. ## Why Makie over Plots.jl Distinct scientific stack (not a wrapper), ~45 % share within Julia, MIT-licensed. CairoMakie is the right backend for CI — pure-Cairo, headless, no GPU / GLFW window. `PlotlyJS.jl` is a plotly.js wrapper (already covered via Python Plotly). Plots.jl is the alternative; revisit only if Plausible data flips. `GLMakie` / `WGLMakie` interactive backends are out of scope; `INTERACTIVE_LIBRARIES` intentionally excludes Makie. ## What's in the PR ### Constants + registry - `core/constants.py`: add `julia` language, `makie` library - `tests/unit/core/test_constants.py`: assert `julia` + `makie` ### CI runtime - `.github/actions/setup-julia/action.yml`: install Julia 1.11, restore from `Project.toml` / `Manifest.toml`, smoke-test a CairoMakie render - `Project.toml`: pin CairoMakie + Makie + dataset packages (CSV, Colors, ColorSchemes, DataFrames, PalmerPenguins, RDatasets, Random, Statistics) **`Manifest.toml` is intentionally not committed** — it gets resolved by the first CI run; the action falls back to `Pkg.add(...)` when `Manifest.toml` is absent so first-run doesn't hard-fail. (Same model as `renv.lock` had pre-bump on the R rollout.) ### Workflows Each workflow derives `LANGUAGE` + `EXT` from `LIBRARY` via a case statement. Every case now has `matplotlib→python`, `ggplot2→r`, `makie→julia`: - `impl-generate.yml`, `impl-repair.yml`, `impl-review.yml`, `impl-merge.yml`: add the `makie→julia` arm; install `setup-julia` when `language==julia`; detect Julia version via `julia -e 'print(VERSION)'`; detect Makie version via `Pkg.dependencies()` - `impl-review.yml`: - extend canvas-gate library-cause map with a Makie entry (`Figure(resolution=(1600,900)) + px_per_unit=2` → 3200×1800; `resolution=(1200,1200)` → 2400×2400) - extend header-rewrite step to handle `#`-prefixed Julia comment blocks, with prepend fallback when missing (same fix as #6947 did for Python / R) - `bulk-generate.yml`: add `makie` to `library` choices and `ALL_LIBRARIES` - `impl-merge.yml`: completion total now derives from the actual library list rather than hardcoding 9 ### Prompts - **`prompts/library/makie.md`** (new): no-workarounds policy, NOT_FEASIBLE for primary-interactivity specs, canvas hard rule, `ANYPLOT_THEME` mapping, forbidden patterns (no `Plots.jl`, no `display(fig)`, no `GLMakie`/`WGLMakie`), `# `-comment header style - `plot-generator.md`: extend lead, available environment, forbidden patterns with Julia/Makie section - `quality-evaluator.md`, `workflow-prompts/ai-quality-review.md`: extend the AR-08 static-libraries list with `makie`; extend the language allow-list with `julia` - `workflow-prompts/impl-generate-claude.md`, `impl-repair-claude.md`: add the `julia | .jl | julia --project=.` row to the (language, ext, runner) table; add Julia run + format sections - `workflow-prompts/impl-similarity-claude.md`: third arm for `julia` in the `{language}` mapping ### Frontend (avoids the two-follow-up-PR pattern from #6961 / #7066) - `app/src/constants/index.ts`: add `makie` to `LIBRARIES`, `LIB_ABBREV: 'mk'`, `LIB_TO_LANG: 'julia'`, `LANG_DISPLAY: 'Julia'`, `LANG_EXT: 'jl'` - `app/src/components/CodeHighlighter.tsx`: register `julia` Prism grammar - `app/src/types/react-syntax-highlighter.d.ts`: declare the `prism/julia` module locally — **TS7016 fix in same PR, not deferred** (the issue specifically called this out as a gap not to repeat) - `app/src/components/LibraryCard.tsx`: description for makie - `app/src/components/PlotOfTheDay.tsx`, `PlotOfTheDayTerminal.tsx`: `julia --project=.` runner token + `.jl` extension when language is julia - `app/src/pages/LibrariesPage.tsx`, `AboutPage.tsx`, `PlotsPage.tsx`: meta-description copy bumped to "Eleven libraries across Python, R, and Julia" - `app/src/pages/DebugPage.tsx`: `makie` column in `SpecStatus` interface (the grid template uses `LIBRARIES.length` so the matrix grows automatically) ### Backend - `api/routers/debug.py`: `SpecStatusItem` and `library_names` entries for makie - `api/routers/specs.py`: doc comment updated to note `makie is Julia` ### Tests - `app/src/components/CodeHighlighter.test.tsx`: julia-grammar case - `app/src/hooks/useCodeFetch.test.ts`: julia `?language=` case + three-language cache-key test - `app/src/pages/DebugPage.test.tsx`: `makie` field on fixture ### Docs - `docs/concepts/library-expansion.md`: §1 current-state table grows to 11 entries; §8 Phase 5 marked **shipped**; §9 records the phase-skip rationale, Makie-over-Plots.jl decision, and CairoMakie-only scope - `docs/reference/repository.md`: `implementations/` layout shows `python/` + `r/` + `julia/` siblings - `docs/concepts/vision.md`, `docs/reference/style-guide.md`: pipeline-story copy ("eleven libraries in three languages") - `docs/reference/plausible.md`: language slug list now includes `julia` - `prompts/README.md`, `agentic/docs/project-guide.md`: Makie added ## Verified - ✅ `core/constants.py` loads: `len(SUPPORTED_LIBRARIES)=11`, `SUPPORTED_LANGUAGES={'python','r','julia'}` - ✅ `pytest tests/unit/core tests/unit/api/test_routers.py tests/unit/api/test_debug.py tests/unit/api/test_schemas.py` — **213 passed**, no regressions - ✅ `Project.toml` valid TOML, deps load - Frontend tests are wired but I couldn't run `yarn test` in this environment (no node_modules). Code follows the existing patterns from the R rollout. ## Post-merge follow-ups (called out in the issue) 1. Run `uv run python -m automation.scripts.label_manager sync` once so `library:makie`, `generate:makie`, `impl:makie:{pending,done,failed}` labels appear. 2. First CI run of `setup-julia` will resolve `Manifest.toml` — commit that lockfile in a tiny follow-up so subsequent runs use `Pkg.instantiate()` instead of the `Pkg.add` fallback. 3. Trigger `bulk-generate.yml -f library=makie` to fill the catalog (separate from this infra PR — the issue called this out as "Out of scope" / handled by the regular flow). 4. Optional `julia.anyplot.ai` marketing subdomain (mentioned in the issue's "Out of scope" section; small follow-up modeled on `python.anyplot.ai`). --- _Generated by [Claude Code](https://claude.ai/code/session_01AzjPDEE5aY2LYR5tcK3faj)_ --------- Co-authored-by: Claude <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
Clicking an R/ggplot2 implementation from
/debuglanded on the cross-language hub filtered to?language=python(without the plot), instead of opening the implementation detail page. Root cause:DebugPage.tsxhardcoded'python'as the language when building plot deep links — for ggplot2 this produced/spec/python/ggplot2, whichSpecPagethen validates against the impl set, fails to match (the impl is in languager), and redirects to the Python-filtered hub.Audited all other pages — only
DebugPagehad the hardcoded-'python'bug. Every other deep link (PlotOfTheDay,SpecOverview,StatsPage,PlotsPage,RelatedSpecs,SpecPage) readslanguagefrom the API response.What changed
Bug fix (DebugPage):
act.language_idfrom the API, and via a newLIB_TO_LANGconstant for the matrix where only alibrary_idis in scope).Companion fixes triggered by the R/ggplot2 rollout that the debug pipe never picked up:
RecentActivitypayload (/debug/status) now includeslanguage_id.SpecStatusItemgains theggplot2column — the matrix column was always empty before.library_namesmap and coverage formula (wasspecs * 9, nowspecs * len(SUPPORTED_LIBRARIES)).9s inDebugPagereplaced withLIBRARIES.length(filter button,{implCount}/9cell,repeat(9, 40px)grid template — both desktop and mobile)./specs/{id}/imagesand/libraries/{id}/imagesnow also exposelanguageso external API consumers (MCP / docs) can build the same deep links. Docs updated.Tests:
_make_implhelper acceptslanguage_id(defaults to"python").test_debug_status_recent_activitynow exercises an R/ggplot2 impl and assertslanguage_idsurvives the round-trip — the regression that just shipped.len(SUPPORTED_LIBRARIES)rather than the magic9.Test plan
uv run --extra test --extra plotting pytest tests/unit/— 1437 passedyarn test --run— 459 passedyarn tsc --noEmit— clean/debug, click a ggplot2 cell in the matrix → lands on/{spec}/r/ggplot2with the plot visible/{spec}/python/{lib}as beforehttps://claude.ai/code/session_01YKrNgGApdLy6LBfRQbL7qf
Generated by Claude Code