What
The vite-built node CLI (build-node.ts, published by publish.yml build-node-cli for 5 targets) ships .txt imports as asset URL strings instead of their content. Verified on current v2 by inspecting dist-node/opencode.mjs:
PROMPT_ANTHROPIC = "/assets/anthropic-Df_a6ajX.txt" // ← the Anthropic system prompt is this literal string
// likewise the default session prompt (session/runner/prompt/base.txt via model-request.ts)
// and the patch tool description (tool/plugin/patch.ts)
SSR builds do not even emit the asset files, so the URLs point at nothing — published node CLIs are running with URL paths where prompt text should be.
Why
.txt is in Vite's built-in KNOWN_ASSET_TYPES, so its core asset plugin claims those modules before the normal-priority rawTextPlugin load hook runs. .md imports work only because .md is not a known asset type.
Why nobody noticed
The bundle builds cleanly and --version/--help run fine — nothing evaluates the imported strings on that path, and at runtime a wrong prompt degrades quality rather than crashing. The bun-compiled CLI (the primary artifact) inlines text correctly, masking the node artifact.
Fix
One line: enforce: "pre" on rawTextPlugin in packages/cli/vite.node.config.ts, plus a build assertion that fails when any text import surfaces as an asset URL (only content assertions catch this class). Both are already implemented and verified in #41838 (they ride with the models.dev snapshot change, which made the same bug loud). If #41838 stalls, the two changes extract cleanly into a standalone fix.
What
The vite-built node CLI (
build-node.ts, published bypublish.ymlbuild-node-clifor 5 targets) ships.txtimports as asset URL strings instead of their content. Verified on current v2 by inspectingdist-node/opencode.mjs:SSR builds do not even emit the asset files, so the URLs point at nothing — published node CLIs are running with URL paths where prompt text should be.
Why
.txtis in Vite's built-inKNOWN_ASSET_TYPES, so its core asset plugin claims those modules before the normal-priorityrawTextPluginloadhook runs..mdimports work only because.mdis not a known asset type.Why nobody noticed
The bundle builds cleanly and
--version/--helprun fine — nothing evaluates the imported strings on that path, and at runtime a wrong prompt degrades quality rather than crashing. The bun-compiled CLI (the primary artifact) inlines text correctly, masking the node artifact.Fix
One line:
enforce: "pre"onrawTextPlugininpackages/cli/vite.node.config.ts, plus a build assertion that fails when any text import surfaces as an asset URL (only content assertions catch this class). Both are already implemented and verified in #41838 (they ride with the models.dev snapshot change, which made the same bug loud). If #41838 stalls, the two changes extract cleanly into a standalone fix.