@girardmedia/bootspring 2.5.0 → 2.5.2

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 (59) hide show
  1. package/README.md +9 -403
  2. package/bin/bootspring.js +1 -96
  3. package/dist/cli/index.js +65134 -0
  4. package/dist/cli-launcher.js +92 -0
  5. package/dist/core/index.d.ts +2110 -5582
  6. package/dist/core/index.js +2 -0
  7. package/dist/core.js +21123 -5413
  8. package/dist/mcp/index.d.ts +357 -1
  9. package/dist/mcp/index.js +2 -0
  10. package/dist/mcp-server.js +51948 -1976
  11. package/package.json +27 -63
  12. package/scripts/postinstall.cjs +144 -0
  13. package/LICENSE +0 -29
  14. package/dist/cli/index.cjs +0 -20776
  15. package/generators/api-docs.js +0 -827
  16. package/generators/decisions.js +0 -655
  17. package/generators/generate.js +0 -595
  18. package/generators/health.js +0 -942
  19. package/generators/index.ts +0 -82
  20. package/generators/presets/full.js +0 -28
  21. package/generators/presets/index.js +0 -12
  22. package/generators/presets/minimal.js +0 -29
  23. package/generators/presets/standard.js +0 -28
  24. package/generators/questionnaire.js +0 -414
  25. package/generators/sections/advanced.js +0 -136
  26. package/generators/sections/ai.js +0 -106
  27. package/generators/sections/auth.js +0 -89
  28. package/generators/sections/backend.js +0 -146
  29. package/generators/sections/business.js +0 -118
  30. package/generators/sections/content.js +0 -300
  31. package/generators/sections/deployment.js +0 -139
  32. package/generators/sections/features.js +0 -122
  33. package/generators/sections/frontend.js +0 -118
  34. package/generators/sections/identity.js +0 -76
  35. package/generators/sections/index.js +0 -40
  36. package/generators/sections/instructions.js +0 -146
  37. package/generators/sections/payments.js +0 -104
  38. package/generators/sections/plugins.js +0 -142
  39. package/generators/sections/pre-build.js +0 -130
  40. package/generators/sections/security.js +0 -127
  41. package/generators/sections/technical.js +0 -171
  42. package/generators/sections/testing.js +0 -125
  43. package/generators/sections/workflow.js +0 -104
  44. package/generators/sprint.js +0 -675
  45. package/generators/templates/agents.template.js +0 -199
  46. package/generators/templates/assistant-context.template.js +0 -83
  47. package/generators/templates/build-planning.template.js +0 -708
  48. package/generators/templates/claude.template.js +0 -379
  49. package/generators/templates/content.template.js +0 -819
  50. package/generators/templates/index.js +0 -16
  51. package/generators/templates/planning.template.js +0 -515
  52. package/generators/templates/seed.template.js +0 -109
  53. package/generators/visual-doc-generator.js +0 -910
  54. package/scripts/postinstall.js +0 -197
  55. /package/{claude-commands → assets/claude-commands}/agent.md +0 -0
  56. /package/{claude-commands → assets/claude-commands}/bs.md +0 -0
  57. /package/{claude-commands → assets/claude-commands}/build.md +0 -0
  58. /package/{claude-commands → assets/claude-commands}/skill.md +0 -0
  59. /package/{claude-commands → assets/claude-commands}/todo.md +0 -0
