diff --git a/packages/bgm/src/__fixtures__/vite-build/src/vite-env.d.ts b/packages/bgm/src/__fixtures__/vite-build/src/vite-env.d.ts
new file mode 100644
index 0000000..be225f6
--- /dev/null
+++ b/packages/bgm/src/__fixtures__/vite-build/src/vite-env.d.ts
@@ -0,0 +1,18 @@
+///
+
+/**
+ * Ambient types for the virtual `bgm` modules served by the bgm vite plugin,
+ * so the fixture's entry typechecks in the editor (the plugin provides them at
+ * build time). Mirrors `apps/web/src/vite-env.d.ts`.
+ */
+declare module 'virtual:bgm/packages' {
+ import type { SerializedPackage } from '@tts/bgm';
+ const packages: SerializedPackage[];
+ export default packages;
+}
+
+declare module 'virtual:bgm/package/*' {
+ import type { SerializedPackage } from '@tts/bgm';
+ const pkg: SerializedPackage;
+ export default pkg;
+}
\ No newline at end of file
diff --git a/packages/bgm/src/vite.unit.test.ts b/packages/bgm/src/vite.unit.test.ts
index 9ad383a..fca3923 100644
--- a/packages/bgm/src/vite.unit.test.ts
+++ b/packages/bgm/src/vite.unit.test.ts
@@ -80,7 +80,9 @@ describe('bgm vite plugin', () => {
const plugin = bgm({ root: gamesRoot });
const watched: string[] = [];
const context = { addWatchFile: (file: string) => watched.push(file) };
- (plugin.buildStart as Callable).call(context);
+ // Vite 8 (rolldown) `buildStart` takes `(this, options)`; the plugin ignores
+ // the options, so pass a placeholder.
+ (plugin.buildStart as Callable).call(context, {} as never);
// Every def file (real + virtual code blocks) is watched so edits
// trigger a re-collect.