@girardmedia/bootspring 2.0.36 → 2.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli/analyze.js CHANGED
@@ -21,6 +21,32 @@ function getContinuousAnalyzer() {
21
21
  return ContinuousAnalyzer;
22
22
  }
23
23
 
24
+ // Lazy load Phase 3 modules
25
+ let DeepArchitectureAnalyzer = null;
26
+ let ContinuousSecurityAnalyzer = null;
27
+ let SemanticDocumentAnalyzer = null;
28
+
29
+ function getDeepArchitectureAnalyzer() {
30
+ if (!DeepArchitectureAnalyzer) {
31
+ DeepArchitectureAnalyzer = require('../analyzers').DeepArchitectureAnalyzer;
32
+ }
33
+ return DeepArchitectureAnalyzer;
34
+ }
35
+
36
+ function getContinuousSecurityAnalyzer() {
37
+ if (!ContinuousSecurityAnalyzer) {
38
+ ContinuousSecurityAnalyzer = require('../analyzers').ContinuousSecurityAnalyzer;
39
+ }
40
+ return ContinuousSecurityAnalyzer;
41
+ }
42
+
43
+ function getSemanticDocumentAnalyzer() {
44
+ if (!SemanticDocumentAnalyzer) {
45
+ SemanticDocumentAnalyzer = require('../core/coherence').SemanticDocumentAnalyzer;
46
+ }
47
+ return SemanticDocumentAnalyzer;
48
+ }
49
+
24
50
  // Get project root
25
51
  const projectRoot = process.cwd();
26
52
 
@@ -39,12 +65,16 @@ ${utils.COLORS.bold}Usage:${utils.COLORS.reset}
39
65
  bootspring analyze reset Reset workflow
40
66
  bootspring analyze watch Watch mode - continuous analysis
41
67
  bootspring analyze drift Detect documentation drift
68
+ bootspring analyze deep Deep architecture analysis
69
+ bootspring analyze security Continuous security analysis
70
+ bootspring analyze semantic Semantic document analysis
42
71
 
43
72
  ${utils.COLORS.bold}Options:${utils.COLORS.reset}
44
73
  --depth=<level> Analysis depth: shallow, standard, deep
45
74
  --phase=<phase> Run specific phase only
46
75
  --include=<glob> Include pattern (e.g., "src/**")
47
76
  --exclude=<glob> Exclude pattern
77
+ --json Output results as JSON
48
78
 
49
79
  ${utils.COLORS.bold}Watch Mode:${utils.COLORS.reset}
50
80
  --watch Start file watcher for continuous analysis
@@ -55,6 +85,14 @@ ${utils.COLORS.bold}Depth Levels:${utils.COLORS.reset}
55
85
  standard Standard analysis with patterns and dependencies
56
86
  deep Comprehensive with flow tracing and components
57
87
 
88
+ ${utils.COLORS.bold}Advanced Analysis (Phase 3):${utils.COLORS.reset}
89
+ deep Comprehensive architecture analysis with data flow,
90
+ dependencies, components, and quality indicators
91
+ security Continuous security analysis with auth, data protection,
92
+ compliance, and vulnerability scanning
93
+ semantic AI-powered document understanding with concept extraction,
94
+ terminology analysis, and contradiction detection
95
+
58
96
  ${utils.COLORS.bold}Notes:${utils.COLORS.reset}
59
97
  Large codebases (500+ files) automatically skip heavy dependency
60
98
  analysis for performance. Use --depth=deep to force full analysis.
@@ -66,6 +104,9 @@ ${utils.COLORS.bold}Examples:${utils.COLORS.reset}
66
104
  bootspring analyze status
67
105
  bootspring analyze watch Continuous file watching
68
106
  bootspring analyze drift Check documentation alignment
