@girardmedia/bootspring 1.1.0

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.
Files changed (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -0
  3. package/agents/README.md +93 -0
  4. package/agents/api-expert/context.md +416 -0
  5. package/agents/architecture-expert/context.md +454 -0
  6. package/agents/backend-expert/context.md +483 -0
  7. package/agents/code-review-expert/context.md +365 -0
  8. package/agents/database-expert/context.md +250 -0
  9. package/agents/devops-expert/context.md +446 -0
  10. package/agents/frontend-expert/context.md +364 -0
  11. package/agents/index.js +140 -0
  12. package/agents/performance-expert/context.md +377 -0
  13. package/agents/security-expert/context.md +343 -0
  14. package/agents/testing-expert/context.md +414 -0
  15. package/agents/ui-ux-expert/context.md +448 -0
  16. package/agents/vercel-expert/context.md +426 -0
  17. package/bin/bootspring.js +310 -0
  18. package/cli/agent.js +337 -0
  19. package/cli/context.js +194 -0
  20. package/cli/dashboard.js +150 -0
  21. package/cli/generate.js +294 -0
  22. package/cli/init.js +410 -0
  23. package/cli/loop.js +421 -0
  24. package/cli/mcp.js +241 -0
  25. package/cli/memory.js +303 -0
  26. package/cli/orchestrator.js +400 -0
  27. package/cli/plugin.js +451 -0
  28. package/cli/quality.js +332 -0
  29. package/cli/skill.js +369 -0
  30. package/cli/task.js +628 -0
  31. package/cli/telemetry.js +114 -0
  32. package/cli/todo.js +614 -0
  33. package/cli/update.js +312 -0
  34. package/core/config.js +245 -0
  35. package/core/context.js +329 -0
  36. package/core/entitlements.js +209 -0
  37. package/core/index.js +43 -0
  38. package/core/policies.js +68 -0
  39. package/core/telemetry.js +247 -0
  40. package/core/utils.js +380 -0
  41. package/dashboard/server.js +818 -0
  42. package/docs/integrations/claude-code.md +42 -0
  43. package/docs/integrations/codex.md +42 -0
  44. package/docs/mcp-api-platform.md +102 -0
  45. package/generators/generate.js +598 -0
  46. package/generators/index.js +18 -0
  47. package/hooks/context-detector.js +177 -0
  48. package/hooks/index.js +35 -0
  49. package/hooks/prompt-enhancer.js +289 -0
  50. package/intelligence/git-memory.js +551 -0
  51. package/intelligence/index.js +59 -0
  52. package/intelligence/orchestrator.js +964 -0
  53. package/intelligence/prd.js +447 -0
  54. package/intelligence/recommendation-weights.json +18 -0
  55. package/intelligence/recommendations.js +234 -0
  56. package/mcp/capabilities.js +71 -0
  57. package/mcp/contracts/mcp-contract.v1.json +497 -0
  58. package/mcp/registry.js +213 -0
  59. package/mcp/response-formatter.js +462 -0
  60. package/mcp/server.js +99 -0
  61. package/mcp/tools/agent-tool.js +137 -0
  62. package/mcp/tools/capabilities-tool.js +54 -0
  63. package/mcp/tools/context-tool.js +49 -0
  64. package/mcp/tools/dashboard-tool.js +58 -0
  65. package/mcp/tools/generate-tool.js +46 -0
  66. package/mcp/tools/loop-tool.js +134 -0
  67. package/mcp/tools/memory-tool.js +180 -0
  68. package/mcp/tools/orchestrator-tool.js +232 -0
  69. package/mcp/tools/plugin-tool.js +76 -0
  70. package/mcp/tools/quality-tool.js +47 -0
  71. package/mcp/tools/skill-tool.js +233 -0
  72. package/mcp/tools/telemetry-tool.js +95 -0
  73. package/mcp/tools/todo-tool.js +133 -0
  74. package/package.json +98 -0
  75. package/plugins/index.js +141 -0
  76. package/quality/index.js +380 -0
  77. package/quality/lint-budgets.json +19 -0
  78. package/skills/index.js +787 -0
  79. package/skills/patterns/README.md +163 -0
  80. package/skills/patterns/api/route-handler.md +217 -0
  81. package/skills/patterns/api/server-action.md +249 -0
  82. package/skills/patterns/auth/clerk.md +132 -0
  83. package/skills/patterns/database/prisma.md +180 -0
  84. package/skills/patterns/payments/stripe.md +272 -0
  85. package/skills/patterns/security/validation.md +268 -0
  86. package/skills/patterns/testing/vitest.md +307 -0
  87. package/templates/bootspring.config.js +83 -0
  88. package/templates/mcp.json +9 -0
@@ -0,0 +1,598 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Bootspring Context Generator
5
+ *
6
+ * Generates all context files from project configuration.
7
+ * Includes MVP source code analysis for enhanced context.
8
+ *
9
+ * @package bootspring
10
+ * @module generators/generate
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+
16
+ // Try to load yaml package, fall back to simple parser
17
+ let yaml;
18
+ try {
19
+ yaml = require('yaml');
20
+ } catch (e) {
21
+ yaml = null;
22
+ }
23
+
24
+ // Colors
25
+ const c = {
26
+ reset: '\x1b[0m',
27
+ bold: '\x1b[1m',
28
+ dim: '\x1b[2m',
29
+ green: '\x1b[32m',
30
+ blue: '\x1b[34m',
31
+ yellow: '\x1b[33m',
32
+ cyan: '\x1b[36m',
33
+ red: '\x1b[31m'
34
+ };
35
+
36
+ /**
37
+ * Simple YAML parser fallback
38
+ * Handles basic key: value pairs and arrays
39
+ */
40
+ function parseYamlSimple(content) {
41
+ const result = {};
42
+ const lines = content.split('\n');
43
+ let currentKey = null;
44
+ let currentIndent = 0;
45
+
46
+ for (let line of lines) {
47
+ // Skip comments and empty lines
48
+ if (line.trim().startsWith('#') || !line.trim()) continue;
49
+
50
+ const indent = line.search(/\S/);
51
+ const trimmed = line.trim();
52
+
53
+ // Array item
54
+ if (trimmed.startsWith('- ')) {
55
+ const value = trimmed.substring(2).trim();
56
+ if (currentKey && Array.isArray(result[currentKey])) {
57
+ result[currentKey].push(value);
58
+ }
59
+ continue;
60
+ }
61
+
62
+ // Key: value pair
63
+ const colonIndex = trimmed.indexOf(':');
64
+ if (colonIndex > 0) {
65
+ const key = trimmed.substring(0, colonIndex).trim();
66
+ const value = trimmed.substring(colonIndex + 1).trim();
67
+
68
+ if (value === '' || value === '|' || value === '>') {
69
+ // Start of object or multiline
70
+ result[key] = [];
71
+ currentKey = key;
72
+ currentIndent = indent;
73
+ } else {
74
+ // Simple value
75
+ let parsedValue = value;
76
+ if (value === 'true') parsedValue = true;
77
+ else if (value === 'false') parsedValue = false;
78
+ else if (!isNaN(value) && value !== '') parsedValue = Number(value);
79
+ else if (value.startsWith('"') && value.endsWith('"')) {
80
+ parsedValue = value.slice(1, -1);
81
+ }
82
+ result[key] = parsedValue;
83
+ currentKey = null;
84
+ }
85
+ }
86
+ }
87
+
88
+ return result;
89
+ }
90
+
91
+ /**
92
+ * Analyze MVP source files
93
+ * @param {string} mvpPath - Path to MVP source directory
94
+ * @returns {object} MVP analysis results
95
+ */
96
+ function analyzeMvpSource(mvpPath) {
97
+ if (!fs.existsSync(mvpPath)) {
98
+ return null;
99
+ }
100
+
101
+ const mvpInfo = {
102
+ exists: true,
103
+ files: [],
104
+ components: [],
105
+ services: [],
106
+ utilities: [],
107
+ hooks: [],
108
+ pages: [],
109
+ patterns: [],
110
+ stats: {
111
+ totalFiles: 0,
112
+ totalLines: 0,
113
+ fileTypes: {}
114
+ }
115
+ };
116
+
117
+ /**
118
+ * Recursively scan directory
119
+ */
120
+ function scanDir(dir, files = []) {
121
+ if (!fs.existsSync(dir)) return files;
122
+
123
+ const items = fs.readdirSync(dir, { withFileTypes: true });
124
+
125
+ for (const item of items) {
126
+ const fullPath = path.join(dir, item.name);
127
+ const relativePath = path.relative(mvpPath, fullPath);
128
+
129
+ // Skip common ignore patterns
130
+ if (['node_modules', '.next', 'dist', '.git', 'coverage', '.turbo'].some(p =>
131
+ relativePath.includes(p)
132
+ )) continue;
133
+
134
+ if (item.isDirectory()) {
135
+ scanDir(fullPath, files);
136
+ } else {
137
+ const ext = path.extname(item.name);
138
+ if (['.ts', '.tsx', '.js', '.jsx', '.mjs'].includes(ext)) {
139
+ files.push({
140
+ name: item.name,
141
+ path: relativePath,
142
+ fullPath,
143
+ ext
144
+ });
145
+ }
146
+ }
147
+ }
148
+ return files;
149
+ }
150
+
151
+ mvpInfo.files = scanDir(mvpPath);
152
+ mvpInfo.stats.totalFiles = mvpInfo.files.length;
153
+
154
+ // Analyze each file
155
+ for (const file of mvpInfo.files) {
156
+ try {
157
+ const content = fs.readFileSync(file.fullPath, 'utf8');
158
+ const lines = content.split('\n').length;
159
+ mvpInfo.stats.totalLines += lines;
160
+
161
+ // Track file types
162
+ mvpInfo.stats.fileTypes[file.ext] = (mvpInfo.stats.fileTypes[file.ext] || 0) + 1;
163
+
164
+ // Categorize by path and content
165
+ const pathLower = file.path.toLowerCase();
166
+ const contentLower = content.toLowerCase();
167
+
168
+ // Components
169
+ if (pathLower.includes('component') ||
170
+ (file.ext === '.tsx' && content.match(/^(export\s+)?(default\s+)?function\s+[A-Z]/m))) {
171
+ mvpInfo.components.push(file.path);
172
+ }
173
+
174
+ // Services / API
175
+ if (pathLower.includes('service') || pathLower.includes('api/')) {
176
+ mvpInfo.services.push(file.path);
177
+ }
178
+
179
+ // Utilities / Lib
180
+ if (pathLower.includes('util') || pathLower.includes('lib/') || pathLower.includes('helper')) {
181
+ mvpInfo.utilities.push(file.path);
182
+ }
183
+
184
+ // Hooks
185
+ if (pathLower.includes('hook') || content.match(/^export\s+(const|function)\s+use[A-Z]/m)) {
186
+ mvpInfo.hooks.push(file.path);
187
+ }
188
+
189
+ // Pages / App routes
190
+ if (pathLower.includes('/app/') || pathLower.includes('/pages/')) {
191
+ mvpInfo.pages.push(file.path);
192
+ }
193
+
194
+ // Detect patterns used
195
+ if (content.includes('async ') && content.includes('try') && content.includes('catch')) {
196
+ if (!mvpInfo.patterns.includes('error-handling')) {
197
+ mvpInfo.patterns.push('error-handling');
198
+ }
199
+ }
200
+ if (content.includes('useState') || content.includes('useEffect')) {
201
+ if (!mvpInfo.patterns.includes('react-hooks')) {
202
+ mvpInfo.patterns.push('react-hooks');
203
+ }
204
+ }
205
+ if (content.includes('fetch(') || content.includes('axios')) {
206
+ if (!mvpInfo.patterns.includes('api-calls')) {
207
+ mvpInfo.patterns.push('api-calls');
208
+ }
209
+ }
210
+ if (contentLower.includes('prisma')) {
211
+ if (!mvpInfo.patterns.includes('prisma-orm')) {
212
+ mvpInfo.patterns.push('prisma-orm');
213
+ }
214
+ }
215
+ if (content.includes('zod') || content.includes('.parse(')) {
216
+ if (!mvpInfo.patterns.includes('validation')) {
217
+ mvpInfo.patterns.push('validation');
218
+ }
219
+ }
220
+ if (contentLower.includes('clerk') || contentLower.includes('auth(')) {
221
+ if (!mvpInfo.patterns.includes('authentication')) {
222
+ mvpInfo.patterns.push('authentication');
223
+ }
224
+ }
225
+ if (content.includes('stripe')) {
226
+ if (!mvpInfo.patterns.includes('payments')) {
227
+ mvpInfo.patterns.push('payments');
228
+ }
229
+ }
230
+ if (content.includes('Server') && (content.includes("'use server'") || content.includes('"use server"'))) {
231
+ if (!mvpInfo.patterns.includes('server-actions')) {
232
+ mvpInfo.patterns.push('server-actions');
233
+ }
234
+ }
235
+
236
+ } catch (e) {
237
+ // Skip files that can't be read
238
+ }
239
+ }
240
+
241
+ return mvpInfo;
242
+ }
243
+
244
+ /**
245
+ * Parse bootspring.config.js or SEED.md
246
+ * @param {string} projectRoot - Project root directory
247
+ * @returns {object} Parsed configuration
248
+ */
249
+ function parseConfig(projectRoot) {
250
+ // Try bootspring.config.js first
251
+ const configPath = path.join(projectRoot, 'bootspring.config.js');
252
+ if (fs.existsSync(configPath)) {
253
+ try {
254
+ delete require.cache[require.resolve(configPath)];
255
+ return require(configPath);
256
+ } catch (e) {
257
+ console.warn(`${c.yellow}Warning: Could not load bootspring.config.js${c.reset}`);
258
+ }
259
+ }
260
+
261
+ // Try SEED.md (for backward compatibility)
262
+ const seedPath = path.join(projectRoot, '.bootspring', 'SEED.md');
263
+ if (fs.existsSync(seedPath)) {
264
+ return parseSeedMd(seedPath);
265
+ }
266
+
267
+ // Try .girardai/SEED.md
268
+ const girardaiSeedPath = path.join(projectRoot, '.girardai', 'SEED.md');
269
+ if (fs.existsSync(girardaiSeedPath)) {
270
+ return parseSeedMd(girardaiSeedPath);
271
+ }
272
+
273
+ // Return default config
274
+ return {
275
+ project: { name: 'My Project', description: '' },
276
+ stack: { framework: 'nextjs', language: 'typescript' },
277
+ plugins: {}
278
+ };
279
+ }
280
+
281
+ /**
282
+ * Parse SEED.md and extract YAML blocks
283
+ * @param {string} seedPath - Path to SEED.md
284
+ * @returns {object} Parsed configuration
285
+ */
286
+ function parseSeedMd(seedPath) {
287
+ const content = fs.readFileSync(seedPath, 'utf8');
288
+ const config = {};
289
+
290
+ // Extract all YAML code blocks
291
+ const yamlBlockRegex = /```yaml\n([\s\S]*?)```/g;
292
+ let match;
293
+
294
+ while ((match = yamlBlockRegex.exec(content)) !== null) {
295
+ try {
296
+ const parsed = yaml ? yaml.parse(match[1]) : parseYamlSimple(match[1]);
297
+ Object.assign(config, parsed);
298
+ } catch (e) {
299
+ // Skip invalid YAML blocks
300
+ }
301
+ }
302
+
303
+ return config;
304
+ }
305
+
306
+ /**
307
+ * Generate MVP section for CLAUDE.md
308
+ * @param {object} mvpInfo - MVP analysis results
309
+ * @returns {string} Markdown section
310
+ */
311
+ function generateMvpSection(mvpInfo) {
312
+ if (!mvpInfo || mvpInfo.files.length === 0) {
313
+ return '';
314
+ }
315
+
316
+ return `
317
+ ---
318
+
319
+ ## MVP Reference Code
320
+
321
+ **IMPORTANT**: This project has MVP prototype code. Before implementing features, check the MVP for existing patterns.
322
+
323
+ ### MVP Statistics
324
+
325
+ | Metric | Count |
326
+ |--------|-------|
327
+ | Total Files | ${mvpInfo.stats.totalFiles} |
328
+ | Total Lines | ${mvpInfo.stats.totalLines.toLocaleString()} |
329
+ | Components | ${mvpInfo.components.length} |
330
+ | Services/API | ${mvpInfo.services.length} |
331
+ | Utilities | ${mvpInfo.utilities.length} |
332
+ | Hooks | ${mvpInfo.hooks.length} |
333
+ | Pages | ${mvpInfo.pages.length} |
334
+
335
+ ### Detected Patterns
336
+
337
+ ${mvpInfo.patterns.length > 0 ? mvpInfo.patterns.map(p => `- ${p}`).join('\n') : '- No specific patterns detected'}
338
+
339
+ ### Key Files
340
+
341
+ **Components** (${Math.min(mvpInfo.components.length, 10)} of ${mvpInfo.components.length}):
342
+ ${mvpInfo.components.slice(0, 10).map(c => `- \`${c}\``).join('\n') || '- None detected'}
343
+ ${mvpInfo.components.length > 10 ? `- ... and ${mvpInfo.components.length - 10} more` : ''}
344
+
345
+ **Services** (${Math.min(mvpInfo.services.length, 5)} of ${mvpInfo.services.length}):
346
+ ${mvpInfo.services.slice(0, 5).map(s => `- \`${s}\``).join('\n') || '- None detected'}
347
+ ${mvpInfo.services.length > 5 ? `- ... and ${mvpInfo.services.length - 5} more` : ''}
348
+
349
+ ### Before Implementing Features
350
+
351
+ 1. **Check MVP first**: Look for existing implementations
352
+ 2. **Reuse patterns**: Follow the detected patterns above
353
+ 3. **Ask about MVP**: "Show me the MVP implementation of X"
354
+ `;
355
+ }
356
+
357
+ /**
358
+ * Generate full CLAUDE.md content
359
+ * @param {object} config - Project configuration
360
+ * @param {object} options - Generation options
361
+ * @returns {string} Generated content
362
+ */
363
+ function generateClaudeMd(config, options = {}) {
364
+ const date = new Date().toISOString().split('T')[0];
365
+
366
+ const project = config.project || {};
367
+ const stack = config.stack || {};
368
+ const plugins = config.plugins || {};
369
+
370
+ // Analyze MVP if exists
371
+ let mvpInfo = null;
372
+ if (options.withMvp || options.mvpPath) {
373
+ const mvpPath = options.mvpPath || path.join(options.projectRoot, 'mvp', 'source');
374
+ mvpInfo = analyzeMvpSource(mvpPath);
375
+ }
376
+
377
+ // Build enabled plugins section
378
+ const enabledPlugins = Object.entries(plugins)
379
+ .filter(([_, p]) => p && p.enabled !== false);
380
+
381
+ const pluginsSection = enabledPlugins.length > 0
382
+ ? enabledPlugins.map(([name, plugin]) => `### ${name.charAt(0).toUpperCase() + name.slice(1)}
383
+ - **Provider**: ${plugin.provider || 'default'}
384
+ - **Features**: ${(plugin.features || []).join(', ') || 'default'}`).join('\n\n')
385
+ : 'No plugins configured.';
386
+
387
+ // Generate content
388
+ const content = `# ${project.name || 'Project'} - AI Context
389
+
390
+ **Generated by**: Bootspring v1.0.0
391
+ **Last Updated**: ${date}
392
+ **Framework**: ${stack.framework || 'unknown'}
393
+
394
+ ---
395
+
396
+ ## Project Overview
397
+
398
+ ${project.description || 'A modern application built with Bootspring.'}
399
+
400
+ ---
401
+
402
+ ## Tech Stack
403
+
404
+ | Component | Technology |
405
+ |-----------|------------|
406
+ | Framework | ${stack.framework || 'N/A'} |
407
+ | Language | ${stack.language || 'typescript'} |
408
+ | Database | ${stack.database || 'N/A'} |
409
+ | Hosting | ${stack.hosting || 'N/A'} |
410
+
411
+ ---
412
+
413
+ ## Enabled Plugins
414
+
415
+ ${pluginsSection}
416
+
417
+ ---
418
+
419
+ ## Bootspring Commands
420
+
421
+ ### Quick Commands (use in AI assistant)
422
+
423
+ | Command | Description |
424
+ |---------|-------------|
425
+ | \`bootspring todo add "task"\` | Add a todo item |
426
+ | \`bootspring todo list\` | List all todos |
427
+ | \`bootspring todo done <id>\` | Mark todo complete |
428
+ | \`bootspring agent list\` | List available agents |
429
+ | \`bootspring agent invoke <name>\` | Get specialized help |
430
+ | \`bootspring skill search <query>\` | Find code patterns |
431
+ | \`bootspring dashboard\` | Start real-time dashboard |
432
+ | \`bootspring generate\` | Regenerate this context |
433
+ | \`bootspring quality pre-commit\` | Run quality checks |
434
+
435
+ ### Specialized Agents
436
+
437
+ | Agent | Expertise |
438
+ |-------|-----------|
439
+ | database-expert | Schema design, queries, migrations |
440
+ | security-expert | Security review, OWASP, auth |
441
+ | frontend-expert | UI components, React, CSS |
442
+ | backend-expert | API design, server logic |
443
+ | api-expert | REST/GraphQL, route handlers |
444
+ | testing-expert | Test strategy, coverage, TDD |
445
+ | performance-expert | Optimization, profiling |
446
+ | devops-expert | CI/CD, deployment |
447
+ | ui-ux-expert | Design patterns, accessibility |
448
+ | architecture-expert | System design, patterns |
449
+ | code-review-expert | Code quality, best practices |
450
+ | vercel-expert | Vercel deployment, edge functions |
451
+
452
+ **Invoke**: \`bootspring agent invoke <name>\`
453
+
454
+ ---
455
+
456
+ ## Development Guidelines
457
+
458
+ ### Code Style
459
+
460
+ - Use ${stack.language === 'typescript' ? 'TypeScript' : 'JavaScript'} for all new code
461
+ - Follow existing naming conventions
462
+ - Keep files under 300 lines when possible
463
+
464
+ ### Best Practices
465
+
466
+ - Use Server Components by default (if Next.js)
467
+ - Prefer Server Actions over API routes for mutations
468
+ - Use Zod for input validation
469
+ - Never expose API keys to client
470
+ - Write tests for new features
471
+
472
+ ### Git Commits
473
+
474
+ - Use conventional commit format: \`feat:\`, \`fix:\`, \`docs:\`, \`refactor:\`
475
+ - Keep commits focused and atomic
476
+ - Never commit sensitive data
477
+ - No AI/Claude references in commits
478
+
479
+ ---
480
+
481
+ ## Quality Gates
482
+
483
+ Run before commits:
484
+
485
+ \`\`\`bash
486
+ bootspring quality pre-commit
487
+ \`\`\`
488
+ ${generateMvpSection(mvpInfo)}
489
+ ---
490
+
491
+ *Generated by [Bootspring](https://bootspring.com)*
492
+ `;
493
+
494
+ return content;
495
+ }
496
+
497
+ /**
498
+ * Main generation function
499
+ * @param {object} options - Generation options
500
+ * @returns {object} Generation result
501
+ */
502
+ async function generate(options = {}) {
503
+ const projectRoot = options.projectRoot || process.cwd();
504
+ const outputPath = options.outputPath || path.join(projectRoot, 'CLAUDE.md');
505
+ const dryRun = options.dryRun || false;
506
+ const withMvp = options.withMvp || false;
507
+
508
+ // Parse config
509
+ const config = parseConfig(projectRoot);
510
+
511
+ // Generate content
512
+ const content = generateClaudeMd(config, {
513
+ projectRoot,
514
+ withMvp,
515
+ mvpPath: options.mvpPath
516
+ });
517
+
518
+ // Write or return
519
+ if (dryRun) {
520
+ return {
521
+ success: true,
522
+ dryRun: true,
523
+ content,
524
+ bytes: content.length
525
+ };
526
+ }
527
+
528
+ try {
529
+ fs.writeFileSync(outputPath, content, 'utf8');
530
+ return {
531
+ success: true,
532
+ outputPath,
533
+ bytes: content.length
534
+ };
535
+ } catch (error) {
536
+ return {
537
+ success: false,
538
+ error: error.message
539
+ };
540
+ }
541
+ }
542
+
543
+ // CLI execution
544
+ if (require.main === module) {
545
+ const args = process.argv.slice(2);
546
+ const options = {
547
+ dryRun: args.includes('--dry-run'),
548
+ withMvp: args.includes('--with-mvp'),
549
+ help: args.includes('--help') || args.includes('-h')
550
+ };
551
+
552
+ if (options.help) {
553
+ console.log(`
554
+ ${c.bold}Bootspring Context Generator${c.reset}
555
+
556
+ ${c.cyan}Usage:${c.reset}
557
+ node generate.js [options]
558
+
559
+ ${c.cyan}Options:${c.reset}
560
+ --with-mvp Include MVP source analysis
561
+ --dry-run Preview without writing files
562
+ --help, -h Show this help
563
+
564
+ ${c.cyan}Examples:${c.reset}
565
+ node generate.js
566
+ node generate.js --with-mvp
567
+ node generate.js --dry-run
568
+ `);
569
+ process.exit(0);
570
+ }
571
+
572
+ console.log(`
573
+ ${c.cyan}${c.bold}Bootspring Context Generator${c.reset}
574
+ ${c.dim}Generating AI context files...${c.reset}
575
+ `);
576
+
577
+ generate(options).then(result => {
578
+ if (result.success) {
579
+ if (result.dryRun) {
580
+ console.log(`${c.yellow}[DRY RUN]${c.reset} Would write ${result.bytes.toLocaleString()} bytes`);
581
+ } else {
582
+ console.log(`${c.green}*${c.reset} Generated ${result.outputPath}`);
583
+ console.log(`${c.dim} ${result.bytes.toLocaleString()} bytes${c.reset}`);
584
+ }
585
+ } else {
586
+ console.log(`${c.red}Error:${c.reset} ${result.error}`);
587
+ process.exit(1);
588
+ }
589
+ });
590
+ }
591
+
592
+ module.exports = {
593
+ generate,
594
+ generateClaudeMd,
595
+ analyzeMvpSource,
596
+ parseConfig,
597
+ parseSeedMd
598
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Bootspring Generators Module
3
+ *
4
+ * Provides context generation, scaffolding, and project setup.
5
+ *
6
+ * @package bootspring
7
+ * @module generators
8
+ */
9
+
10
+ const generator = require('./generate');
11
+
12
+ module.exports = {
13
+ generate: generator.generate,
14
+ generateClaudeMd: generator.generateClaudeMd,
15
+ analyzeMvpSource: generator.analyzeMvpSource,
16
+ parseConfig: generator.parseConfig,
17
+ parseSeedMd: generator.parseSeedMd
18
+ };