fix(deploy): ship data/ so Docker images keep their baked plugin previews - #7028
Open
jiulongche wants to merge 1 commit into
Open
fix(deploy): ship data/ so Docker images keep their baked plugin previews#7028jiulongche wants to merge 1 commit into
jiulongche wants to merge 1 commit into
Conversation
…iews
`deploy/Dockerfile` copies skills, design-systems, craft, prompt-templates,
assets and plugins/_official, but not data/ — so
`data/plugin-previews/manifest.json`, which CI commits precisely so deployments
can find the bakes, is absent at runtime. `resolvePluginPreviewsDir()` defaults
to <projectRoot>/data/plugin-previews, `loadManifest()` returns {},
`applyBakedPreviews()` returns the records untouched, and
`inferPluginPreview(record, { preferBaked: true })` falls through to the live
iframe for every plugin.
Measured on 0.19.2 with 461 registered plugins: the checked-in manifest has 176
entries and 0 records carried od.bakedPreview. With data/ present the same
daemon reports 176 — deck 79, prototype 79, video 10, scenario 4, image 1,
audio 1, template 2. The packaged app reaches the manifest through its own
packaging path, so only Docker/self-hosted deployments are affected.
Also warn once per path when the manifest is absent. `loadManifest()` already
carries the reasoning for the malformed case — «would otherwise silently
disable every baked preview with no trace; surface it so it's diagnosable» —
but the absent branch returned {} with no message, which is the same failure
with the same lack of trace.
Fixes nexu-io#7018
xxiaoxiong
approved these changes
Aug 18, 2026
Contributor
|
Nice catch on the missing This PR changes a user-visible runtime behavior in Docker/self-hosted deployments, so it needs a manual QA pass before merge — please hold off self-merging for now; we'll loop QA in once it's merge-ready. |
nettee
approved these changes
Aug 18, 2026
nettee
left a comment
Contributor
There was a problem hiding this comment.
@jiulongche I reviewed every changed range and verified the Docker manifest is copied through both build stages, the one-per-path missing-manifest diagnostic is covered, and the focused daemon/e2e tests, typechecks, repository guard, and Dockerfile check all pass. This is a focused, well-tested fix—thanks for tracing the self-hosted regression and adding the regression coverage.
🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.
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.
Fixes #7018
Why
I run a self-hosted Docker deployment. Chasing blank thumbnails in the home rail, I found that no plugin was using its baked preview — all 461 were rendering as live, scaled iframes, which
plugin-preview-bakes.tsopens by noting is "GPU-expensive at scale" and is the whole reason the bakes exist.The cause is one missing
COPY. @lefarcen confirmed it in #7018 and labelled ithelp wanted/good first issue.What users will see
On Docker/self-hosted deployments, plugin cards in the home gallery show their baked poster and hover clip again instead of running a live iframe each. That is the same rendering the packaged app has always had; those users see no change.
Operators additionally get one log line if the manifest is ever missing again, instead of a gallery that is merely slower for no stated reason.
The chain
deploy/Dockerfilecopiesskills,design-systems,craft,prompt-templates,assetsandplugins/_official.data/is the one content directory missing from that list, and it holds the manifest CI commits for exactly this purpose:From there everything degrades quietly:
resolvePluginPreviewsDir()defaults to<projectRoot>/data/plugin-previewsloadManifest()finds nomanifest.jsonand returns{}applyBakedPreviews()early-returns the records untouched, so nothing gets anod.bakedPreviewinferPluginPreview(record, { preferBaked: true })falls through to the live-HTML branchMeasured on 0.19.2 with 461 registered plugins: the checked-in manifest has 176 entries, and 0 records carried
od.bakedPreview. Withdata/present the same daemon reports 176 — deck 79, prototype 79, video 10, scenario 4, image 1, audio 1, template 2.The packaged app reaches the manifest through its own packaging path, which is why this only bites Docker/self-hosted deployments and why it has gone unreported.
The second change
loadManifest()now warns once per path when the manifest is absent. That is not scope creep so much as finishing a thought already in the file — the malformed branch carries this comment:…and warns accordingly, while the absent branch returned
{}with no message. Same failure, same lack of trace. The notice is deduplicated per path becauseloadManifestruns on every plugin listing.Surface area
Screenshots
n/a — no UI surface. The visible effect is which of two existing render paths a card takes, and the counts above measure that directly.
Bug fix verification
e2e/tests/docker-image-content-directories.test.ts,apps/daemon/tests/plugin-preview-bakes.test.tsmain, green on this branch: yesPre-fix output:
The Dockerfile assertion lives in
e2e/tests/per the rootAGENTS.mdrule that repository-resource consistency checks belong there. It covers the other four runtime-resolved directories too, not justdata/, so the next one to go missing fails on the way in rather than in someone's deployment.assetsis deliberately excluded: the runtime stage copies it selectively (assets/frames,assets/community-pets), so a whole-directory assertion would be wrong.The daemon spec calls
applyBakedPreviewstwice against the same manifest-less directory, so it pins the dedup as well as the notice.Validation
pnpm --filter @open-design/daemon exec vitest run tests/plugin-preview-bakes.test.ts— 6 passedpnpm --filter @open-design/e2e exec vitest run tests/docker-image-content-directories.test.ts— 2 passedpnpm --filter @open-design/daemon typecheck— passpnpm guard— passI have not built the image in CI here; the Dockerfile change is two
COPYlines mirroring the ones directly above them, and the spec asserts both stages.Not addressed here
#7019 is the rendering bug this one exposes — with no manifest, every card lands on the live-iframe path, and deck tiles there position outside their frame. Separate PR (#7026). Fixing this issue hides that symptom for deck (79 of 80 are baked) but does not resolve it: 285 of the 461 bundled plugins have no bake at all, and user-installed plugins never do.