107
+ bootspring analyze deep Deep architecture analysis
108
+ bootspring analyze security Security posture analysis
109
+ bootspring analyze semantic Document semantic analysis
69
110
  `);
70
111
  }
71
112
 
@@ -626,6 +667,268 @@ async function analyzeDrift() {
626
667
  }
627
668
  }
628
669
 
670
+ /**
671
+ * Run deep architecture analysis
672
+ */
673
+ async function analyzeDeepArchitecture(args) {
674
+ const Analyzer = getDeepArchitectureAnalyzer();
675
+ const analyzer = new Analyzer(projectRoot);
676
+
677
+ utils.print.header('Deep Architecture Analysis');
678
+ console.log('');
679
+
680
+ const spinner = utils.createSpinner('Analyzing architecture in depth...').start();
681
+
682
+ try {
683
+ const result = await analyzer.analyze();
684
+
685
+ spinner.succeed('Deep architecture analysis complete');
686
+ console.log('');
687
+
688
+ if (args.json) {
689
+ console.log(JSON.stringify(result, null, 2));
690
+ return;
691
+ }
692
+
693
+ // Display results
694
+ if (result.structure) {
695
+ console.log(`${utils.COLORS.cyan}Structure:${utils.COLORS.reset}`);
696
+ console.log(` Layers: ${result.structure.layers?.length || 0}`);
697
+ console.log(` Modules: ${result.structure.modules?.length || 0}`);
698
+ console.log(` Entry Points: ${result.structure.entryPoints?.length || 0}`);
699
+ console.log('');
700
+ }
701
+
702
+ if (result.dataFlow) {
703
+ console.log(`${utils.COLORS.cyan}Data Flow:${utils.COLORS.reset}`);
704
+ console.log(` Sources: ${result.dataFlow.sources?.length || 0}`);
705
+ console.log(` Processors: ${result.dataFlow.processors?.length || 0}`);
706
+ console.log(` Outputs: ${result.dataFlow.outputs?.length || 0}`);
707
+ console.log('');
708
+ }
709
+
710
+ if (result.dependencies) {
711
+ console.log(`${utils.COLORS.cyan}Dependencies:${utils.COLORS.reset}`);
712
+ console.log(` External: ${result.dependencies.external?.length || 0}`);
713
+ console.log(` Internal: ${result.dependencies.internal?.length || 0}`);
714
+ if (result.dependencies.circular?.length > 0) {
715
+ console.log(` ${utils.COLORS.yellow}Circular: ${result.dependencies.circular.length}${utils.COLORS.reset}`);
716
+ }
717
+ console.log('');
718
+ }
719
+
720
+ if (result.quality) {
721
+ console.log(`${utils.COLORS.cyan}Quality Indicators:${utils.COLORS.reset}`);
722
+ console.log(` Modularity: ${result.quality.modularity || 'N/A'}`);
723
+ console.log(` Coupling: ${result.quality.coupling || 'N/A'}`);
724
+ console.log(` Cohesion: ${result.quality.cohesion || 'N/A'}`);
725
+ console.log('');
726
+ }
727
+
728
+ if (result.recommendations?.length > 0) {
729
+ console.log(`${utils.COLORS.cyan}Recommendations:${utils.COLORS.reset}`);
730
+ for (const rec of result.recommendations.slice(0, 5)) {
731
+ console.log(` ${utils.COLORS.yellow}→${utils.COLORS.reset} ${rec.message || rec}`);
732
+ }
733
+ }
734
+
735
+ } catch (error) {
736
+ spinner.fail(`Analysis failed: ${error.message}`);
737
+ }
738
+ }
739
+
740
+ /**
741
+ * Run continuous security analysis
742
+ */
743
+ async function analyzeSecurityContinuous(args) {
744
+ const Analyzer = getContinuousSecurityAnalyzer();
745
+ const analyzer = new Analyzer(projectRoot);
746
+
747
+ utils.print.header('Continuous Security Analysis');
748
+ console.log('');
749
+
750
+ const spinner = utils.createSpinner('Analyzing security posture...').start();
751
+
752
+ try {
753
+ const result = await analyzer.analyze();
754
+
755
+ spinner.succeed('Security analysis complete');
756
+ console.log('');
757
+
758
+ if (args.json) {
759
+ console.log(JSON.stringify(result, null, 2));
760
+ return;
761
+ }
762
+
763
+ // Risk score
764
+ const scoreColor = result.riskScore < 30 ? utils.COLORS.green :
765
+ result.riskScore < 60 ? utils.COLORS.yellow :
766
+ utils.COLORS.red;
767
+ console.log(`Risk Score: ${scoreColor}${result.riskScore || 0}${utils.COLORS.reset}/100`);
768
+ console.log('');
769
+
770
+ // Authentication
771
+ if (result.authentication) {
772
+ console.log(`${utils.COLORS.cyan}Authentication:${utils.COLORS.reset}`);
773
+ console.log(` Mechanisms: ${result.authentication.mechanisms?.join(', ') || 'None detected'}`);
774
+ console.log(` Issues: ${result.authentication.issues?.length || 0}`);
775
+ console.log('');
776
+ }
777
+
778
+ // Authorization
779
+ if (result.authorization) {
780
+ console.log(`${utils.COLORS.cyan}Authorization:${utils.COLORS.reset}`);
781
+ console.log(` Patterns: ${result.authorization.patterns?.join(', ') || 'None detected'}`);
782
+ console.log(` Issues: ${result.authorization.issues?.length || 0}`);
783
+ console.log('');
784
+ }
785
+
786
+ // Data Protection
787
+ if (result.dataProtection) {
788
+ console.log(`${utils.COLORS.cyan}Data Protection:${utils.COLORS.reset}`);
789
+ console.log(` Encryption: ${result.dataProtection.encryption ? 'Detected' : 'Not detected'}`);
790
+ console.log(` PII Handling: ${result.dataProtection.piiDetected ? 'Detected' : 'Not detected'}`);
791
+ console.log('');
792
+ }
793
+
794
+ // Compliance
795
+ if (result.compliance) {
796
+ console.log(`${utils.COLORS.cyan}Compliance:${utils.COLORS.reset}`);
797
+ for (const [standard, status] of Object.entries(result.compliance)) {
798
+ const icon = status.compliant ? `${utils.COLORS.green}✓${utils.COLORS.reset}` : `${utils.COLORS.yellow}○${utils.COLORS.reset}`;
799
+ console.log(` ${icon} ${standard}: ${status.compliant ? 'Compliant' : 'Needs review'}`);
800
+ }
801
+ console.log('');
802
+ }
803
+
804
+ // Recommendations
805
+ if (result.recommendations?.length > 0) {
806
+ console.log(`${utils.COLORS.cyan}Recommendations:${utils.COLORS.reset}`);
807
+ for (const rec of result.recommendations.slice(0, 5)) {
808
+ const priority = rec.priority || 'medium';
809
+ const icon = priority === 'high' ? `${utils.COLORS.red}!${utils.COLORS.reset}` :
810
+ priority === 'medium' ? `${utils.COLORS.yellow}→${utils.COLORS.reset}` :
811
+ `${utils.COLORS.dim}○${utils.COLORS.reset}`;
812
+ console.log(` ${icon} ${rec.message || rec}`);
813
+ }
814
+ }
815
+
816
+ } catch (error) {
817
+ spinner.fail(`Analysis failed: ${error.message}`);
818
+ }
819
+ }
820
+
821
+ /**
822
+ * Run semantic document analysis
823
+ */
824
+ async function analyzeSemanticDocuments(args) {
825
+ const Analyzer = getSemanticDocumentAnalyzer();
826
+ const analyzer = new Analyzer();
827
+
828
+ utils.print.header('Semantic Document Analysis');
829
+ console.log('');
830
+
831
+ // Collect documents to analyze
832
+ const fs = require('fs');
833
+ const documents = [];
834
+
835
+ const docFiles = [
836
+ path.join(projectRoot, 'CLAUDE.md'),
837
+ path.join(projectRoot, 'README.md'),
838
+ path.join(projectRoot, 'docs', 'README.md'),
839
+ path.join(projectRoot, 'docs', 'architecture.md'),
840
+ path.join(projectRoot, 'docs', 'api.md')
841
+ ];
842
+
843
+ for (const file of docFiles) {
844
+ if (fs.existsSync(file)) {
845
+ const content = fs.readFileSync(file, 'utf-8');
846
+ documents.push({
847
+ path: file,
848
+ name: path.basename(file),
849
+ content
850
+ });
851
+ }
852
+ }
853
+
854
+ if (documents.length === 0) {
855
+ utils.print.warn('No documentation files found to analyze');
856
+ return;
857
+ }
858
+
859
+ const spinner = utils.createSpinner(`Analyzing ${documents.length} documents...`).start();
860
+
861
+ try {
862
+ const result = await analyzer.analyze(documents);
863
+
864
+ spinner.succeed('Semantic analysis complete');
865
+ console.log('');
866
+
867
+ if (args.json) {
868
+ console.log(JSON.stringify(result, null, 2));
869
+ return;
870
+ }
871
+
872
+ // Concepts
873
+ if (result.concepts) {
874
+ console.log(`${utils.COLORS.cyan}Concepts Extracted:${utils.COLORS.reset}`);
875
+ const topConcepts = Object.entries(result.concepts)
876
+ .sort((a, b) => b[1].frequency - a[1].frequency)
877
+ .slice(0, 10);
878
+ for (const [concept, data] of topConcepts) {
879
+ console.log(` ${concept}: ${data.frequency} occurrences`);
880
+ }
881
+ console.log('');
882
+ }
883
+
884
+ // Terminology
885
+ if (result.terminology) {
886
+ console.log(`${utils.COLORS.cyan}Terminology:${utils.COLORS.reset}`);
887
+ console.log(` Unique terms: ${result.terminology.uniqueTerms || 0}`);
888
+ console.log(` Technical density: ${result.terminology.technicalDensity || 'N/A'}`);
889
+ if (result.terminology.inconsistencies?.length > 0) {
890
+ console.log(` ${utils.COLORS.yellow}Inconsistencies: ${result.terminology.inconsistencies.length}${utils.COLORS.reset}`);
891
+ }
892
+ console.log('');
893
+ }
894
+
895
+ // Contradictions
896
+ if (result.contradictions?.length > 0) {
897
+ console.log(`${utils.COLORS.cyan}Potential Contradictions:${utils.COLORS.reset}`);
898
+ for (const contradiction of result.contradictions.slice(0, 3)) {
899
+ console.log(` ${utils.COLORS.yellow}!${utils.COLORS.reset} ${contradiction.description || contradiction}`);
900
+ }
901
+ console.log('');
902
+ }
903
+
904
+ // Specificity
905
+ if (result.specificity) {
906
+ console.log(`${utils.COLORS.cyan}Specificity:${utils.COLORS.reset}`);
907
+ console.log(` Overall: ${result.specificity.overall || 'N/A'}`);
908
+ console.log(` Vague sections: ${result.specificity.vagueSections?.length || 0}`);
909
+ console.log('');
910
+ }
911
+
912
+ // Gaps
913
+ if (result.gaps?.length > 0) {
914
+ console.log(`${utils.COLORS.cyan}Documentation Gaps:${utils.COLORS.reset}`);
915
+ for (const gap of result.gaps.slice(0, 5)) {
916
+ console.log(` ${utils.COLORS.yellow}○${utils.COLORS.reset} ${gap.description || gap}`);
917
+ }
918
+ }
919
+
920
+ // Summary
921
+ if (result.summary) {
922
+ console.log('');
923
+ console.log(`${utils.COLORS.cyan}Summary:${utils.COLORS.reset}`);
924
+ console.log(` ${result.summary.overview || 'Analysis complete'}`);
925
+ }
926
+
927
+ } catch (error) {
928
+ spinner.fail(`Analysis failed: ${error.message}`);
929
+ }
930
+ }
931
+
629
932
  /**
630
933
  * Main entry point
631
934
  */
@@ -659,6 +962,15 @@ async function run(args) {
659
962
  case 'drift':
660
963
  return analyzeDrift();
661
964
 
965
+ case 'deep':
966
+ return analyzeDeepArchitecture(parsedArgs);
967
+
968
+ case 'security':
969
+ return analyzeSecurityContinuous(parsedArgs);
970
+
971
+ case 'semantic':
972
+ return analyzeSemanticDocuments(parsedArgs);
973
+
662
974
  case 'help':
663
975
  case '--help':
664
976
  case '-h':
package/cli/generate.js CHANGED
@@ -7,12 +7,25 @@
7
7
  */
8
8
 
9
9
  const path = require('path');
10
+ const fs = require('fs');
10
11
  const config = require('../core/config');
11
12
  const context = require('../core/context');
12
13
  const utils = require('../core/utils');
13
14
  const gitMemory = require('../intelligence/git-memory');
14
15
  const agentsTemplate = require('../generators/templates/agents.template');
15
16
 
17
+ // Lazy load Phase 3 module
18
+ let ModelContextOptimizer = null;
19
+ let listSupportedModels = null;
20
+ function getModelContextOptimizer() {
21
+ if (!ModelContextOptimizer) {
22
+ const module = require('../intelligence/model-context-optimizer');
23
+ ModelContextOptimizer = module.ModelContextOptimizer;
24
+ listSupportedModels = module.listSupportedModels;
25
+ }
26
+ return { ModelContextOptimizer, listSupportedModels };
27
+ }
28
+
16
29
  /**
17
30
  * Generate CLAUDE.md content from config and project state
18
31
  */
@@ -186,6 +199,19 @@ ${cfg.customInstructions}
186
199
  */
187
200
  async function run(args) {
188
201
  const parsedArgs = utils.parseArgs(args);
202
+ const subcommand = parsedArgs._[0];
203
+
204
+ // Handle help
205
+ if (subcommand === 'help' || parsedArgs.help || parsedArgs.h) {
206
+ showHelp();
207
+ return;
208
+ }
209
+
210
+ // Handle multimodel subcommand
211
+ if (subcommand === 'multimodel' || subcommand === 'multi') {
212
+ return generateMultiModel(parsedArgs);
213
+ }
214
+
189
215
  const full = parsedArgs.full || parsedArgs.f;
190
216
 
191
217
  console.log(`
