@@ -41,6 +41,7 @@ import { TursoDriver } from '@objectstack/driver-turso';
4141import { SqlDriver } from '@objectstack/driver-sql' ;
4242import type { Contracts } from '@objectstack/spec' ;
4343import { createControlPlanePlugins } from './control-plane-preset.js' ;
44+ import { createTemplateSeeder } from './template-seeder.js' ;
4445
4546type IDataDriver = Contracts . IDataDriver ;
4647
@@ -194,40 +195,10 @@ async function bootstrapMultiProject(
194195 ) ,
195196 } ) ;
196197
197- // MVP app-bundle resolver.
198- //
199- // The example CRM / Todo / BI bundles are loaded lazily *and* gated on
200- // an env flag so that:
201- // 1. Test environments (E2E, unit tests) can skip them entirely —
202- // the example `defineStack(...)` configs perform their own Zod
203- // validation on import, so a single unrelated schema drift in
204- // an example would otherwise crash bootstrap for everyone.
205- // 2. Production multi-project deployments that do not ship the
206- // reference apps (the typical case) avoid paying the cost.
207- //
208- // Set `OBJECTSTACK_BUNDLE_EXAMPLES=true` to get the legacy behaviour —
209- // all three example bundles are attached to every project kernel.
210- // Swap this resolver for a registry-backed one once
211- // `sys_project_package` is consulted.
198+ // Example bundles are no longer pre-installed into every project kernel.
199+ // They are seeded once at provisioning time via `createTemplateSeeder`.
212200 const appBundles : AppBundleResolver = {
213- async resolve ( ) {
214- if ( process . env . OBJECTSTACK_BUNDLE_EXAMPLES !== 'true' ) {
215- return [ ] ;
216- }
217- // Dynamic `new Function('return import(...)')(…)` sidesteps
218- // TypeScript's static rootDir analysis — the example configs
219- // live outside apps/server's tsconfig rootDir but are still
220- // resolvable at runtime. Kept here intentionally so the tsc
221- // typecheck doesn't need a dedicated include for examples.
222- const dyn = ( spec : string ) =>
223- ( new Function ( 's' , 'return import(s)' ) as ( s : string ) => Promise < any > ) ( spec ) ;
224- const [ crm , todo , bi ] = await Promise . all ( [
225- dyn ( '../../../examples/app-crm/objectstack.config.ts' ) ,
226- dyn ( '../../../examples/app-todo/objectstack.config.ts' ) ,
227- dyn ( '../../../examples/plugin-bi/objectstack.config.ts' ) ,
228- ] ) ;
229- return [ crm . default , todo . default , bi . default ] ;
230- } ,
201+ async resolve ( ) { return [ ] ; } ,
231202 } ;
232203
233204 // Per-project kernels only need the minimal base — driver is injected
@@ -259,6 +230,11 @@ async function bootstrapMultiProject(
259230
260231 const controlKernel = await bootstrapControlKernel ( controlDriver , driverName ) ;
261232
233+ // Register the template seeder so http-dispatcher can resolve it during
234+ // provisioning via `kernel.getServiceAsync('template-seeder')`.
235+ const seeder = createTemplateSeeder ( kernelManager ) ;
236+ controlKernel . registerService ( 'template-seeder' , seeder ) ;
237+
262238 return {
263239 kernel : controlKernel ,
264240 kernelManager,
0 commit comments