@@ -1,136 +0,0 @@
1
- /**
2
- * Advanced Options Section
3
- *
4
- * Collects security, compliance, and infrastructure settings.
5
- * Only included in full preset.
6
- *
7
- * @package bootspring
8
- * @module generators/sections/advanced
9
- */
10
-
11
- const title = 'Advanced Options';
12
- const description = 'Security, compliance, and infrastructure';
13
-
14
- /**
15
- * Run the advanced section
16
- */
17
- async function run(rl, previousAnswers, helpers) {
18
- const { askChoice, askMultiSelect, askYesNo } = helpers;
19
-
20
- const answers = {};
21
-
22
- console.log('\nAdvanced configuration options');
23
-
24
- // Security level
25
- answers.securityLevel = await askChoice(
26
- rl,
27
- 'Security level:',
28
- [
29
- { label: 'Standard', value: 'standard', description: 'Good defaults for most apps' },
30
- { label: 'Enhanced', value: 'enhanced', description: 'Additional security measures' },
31
- { label: 'Enterprise', value: 'enterprise', description: 'Maximum security posture' }
32
- ],
33
- 0
34
- );
35
-
36
- // Compliance requirements
37
- const needsCompliance = await askYesNo(
38
- rl,
39
- 'Have compliance requirements (GDPR, SOC2, etc.)?',
40
- false
41
- );
42
-
43
- if (needsCompliance) {
44
- answers.compliance = await askMultiSelect(
45
- rl,
46
- 'Select compliance requirements:',
47
- [
48
- { label: 'GDPR', value: 'gdpr', description: 'EU data protection' },
49
- { label: 'SOC 2', value: 'soc2', description: 'Service organization controls' },
50
- { label: 'HIPAA', value: 'hipaa', description: 'Healthcare data' },
51
- { label: 'PCI DSS', value: 'pci', description: 'Payment card data' },
52
- { label: 'CCPA', value: 'ccpa', description: 'California privacy' }
53
- ],
54
- []
55
- );
56
- }
57
-
58
- // Infrastructure
59
- answers.infrastructure = await askChoice(
60
- rl,
61
- 'Infrastructure approach:',
62
- [
63
- { label: 'Managed/Serverless', value: 'managed', description: 'Vercel, Railway, etc.' },
64
- { label: 'Containers', value: 'containers', description: 'Docker, Kubernetes' },
65
- { label: 'VMs', value: 'vms', description: 'Traditional servers' },
66
- { label: 'Hybrid', value: 'hybrid', description: 'Mix of approaches' }
67
- ],
68
- 0
69
- );
70
-
71
- // Monitoring
72
- const wantMonitoring = await askYesNo(
73
- rl,
74
- 'Set up monitoring/observability?',
75
- true
76
- );
77
-
78
- if (wantMonitoring) {
79
- answers.monitoring = await askMultiSelect(
80
- rl,
81
- 'Monitoring tools:',
82
- [
83
- { label: 'Error tracking (Sentry)', value: 'sentry' },
84
- { label: 'Analytics (Posthog)', value: 'posthog' },
85
- { label: 'Logging (Axiom)', value: 'axiom' },
86
- { label: 'Uptime monitoring', value: 'uptime' },
87
- { label: 'Performance (Vercel Analytics)', value: 'vercel-analytics' }
88
- ],
89
- ['sentry']
90
- );
91
- }
92
-
93
- // Feature flags
94
- answers.featureFlags = await askYesNo(
95
- rl,
96
- 'Use feature flags?',
97
- false
98
- );
99
-
100
- if (answers.featureFlags) {
101
- answers.featureFlagProvider = await askChoice(
102
- rl,
103
- 'Feature flag provider:',
104
- [
105
- { label: 'LaunchDarkly', value: 'launchdarkly' },
106
- { label: 'Flagsmith', value: 'flagsmith' },
107
- { label: 'PostHog', value: 'posthog' },
108
- { label: 'Custom', value: 'custom' }
109
- ],
110
- 0
111
- );
112
- }
113
-
114
- // Multi-tenancy
115
- if (previousAnswers.businessModel === 'saas') {
116
- answers.multiTenancy = await askChoice(
117
- rl,
118
- 'Multi-tenancy approach:',
119
- [
120
- { label: 'Single tenant', value: 'single', description: 'One instance per customer' },
121
- { label: 'Shared DB', value: 'shared-db', description: 'Shared database, row-level' },
122
- { label: 'Schema per tenant', value: 'schema', description: 'Separate schemas' },
123
- { label: 'DB per tenant', value: 'db-per-tenant', description: 'Separate databases' }
124
- ],
125
- 1
126
- );
127
- }
128
-
129
- return answers;
130
- }
131
-
132
- module.exports = {
133
- title,
134
- description,
135
- run
136
- };
@@ -1,106 +0,0 @@
1
- /**
2
- * AI Integration Section
3
- *
4
- * AI providers, features, and configuration.
5
- *
6
- * @package bootspring
7
- * @module generators/sections/ai
8
- */
9
-
10
- const title = 'AI Integration';
11
- const description = 'AI and LLM setup';
12
-
13
- /**
14
- * Run the AI section
15
- */
16
- async function run(rl, previousAnswers, helpers) {
17
- const { askChoice, askMultiSelect, askYesNo } = helpers;
18
- const answers = {};
19
-
20
- // Enable AI
21
- answers.enableAI = await askYesNo(
22
- rl,
23
- 'Does your app need AI/LLM features?',
24
- false
25
- );
26
-
27
- if (!answers.enableAI) {
28
- return answers;
29
- }
30
-
31
- // AI Providers (multi-select)
32
- const providerOptions = [
33
- { label: 'Anthropic (Claude)', value: 'anthropic', description: 'Claude models (Recommended)' },
34
- { label: 'OpenAI', value: 'openai', description: 'GPT models' },
35
- { label: 'Google AI', value: 'google', description: 'Gemini models' },
36
- { label: 'Cohere', value: 'cohere', description: 'Enterprise NLP' },
37
- { label: 'Hugging Face', value: 'huggingface', description: 'Open source models' },
38
- { label: 'Local (Ollama)', value: 'ollama', description: 'Self-hosted models' }
39
- ];
40
-
41
- answers.aiProviders = await askMultiSelect(
42
- rl,
43
- 'AI providers to integrate (select one or more):',
44
- providerOptions,
45
- ['anthropic']
46
- );
47
-
48
- // AI Features
49
- const featureOptions = [
50
- { label: 'Chat/Conversation', value: 'chat' },
51
- { label: 'Text generation', value: 'generation' },
52
- { label: 'Embeddings/Search', value: 'embeddings' },
53
- { label: 'RAG (Retrieval Augmented)', value: 'rag' },
54
- { label: 'Image generation', value: 'images' },
55
- { label: 'Code generation', value: 'code' },
56
- { label: 'Speech/Audio', value: 'speech' },
57
- { label: 'Structured output', value: 'structured' }
58
- ];
59
-
60
- answers.aiFeatures = await askMultiSelect(
61
- rl,
62
- 'AI features needed:',
63
- featureOptions,
64
- ['chat', 'generation']
65
- );
66
-
67
- // Vector Database (if embeddings/RAG selected)
68
- if (answers.aiFeatures.includes('embeddings') || answers.aiFeatures.includes('rag')) {
69
- const vectorOptions = [
70
- { label: 'Pinecone', value: 'pinecone', description: 'Managed vector DB' },
71
- { label: 'Qdrant', value: 'qdrant', description: 'Open source vector DB' },
72
- { label: 'Weaviate', value: 'weaviate', description: 'AI-native vector DB' },
73
- { label: 'Supabase pgvector', value: 'pgvector', description: 'PostgreSQL extension' },
74
- { label: 'Turbopuffer', value: 'turbopuffer', description: 'Fast serverless' }
75
- ];
76
-
77
- answers.vectorDb = await askChoice(
78
- rl,
79
- 'Vector database:',
80
- vectorOptions,
81
- 0
82
- );
83
- }
84
-
85
- // Streaming
86
- answers.aiStreaming = await askYesNo(
87
- rl,
88
- 'Enable streaming responses?',
89
- true
90
- );
91
-
92
- // Rate limiting
93
- answers.aiRateLimiting = await askYesNo(
94
- rl,
95
- 'Need AI rate limiting?',
96
- true
97
- );
98
-
99
- return answers;
100
- }
101
-
102
- module.exports = {
103
- title,
104
- description,
105
- run
106
- };
@@ -1,89 +0,0 @@
1
- /**
2
- * Authentication Section
3
- *
4
- * Auth provider, methods, and configuration.
5
- *
6
- * @package bootspring
7
- * @module generators/sections/auth
8
- */
9
-
10
- const title = 'Authentication';
11
- const description = 'User authentication setup';
12
-
13
- /**
14
- * Run the auth section
15
- */
16
- async function run(rl, previousAnswers, helpers) {
17
- const { askChoice, askMultiSelect, askYesNo } = helpers;
18
- const answers = {};
19
-
20
- // Enable auth
21
- answers.enableAuth = await askYesNo(
22
- rl,
23
- 'Does your app need user authentication?',
24
- true
25
- );
26
-
27
- if (!answers.enableAuth) {
28
- return answers;
29
- }
30
-
31
- // Auth Provider
32
- const providerOptions = [
33
- { label: 'Clerk', value: 'clerk', description: 'Full-featured, easy setup (Recommended)' },
34
- { label: 'Auth.js (NextAuth)', value: 'authjs', description: 'Flexible, many providers' },
35
- { label: 'Supabase Auth', value: 'supabase', description: 'Part of Supabase stack' },
36
- { label: 'Firebase Auth', value: 'firebase', description: 'Google Firebase' },
37
- { label: 'Kinde', value: 'kinde', description: 'Developer-friendly' },
38
- { label: 'Custom', value: 'custom', description: 'Build your own' }
39
- ];
40
-
41
- answers.authProvider = await askChoice(
42
- rl,
43
- 'Auth provider:',
44
- providerOptions,
45
- 0
46
- );
47
-
48
- // Auth Methods
49
- const methodOptions = [
50
- { label: 'Email/Password', value: 'email' },
51
- { label: 'Magic Link', value: 'magic' },
52
- { label: 'Google OAuth', value: 'google' },
53
- { label: 'GitHub OAuth', value: 'github' },
54
- { label: 'Apple OAuth', value: 'apple' },
55
- { label: 'Passkeys/WebAuthn', value: 'passkeys' },
56
- { label: 'SMS/Phone', value: 'phone' }
57
- ];
58
-
59
- answers.authMethods = await askMultiSelect(
60
- rl,
61
- 'Authentication methods:',
62
- methodOptions,
63
- ['email', 'google']
64
- );
65
-
66
- // Advanced auth features
67
- const featureOptions = [
68
- { label: 'Multi-factor authentication (MFA)', value: 'mfa' },
69
- { label: 'Role-based access control (RBAC)', value: 'rbac' },
70
- { label: 'Organization/Team support', value: 'orgs' },
71
- { label: 'Session management', value: 'sessions' },
72
- { label: 'Audit logging', value: 'audit' }
73
- ];
74
-
75
- answers.authFeatures = await askMultiSelect(
76
- rl,
77
- 'Advanced auth features:',
78
- featureOptions,
79
- []
80
- );
81
-
82
- return answers;
83
- }
84
-
85
- module.exports = {
86
- title,
87
- description,
88
- run
89
- };
@@ -1,146 +0,0 @@
1
- /**
2
- * Backend Stack Section
3
- *
4
- * API patterns, background jobs, storage, and services.
5
- *
6
- * @package bootspring
7
- * @module generators/sections/backend
8
- */
9
-
10
- const title = 'Backend Stack';
11
- const description = 'API and server-side choices';
12
-
13
- /**
14
- * Run the backend section
15
- */
16
- async function run(rl, previousAnswers, helpers) {
17
- const { askChoice, askYesNo } = helpers;
18
- const answers = {};
19
-
20
- // API Style
21
- const apiOptions = [
22
- { label: 'REST', value: 'rest', description: 'Traditional REST API' },
23
- { label: 'tRPC', value: 'trpc', description: 'End-to-end type safety' },
24
- { label: 'GraphQL', value: 'graphql', description: 'Query language' },
25
- { label: 'Server Actions', value: 'server-actions', description: 'Next.js Server Actions' },
26
- { label: 'Hybrid', value: 'hybrid', description: 'Mix of approaches' }
27
- ];
28
-
29
- // Default based on framework
30
- const isNextjs = previousAnswers.framework === 'nextjs';
31
- const defaultApi = isNextjs ? 3 : 0; // Server Actions for Next.js, REST otherwise
32
-
33
- answers.apiStyle = await askChoice(
34
- rl,
35
- 'API style:',
36
- apiOptions,
37
- defaultApi
38
- );
39
-
40
- // Validation
41
- const validationOptions = [
42
- { label: 'Zod', value: 'zod', description: 'TypeScript-first (Recommended)' },
43
- { label: 'Yup', value: 'yup', description: 'Popular schema builder' },
44
- { label: 'Joi', value: 'joi', description: 'Enterprise validation' },
45
- { label: 'Custom', value: 'custom', description: 'Roll your own' }
46
- ];
47
-
48
- answers.validation = await askChoice(
49
- rl,
50
- 'Validation library:',
51
- validationOptions,
52
- 0
53
- );
54
-
55
- // Background Jobs
56
- answers.enableBackgroundJobs = await askYesNo(
57
- rl,
58
- 'Need background jobs/queues?',
59
- false
60
- );
61
-
62
- if (answers.enableBackgroundJobs) {
63
- const jobOptions = [
64
- { label: 'Inngest', value: 'inngest', description: 'Serverless functions' },
65
- { label: 'Trigger.dev', value: 'trigger', description: 'Background jobs platform' },
66
- { label: 'BullMQ', value: 'bullmq', description: 'Redis-based queues' },
67
- { label: 'Quirrel', value: 'quirrel', description: 'Job scheduling' }
68
- ];
69
-
70
- answers.jobProcessor = await askChoice(
71
- rl,
72
- 'Job processor:',
73
- jobOptions,
74
- 0
75
- );
76
- }
77
-
78
- // File Storage
79
- answers.enableFileStorage = await askYesNo(
80
- rl,
81
- 'Need file uploads/storage?',
82
- false
83
- );
84
-
85
- if (answers.enableFileStorage) {
86
- const storageOptions = [
87
- { label: 'Uploadthing', value: 'uploadthing', description: 'Easy file uploads' },
88
- { label: 'Cloudflare R2', value: 'r2', description: 'S3-compatible, cheap' },
89
- { label: 'AWS S3', value: 's3', description: 'Industry standard' },
90
- { label: 'Vercel Blob', value: 'vercel-blob', description: 'Vercel storage' }
91
- ];
92
-
93
- answers.fileStorage = await askChoice(
94
- rl,
95
- 'File storage:',
96
- storageOptions,
97
- 0
98
- );
99
- }
100
-
101
- // Caching
102
- const cacheOptions = [
103
- { label: 'None', value: 'none', description: 'No caching layer' },
104
- { label: 'Redis / Upstash', value: 'redis', description: 'In-memory cache' },
105
- { label: 'Vercel KV', value: 'vercel-kv', description: 'Vercel Redis' },
106
- { label: 'Cloudflare KV', value: 'cloudflare-kv', description: 'Edge KV' }
107
- ];
108
-
109
- answers.caching = await askChoice(
110
- rl,
111
- 'Caching layer:',
112
- cacheOptions,
113
- 0
114
- );
115
-
116
- // Email
117
- answers.enableEmail = await askYesNo(
118
- rl,
119
- 'Need email sending?',
120
- false
121
- );
122
-
123
- if (answers.enableEmail) {
124
- const emailOptions = [
125
- { label: 'Resend', value: 'resend', description: 'Modern email API' },
126
- { label: 'SendGrid', value: 'sendgrid', description: 'Popular email service' },
127
- { label: 'Postmark', value: 'postmark', description: 'Transactional email' },
128
- { label: 'AWS SES', value: 'ses', description: 'Amazon email service' }
129
- ];
130
-
131
- answers.emailProvider = await askChoice(
132
- rl,
133
- 'Email provider:',
134
- emailOptions,
135
- 0
136
- );
137
- }
138
-
139
- return answers;
140
- }
141
-
142
- module.exports = {
143
- title,
144
- description,
145
- run
146
- };
@@ -1,118 +0,0 @@
1
- /**
2
- * Business Context Section
3
- *
4
- * Collects business model, pricing, and market information.
5
- * Only included in full preset.
6
- *
7
- * @package bootspring
8
- * @module generators/sections/business
9
- */
10
-
11
- const title = 'Business Context';
12
- const description = 'Optional business information for better context';
13
-
14
- /**
15
- * Skip in minimal and standard presets
16
- */
17
- function shouldSkip(_previousAnswers) {
18
- // This section is only in 'full' preset, so no need to check
19
- return false;
20
- }
21
-
22
- /**
23
- * Run the business section
24
- */
25
- async function run(rl, previousAnswers, helpers) {
26
- const { askChoice, askText, askYesNo } = helpers;
27
-
28
- const answers = {};
29
-
30
- console.log('\nThis helps generate better business context in CLAUDE.md');
31
-
32
- // Business model
33
- answers.businessModel = await askChoice(
34
- rl,
35
- 'Business model:',
36
- [
37
- { label: 'SaaS', value: 'saas', description: 'Software as a Service' },
38
- { label: 'Marketplace', value: 'marketplace', description: 'Two-sided marketplace' },
39
- { label: 'E-commerce', value: 'ecommerce', description: 'Online store' },
40
- { label: 'Consumer App', value: 'consumer', description: 'B2C application' },
41
- { label: 'Enterprise', value: 'enterprise', description: 'B2B enterprise' },
42
- { label: 'Open Source', value: 'opensource', description: 'Open source project' },
43
- { label: 'Internal Tool', value: 'internal', description: 'Internal company tool' },
44
- { label: 'Other', value: 'other', description: 'Something else' }
45
- ],
46
- 0
47
- );
48
-
49
- // Pricing strategy (if commercial)
50
- if (!['opensource', 'internal'].includes(answers.businessModel)) {
51
- answers.pricingStrategy = await askChoice(
52
- rl,
53
- 'Pricing strategy:',
54
- [
55
- { label: 'Freemium', value: 'freemium', description: 'Free tier + paid upgrades' },
56
- { label: 'Subscription', value: 'subscription', description: 'Monthly/yearly plans' },
57
- { label: 'Usage-based', value: 'usage', description: 'Pay per use' },
58
- { label: 'One-time', value: 'one-time', description: 'Single purchase' },
59
- { label: 'Free', value: 'free', description: 'Completely free' },
60
- { label: 'Undecided', value: 'undecided', description: "Haven't decided yet" }
61
- ],
62
- 0
63
- );
64
-
65
- // Target market
66
- answers.targetMarket = await askText(
67
- rl,
68
- 'Target market (who are your users?)',
69
- ''
70
- );
71
-
72
- // Key differentiators
73
- answers.differentiators = await askText(
74
- rl,
75
- 'Key differentiator (what makes you unique?)',
76
- ''
77
- );
78
- }
79
-
80
- // Competitors
81
- const hasCompetitors = await askYesNo(
82
- rl,
83
- 'Want to note competitors for reference?',
84
- false
85
- );
86
-
87
- if (hasCompetitors) {
88
- answers.competitors = await askText(
89
- rl,
90
- 'Main competitors (comma-separated)',
91
- ''
92
- );
93
- }
94
-
95
- // Launch timeline
96
- answers.launchTimeline = await askChoice(
97
- rl,
98
- 'Launch timeline:',
99
- [
100
- { label: 'Already launched', value: 'launched' },
101
- { label: 'This month', value: 'this-month' },
102
- { label: '1-3 months', value: '1-3-months' },
103
- { label: '3-6 months', value: '3-6-months' },
104
- { label: '6+ months', value: '6-plus-months' },
105
- { label: 'No timeline', value: 'no-timeline' }
106
- ],
107
- 2
108
- );
109
-
110
- return answers;
111
- }
112
-
113
- module.exports = {
114
- title,
115
- description,
116
- shouldSkip,
117
- run
118
- };