@@ -303,4 +329,159 @@ ${utils.COLORS.dim}Tip: Run 'bootspring generate --full' to regenerate all files
303
329
  `);
304
330
  }
305
331
 
306
- module.exports = { run, generateClaudeMd };
332
+ /**
333
+ * Generate multi-model context files
334
+ */
335
+ async function generateMultiModel(args) {
336
+ const { ModelContextOptimizer, listSupportedModels } = getModelContextOptimizer();
337
+
338
+ console.log(`
339
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Multi-Model Context Generation${utils.COLORS.reset}
340
+ ${utils.COLORS.dim}Generating optimized context for multiple AI models...${utils.COLORS.reset}
341
+ `);
342
+
343
+ const cfg = config.load();
344
+
345
+ if (!cfg._configPath) {
346
+ utils.print.error('No bootspring.config.js found');
347
+ utils.print.dim('Run "bootspring init" first to initialize your project');
348
+ return;
349
+ }
350
+
351
+ // Check for existing CLAUDE.md
352
+ const claudePath = path.join(cfg._projectRoot, 'CLAUDE.md');
353
+ if (!fs.existsSync(claudePath)) {
354
+ utils.print.error('CLAUDE.md not found');
355
+ utils.print.dim('Run "bootspring generate" first to create the base context');
356
+ return;
357
+ }
358
+
359
+ const sourceContent = fs.readFileSync(claudePath, 'utf-8');
360
+
361
+ // List models if requested
362
+ if (args.list) {
363
+ const models = listSupportedModels();
364
+ console.log(`${utils.COLORS.bold}Supported Models:${utils.COLORS.reset}\n`);
365
+ for (const model of models) {
366
+ console.log(` ${utils.COLORS.cyan}${model.family}${utils.COLORS.reset} (${model.provider})`);
367
+ console.log(` Variants: ${model.variants.join(', ')}`);
368
+ console.log(` Context file: ${model.contextFile}`);
369
+ console.log('');
370
+ }
371
+ return;
372
+ }
373
+
374
+ // Determine which models to generate for
375
+ let targetModels = ['claude', 'openai', 'gemini'];
376
+ if (args.models) {
377
+ targetModels = args.models.split(',').map(m => m.trim().toLowerCase());
378
+ }
379
+
380
+ // Compare across models
381
+ if (args.compare) {
382
+ const optimizer = new ModelContextOptimizer({ projectRoot: cfg._projectRoot });
383
+ const comparison = optimizer.compareAcrossModels(sourceContent);
384
+
385
+ console.log(`${utils.COLORS.bold}Context Comparison Across Models:${utils.COLORS.reset}\n`);
386
+ console.log(`Source tokens: ~${optimizer.estimateTokens(sourceContent).toLocaleString()}\n`);
387
+
388
+ for (const result of comparison) {
389
+ const statusIcon = result.fitsWithinBudget
390
+ ? `${utils.COLORS.green}✓${utils.COLORS.reset}`
391
+ : `${utils.COLORS.yellow}⚠${utils.COLORS.reset}`;
392
+
393
+ console.log(` ${statusIcon} ${result.model} (${result.variant})`);
394
+ console.log(` ${utils.COLORS.dim}Context window: ${result.contextWindow.toLocaleString()} tokens${utils.COLORS.reset}`);
395
+ console.log(` ${utils.COLORS.dim}Utilization: ${result.utilizationPercent}%${utils.COLORS.reset}`);
396
+ }
397
+ console.log('');
398
+ return;
399
+ }
400
+
401
+ // Generate context files
402
+ const generated = [];
403
+
404
+ for (const model of targetModels) {
405
+ try {
406
+ const optimizer = new ModelContextOptimizer({
407
+ projectRoot: cfg._projectRoot,
408
+ model
409
+ });
410
+
411
+ const spinner = utils.createSpinner(`Generating ${optimizer.config.contextFile}`).start();
412
+
413
+ const result = optimizer.generateContextFile(sourceContent);
414
+
415
+ // Write the file
416
+ fs.writeFileSync(result.filepath, result.content, 'utf-8');
417
+
418
+ const savings = result.optimization.originalTokens - result.optimization.optimizedTokens;
419
+ const savingsPercent = Math.round((savings / result.optimization.originalTokens) * 100);
420
+
421
+ spinner.succeed(`Generated ${result.filename}`);
422
+
423
+ if (result.optimization.sectionsDropped > 0) {
424
+ console.log(` ${utils.COLORS.dim}Optimized: ${result.optimization.optimizedTokens.toLocaleString()} tokens (${savingsPercent}% reduction)${utils.COLORS.reset}`);
425
+ console.log(` ${utils.COLORS.dim}Dropped ${result.optimization.sectionsDropped} low-priority sections${utils.COLORS.reset}`);
426
+ }
427
+
428
+ generated.push({
429
+ model,
430
+ filename: result.filename,
431
+ tokens: result.optimization.optimizedTokens
432
+ });
433
+
434
+ } catch (error) {
435
+ utils.print.error(`Failed to generate for ${model}: ${error.message}`);
436
+ }
437
+ }
438
+
439
+ if (generated.length > 0) {
440
+ console.log(`
441
+ ${utils.COLORS.bold}Summary:${utils.COLORS.reset}
442
+ Generated ${generated.length} context file(s):
443
+ ${generated.map(g => ` ${utils.COLORS.green}✓${utils.COLORS.reset} ${g.filename} (~${g.tokens.toLocaleString()} tokens)`).join('\n')}
444
+
445
+ ${utils.COLORS.dim}These files are optimized for each AI model's context window and formatting preferences.${utils.COLORS.reset}
446
+ `);
447
+ }
448
+ }
449
+
450
+ /**
451
+ * Show help
452
+ */
453
+ function showHelp() {
454
+ console.log(`
455
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Generate${utils.COLORS.reset}
456
+ ${utils.COLORS.dim}Generate AI context files${utils.COLORS.reset}
457
+
458
+ ${utils.COLORS.bold}Usage:${utils.COLORS.reset}
459
+ bootspring generate Generate CLAUDE.md
460
+ bootspring generate --full Generate all context files
461
+ bootspring generate multimodel Generate for multiple AI models
462
+ bootspring generate multimodel --list List supported models
463
+ bootspring generate multimodel --compare Compare context across models
464
+
465
+ ${utils.COLORS.bold}Options:${utils.COLORS.reset}
466
+ --full, -f Generate all files (CLAUDE.md, AGENTS.md, .mcp.json)
467
+ --models <list> Comma-separated list of models (default: claude,openai,gemini)
468
+ --list List all supported AI models
469
+ --compare Compare context requirements across models
470
+
471
+ ${utils.COLORS.bold}Supported Models:${utils.COLORS.reset}
472
+ claude Claude (Anthropic) - CLAUDE.md
473
+ openai GPT (OpenAI) - OPENAI.md
474
+ gemini Gemini (Google) - GEMINI.md
475
+ mistral Mistral (Mistral AI) - MISTRAL.md
476
+ llama Llama (Meta) - LLAMA.md
477
+
478
+ ${utils.COLORS.bold}Examples:${utils.COLORS.reset}
479
+ bootspring generate # Generate CLAUDE.md
480
+ bootspring generate --full # Generate all files
481
+ bootspring generate multimodel # Generate for all default models
482
+ bootspring generate multimodel --models claude,openai
483
+ bootspring generate multimodel --compare
484
+ `);
485
+ }
486
+
487
+ module.exports = { run, generateClaudeMd, generateMultiModel };