@@ -10,6 +10,7 @@ interface ProjectConfig {
1010 targetDir : string
1111 renderMode : 'ssr-stream' | 'ssr-string' | 'ssg' | 'spa'
1212 features : string [ ]
13+ packageStrategy : 'meta' | 'individual'
1314 aiToolchain : boolean
1415}
1516
@@ -68,6 +69,26 @@ const FEATURES = {
6869 label : 'Hooks (@pyreon/hooks — 25+ signal-based utilities)' ,
6970 deps : [ '@pyreon/hooks' ] ,
7071 } ,
72+ charts : {
73+ label : 'Charts (@pyreon/charts — reactive ECharts)' ,
74+ deps : [ '@pyreon/charts' ] ,
75+ } ,
76+ hotkeys : {
77+ label : 'Hotkeys (@pyreon/hotkeys — keyboard shortcuts)' ,
78+ deps : [ '@pyreon/hotkeys' ] ,
79+ } ,
80+ storage : {
81+ label : 'Storage (@pyreon/storage — localStorage, cookies, IndexedDB)' ,
82+ deps : [ '@pyreon/storage' ] ,
83+ } ,
84+ flow : {
85+ label : 'Flow Diagrams (@pyreon/flow — reactive node graphs)' ,
86+ deps : [ '@pyreon/flow' ] ,
87+ } ,
88+ code : {
89+ label : 'Code Editor (@pyreon/code — CodeMirror 6)' ,
90+ deps : [ '@pyreon/code' ] ,
91+ } ,
7192} as const
7293
7394type FeatureKey = keyof typeof FEATURES
@@ -142,6 +163,20 @@ async function main() {
142163 process . exit ( 0 )
143164 }
144165
166+ // Package strategy
167+ const packageStrategy = await p . select ( {
168+ message : 'Package imports' ,
169+ options : [
170+ { value : 'meta' , label : '@pyreon/meta (single barrel)' , hint : 'one import for everything — simpler, tree-shaken at build' } ,
171+ { value : 'individual' , label : 'Individual packages' , hint : 'only install what you selected — smaller node_modules' } ,
172+ ] ,
173+ } )
174+
175+ if ( p . isCancel ( packageStrategy ) ) {
176+ p . cancel ( 'Cancelled.' )
177+ process . exit ( 0 )
178+ }
179+
145180 // AI toolchain
146181 const aiToolchain = await p . confirm ( {
147182 message : 'Include AI toolchain? (MCP server, CLAUDE.md, doctor)' ,
@@ -158,6 +193,7 @@ async function main() {
158193 targetDir,
159194 renderMode : renderMode as ProjectConfig [ 'renderMode' ] ,
160195 features : features as string [ ] ,
196+ packageStrategy : packageStrategy as ProjectConfig [ 'packageStrategy' ] ,
161197 aiToolchain : aiToolchain as boolean ,
162198 }
163199
@@ -266,45 +302,79 @@ async function scaffold(config: ProjectConfig) {
266302
267303// ─── File generators ────────────────────────────────────────────────────────
268304
305+ // Resolve the correct version range for a @pyreon /* package
306+ function pyreonVersion ( pkg : string ) : string {
307+ // Core packages
308+ const core = [ 'core' , 'reactivity' , 'runtime-dom' , 'runtime-server' , 'server' , 'head' , 'router' , 'vite-plugin' , 'compiler' , 'cli' , 'mcp' ]
309+ if ( core . some ( ( c ) => pkg === `@pyreon/${ c } ` ) ) return '^0.7.0'
310+ // Zero framework packages
311+ if ( pkg === '@pyreon/zero' || pkg === '@pyreon/meta' || pkg === '@pyreon/zero-cli' || pkg === '@pyreon/create-zero' ) return '^0.2.0'
312+ // Fundamentals
313+ const fundamentals = [ 'store' , 'form' , 'validation' , 'query' , 'table' , 'virtual' , 'i18n' , 'feature' , 'machine' , 'permissions' , 'flow' , 'code' ]
314+ if ( fundamentals . some ( ( f ) => pkg === `@pyreon/${ f } ` ) ) return '^0.6.0'
315+ // UI system
316+ return '^0.2.0'
317+ }
318+
269319function generatePackageJson ( config : ProjectConfig ) : string {
270320 const deps : Record < string , string > = {
271- '@pyreon/core' : 'latest' ,
272- '@pyreon/head' : 'latest' ,
273- '@pyreon/reactivity' : 'latest' ,
274- '@pyreon/router' : 'latest' ,
275- '@pyreon/runtime-dom' : 'latest' ,
276- '@pyreon/runtime-server' : 'latest' ,
277- '@pyreon/server' : 'latest' ,
278- '@pyreon/zero' : 'latest' ,
321+ '@pyreon/core' : pyreonVersion ( '@pyreon/core' ) ,
322+ '@pyreon/head' : pyreonVersion ( '@pyreon/head' ) ,
323+ '@pyreon/reactivity' : pyreonVersion ( '@pyreon/reactivity' ) ,
324+ '@pyreon/router' : pyreonVersion ( '@pyreon/router' ) ,
325+ '@pyreon/runtime-dom' : pyreonVersion ( '@pyreon/runtime-dom' ) ,
326+ '@pyreon/runtime-server' : pyreonVersion ( '@pyreon/runtime-server' ) ,
327+ '@pyreon/server' : pyreonVersion ( '@pyreon/server' ) ,
328+ '@pyreon/zero' : pyreonVersion ( '@pyreon/zero' ) ,
279329 }
280330
281- // Add feature-specific deps
282- const allDeps = new Set < string > ( )
283- for ( const key of config . features ) {
284- const feature = FEATURES [ key as FeatureKey ]
285- if ( feature ) {
286- for ( const dep of feature . deps ) allDeps . add ( dep )
331+ if ( config . packageStrategy === 'meta' ) {
332+ // Single barrel — includes all fundamentals + UI system
333+ deps [ '@pyreon/meta' ] = pyreonVersion ( '@pyreon/meta' )
334+ // Still need non-pyreon deps for selected features
335+ for ( const key of config . features ) {
336+ const feature = FEATURES [ key as FeatureKey ]
337+ if ( feature ) {
338+ for ( const dep of feature . deps ) {
339+ if ( ! dep . startsWith ( '@pyreon/' ) ) {
340+ if ( dep . startsWith ( '@tanstack/' ) ) {
341+ deps [ dep ] = dep . includes ( 'query' ) ? '^5.90.0' : dep . includes ( 'table' ) ? '^8.21.0' : '^3.13.0'
342+ } else if ( dep === 'zod' ) {
343+ deps [ dep ] = '^4.0.0'
344+ }
345+ }
346+ }
347+ }
287348 }
288- }
289- for ( const dep of allDeps ) {
290- if ( dep . startsWith ( '@pyreon/' ) ) {
291- deps [ dep ] = 'latest'
292- } else if ( dep . startsWith ( '@tanstack/' ) ) {
293- deps [ dep ] = dep . includes ( 'query' ) ? '^5.90.0' : dep . includes ( 'table' ) ? '^8.21.0' : '^3.13.0'
294- } else if ( dep === 'zod' ) {
295- deps [ dep ] = '^4.0.0'
349+ } else {
350+ // Individual packages — only install what's selected
351+ const allDeps = new Set < string > ( )
352+ for ( const key of config . features ) {
353+ const feature = FEATURES [ key as FeatureKey ]
354+ if ( feature ) {
355+ for ( const dep of feature . deps ) allDeps . add ( dep )
356+ }
357+ }
358+ for ( const dep of allDeps ) {
359+ if ( dep . startsWith ( '@pyreon/' ) ) {
360+ deps [ dep ] = pyreonVersion ( dep )
361+ } else if ( dep . startsWith ( '@tanstack/' ) ) {
362+ deps [ dep ] = dep . includes ( 'query' ) ? '^5.90.0' : dep . includes ( 'table' ) ? '^8.21.0' : '^3.13.0'
363+ } else if ( dep === 'zod' ) {
364+ deps [ dep ] = '^4.0.0'
365+ }
296366 }
297367 }
298368
299369 const devDeps : Record < string , string > = {
300- '@pyreon/vite-plugin' : 'latest' ,
301- '@pyreon/zero-cli' : 'latest' ,
370+ '@pyreon/vite-plugin' : pyreonVersion ( '@pyreon/vite-plugin' ) ,
371+ '@pyreon/zero-cli' : pyreonVersion ( '@pyreon/zero-cli' ) ,
302372 'typescript' : '^5.9.3' ,
303373 'vite' : '^7.0.0' ,
304374 }
305375
306376 if ( config . aiToolchain ) {
307- devDeps [ '@pyreon/mcp' ] = 'latest'
377+ devDeps [ '@pyreon/mcp' ] = pyreonVersion ( '@pyreon/mcp' )
308378 }
309379
310380 const scripts : Record < string , string > = {
0 commit comments