@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.
- package/README.md +9 -403
- package/bin/bootspring.js +1 -96
- package/dist/cli/index.js +65134 -0
- package/dist/cli-launcher.js +92 -0
- package/dist/core/index.d.ts +2110 -5582
- package/dist/core/index.js +2 -0
- package/dist/core.js +21123 -5413
- package/dist/mcp/index.d.ts +357 -1
- package/dist/mcp/index.js +2 -0
- package/dist/mcp-server.js +51948 -1976
- package/package.json +27 -63
- package/scripts/postinstall.cjs +144 -0
- package/LICENSE +0 -29
- package/dist/cli/index.cjs +0 -20776
- package/generators/api-docs.js +0 -827
- package/generators/decisions.js +0 -655
- package/generators/generate.js +0 -595
- package/generators/health.js +0 -942
- package/generators/index.ts +0 -82
- package/generators/presets/full.js +0 -28
- package/generators/presets/index.js +0 -12
- package/generators/presets/minimal.js +0 -29
- package/generators/presets/standard.js +0 -28
- package/generators/questionnaire.js +0 -414
- package/generators/sections/advanced.js +0 -136
- package/generators/sections/ai.js +0 -106
- package/generators/sections/auth.js +0 -89
- package/generators/sections/backend.js +0 -146
- package/generators/sections/business.js +0 -118
- package/generators/sections/content.js +0 -300
- package/generators/sections/deployment.js +0 -139
- package/generators/sections/features.js +0 -122
- package/generators/sections/frontend.js +0 -118
- package/generators/sections/identity.js +0 -76
- package/generators/sections/index.js +0 -40
- package/generators/sections/instructions.js +0 -146
- package/generators/sections/payments.js +0 -104
- package/generators/sections/plugins.js +0 -142
- package/generators/sections/pre-build.js +0 -130
- package/generators/sections/security.js +0 -127
- package/generators/sections/technical.js +0 -171
- package/generators/sections/testing.js +0 -125
- package/generators/sections/workflow.js +0 -104
- package/generators/sprint.js +0 -675
- package/generators/templates/agents.template.js +0 -199
- package/generators/templates/assistant-context.template.js +0 -83
- package/generators/templates/build-planning.template.js +0 -708
- package/generators/templates/claude.template.js +0 -379
- package/generators/templates/content.template.js +0 -819
- package/generators/templates/index.js +0 -16
- package/generators/templates/planning.template.js +0 -515
- package/generators/templates/seed.template.js +0 -109
- package/generators/visual-doc-generator.js +0 -910
- package/scripts/postinstall.js +0 -197
- /package/{claude-commands → assets/claude-commands}/agent.md +0 -0
- /package/{claude-commands → assets/claude-commands}/bs.md +0 -0
- /package/{claude-commands → assets/claude-commands}/build.md +0 -0
- /package/{claude-commands → assets/claude-commands}/skill.md +0 -0
- /package/{claude-commands → assets/claude-commands}/todo.md +0 -0
package/generators/index.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bootspring Generators Module
|
|
3
|
-
*
|
|
4
|
-
* Provides context generation, scaffolding, and project setup.
|
|
5
|
-
*
|
|
6
|
-
* @package bootspring
|
|
7
|
-
* @module generators
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// ============================================================================
|
|
11
|
-
// Types
|
|
12
|
-
// ============================================================================
|
|
13
|
-
|
|
14
|
-
export interface GenerateOptions {
|
|
15
|
-
cwd?: string | undefined;
|
|
16
|
-
force?: boolean | undefined;
|
|
17
|
-
verbose?: boolean | undefined;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface GenerateResult {
|
|
21
|
-
success: boolean;
|
|
22
|
-
files: string[];
|
|
23
|
-
errors?: string[] | undefined;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface MvpAnalysis {
|
|
27
|
-
sections: Record<string, string>;
|
|
28
|
-
features: string[];
|
|
29
|
-
entities: string[];
|
|
30
|
-
routes: string[];
|
|
31
|
-
components: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface ParsedConfig {
|
|
35
|
-
project?: {
|
|
36
|
-
name?: string | undefined;
|
|
37
|
-
description?: string | undefined;
|
|
38
|
-
version?: string | undefined;
|
|
39
|
-
} | undefined;
|
|
40
|
-
stack?: {
|
|
41
|
-
framework?: string | undefined;
|
|
42
|
-
language?: string | undefined;
|
|
43
|
-
database?: string | undefined;
|
|
44
|
-
} | undefined;
|
|
45
|
-
plugins?: Record<string, unknown> | undefined;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface ParsedSeed {
|
|
49
|
-
name?: string | undefined;
|
|
50
|
-
tagline?: string | undefined;
|
|
51
|
-
problem?: string | undefined;
|
|
52
|
-
solution?: string | undefined;
|
|
53
|
-
features?: string[] | undefined;
|
|
54
|
-
userTypes?: string[] | undefined;
|
|
55
|
-
stack?: Record<string, string> | undefined;
|
|
56
|
-
phases?: Array<{
|
|
57
|
-
name: string;
|
|
58
|
-
tasks: string[];
|
|
59
|
-
}> | undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ============================================================================
|
|
63
|
-
// Module Import
|
|
64
|
-
// ============================================================================
|
|
65
|
-
|
|
66
|
-
const generator = require('./generate') as {
|
|
67
|
-
generate: (options?: GenerateOptions) => GenerateResult;
|
|
68
|
-
generateClaudeMd: (options?: GenerateOptions) => string;
|
|
69
|
-
analyzeMvpSource: (content: string) => MvpAnalysis;
|
|
70
|
-
parseConfig: (configPath: string) => ParsedConfig | null;
|
|
71
|
-
parseSeedMd: (content: string) => ParsedSeed;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
// ============================================================================
|
|
75
|
-
// Exports
|
|
76
|
-
// ============================================================================
|
|
77
|
-
|
|
78
|
-
export const generate = generator.generate;
|
|
79
|
-
export const generateClaudeMd = generator.generateClaudeMd;
|
|
80
|
-
export const analyzeMvpSource = generator.analyzeMvpSource;
|
|
81
|
-
export const parseConfig = generator.parseConfig;
|
|
82
|
-
export const parseSeedMd = generator.parseSeedMd;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Full Preset
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive setup with all options.
|
|
5
|
-
* Time: 10-15 minutes
|
|
6
|
-
*
|
|
7
|
-
* @package bootspring
|
|
8
|
-
* @module generators/presets/full
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
module.exports = {
|
|
12
|
-
name: 'full',
|
|
13
|
-
description: 'Comprehensive setup - all options',
|
|
14
|
-
duration: '10-15 minutes',
|
|
15
|
-
sections: [
|
|
16
|
-
'pre-build',
|
|
17
|
-
'identity',
|
|
18
|
-
'technical',
|
|
19
|
-
'plugins',
|
|
20
|
-
'workflow',
|
|
21
|
-
'instructions',
|
|
22
|
-
'business',
|
|
23
|
-
'advanced'
|
|
24
|
-
],
|
|
25
|
-
defaults: {
|
|
26
|
-
// No defaults - everything is asked
|
|
27
|
-
}
|
|
28
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal Preset
|
|
3
|
-
*
|
|
4
|
-
* Quick setup with just the essentials.
|
|
5
|
-
* Time: 2-3 minutes
|
|
6
|
-
*
|
|
7
|
-
* @package bootspring
|
|
8
|
-
* @module generators/presets/minimal
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
module.exports = {
|
|
12
|
-
name: 'minimal',
|
|
13
|
-
description: 'Quick setup - just the essentials',
|
|
14
|
-
duration: '2-3 minutes',
|
|
15
|
-
sections: ['pre-build', 'identity', 'technical', 'plugins'],
|
|
16
|
-
defaults: {
|
|
17
|
-
// Sensible defaults for skipped sections
|
|
18
|
-
workflow: {
|
|
19
|
-
gitStrategy: 'feature-branch',
|
|
20
|
-
teamSize: 'solo',
|
|
21
|
-
commitStyle: 'conventional'
|
|
22
|
-
},
|
|
23
|
-
instructions: {
|
|
24
|
-
componentPreferences: ['server-components', 'small-components'],
|
|
25
|
-
validationPreferences: ['zod', 'strict-ts'],
|
|
26
|
-
securityRules: ['no-client-keys', 'env-secrets']
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standard Preset
|
|
3
|
-
*
|
|
4
|
-
* Balanced setup covering most use cases.
|
|
5
|
-
* Time: 5-8 minutes
|
|
6
|
-
*
|
|
7
|
-
* @package bootspring
|
|
8
|
-
* @module generators/presets/standard
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
module.exports = {
|
|
12
|
-
name: 'standard',
|
|
13
|
-
description: 'Balanced setup - recommended for most projects',
|
|
14
|
-
duration: '5-8 minutes',
|
|
15
|
-
sections: ['pre-build', 'identity', 'technical', 'plugins', 'workflow', 'instructions'],
|
|
16
|
-
defaults: {
|
|
17
|
-
// Defaults for skipped business/advanced sections
|
|
18
|
-
business: {
|
|
19
|
-
model: null,
|
|
20
|
-
pricing: null
|
|
21
|
-
},
|
|
22
|
-
advanced: {
|
|
23
|
-
securityLevel: 'standard',
|
|
24
|
-
compliance: [],
|
|
25
|
-
infrastructure: 'managed'
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bootspring Questionnaire Engine
|
|
3
|
-
*
|
|
4
|
-
* Interactive questionnaire system for project initialization.
|
|
5
|
-
* Provides a guided, conversational experience for scaffolding.
|
|
6
|
-
*
|
|
7
|
-
* @package bootspring
|
|
8
|
-
* @module generators/questionnaire
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const readline = require('readline');
|
|
12
|
-
const utils = require('../core/utils');
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Questionnaire configuration - 17 sections
|
|
16
|
-
*/
|
|
17
|
-
const QUESTIONNAIRE_CONFIG = {
|
|
18
|
-
sections: [
|
|
19
|
-
'pre-build', // 1. Pre-Build Assets (MVP, PRD, business docs)
|
|
20
|
-
'identity', // 2. Project Identity
|
|
21
|
-
'business', // 3. Business Context (model, pricing, market)
|
|
22
|
-
'technical', // 4. Technical Framework
|
|
23
|
-
'frontend', // 5. Frontend Stack (UI, styling, state)
|
|
24
|
-
'backend', // 6. Backend Stack (API, jobs, storage)
|
|
25
|
-
'auth', // 7. Authentication
|
|
26
|
-
'payments', // 8. Payments & Monetization
|
|
27
|
-
'ai', // 9. AI Integration
|
|
28
|
-
'testing', // 10. Testing Strategy
|
|
29
|
-
'deployment', // 11. DevOps & Deployment
|
|
30
|
-
'security', // 12. Security Requirements
|
|
31
|
-
'features', // 13. Features & Functionality
|
|
32
|
-
'content', // 14. Content & Documentation
|
|
33
|
-
'workflow', // 15. Team & Workflow
|
|
34
|
-
'instructions', // 16. Custom Instructions
|
|
35
|
-
'advanced' // 17. Advanced Options
|
|
36
|
-
],
|
|
37
|
-
presets: {
|
|
38
|
-
// Quick setup - just the essentials (4 sections)
|
|
39
|
-
minimal: ['pre-build', 'identity', 'technical', 'features'],
|
|
40
|
-
// Standard setup - core config (9 sections)
|
|
41
|
-
standard: ['pre-build', 'identity', 'business', 'technical', 'frontend', 'auth', 'content', 'workflow', 'instructions'],
|
|
42
|
-
// Full setup - all sections (17 sections)
|
|
43
|
-
full: [
|
|
44
|
-
'pre-build', 'identity', 'business', 'technical', 'frontend', 'backend',
|
|
45
|
-
'auth', 'payments', 'ai', 'testing', 'deployment', 'security',
|
|
46
|
-
'features', 'content', 'workflow', 'instructions', 'advanced'
|
|
47
|
-
],
|
|
48
|
-
// Startup preset - business-focused (11 sections)
|
|
49
|
-
startup: [
|
|
50
|
-
'pre-build', 'identity', 'business', 'technical', 'frontend',
|
|
51
|
-
'auth', 'payments', 'features', 'content', 'workflow', 'instructions'
|
|
52
|
-
],
|
|
53
|
-
// API preset - backend-focused (9 sections)
|
|
54
|
-
api: ['pre-build', 'identity', 'technical', 'backend', 'auth', 'testing', 'deployment', 'security', 'content'],
|
|
55
|
-
// Content preset - content and marketing focused (8 sections)
|
|
56
|
-
content: ['pre-build', 'identity', 'business', 'technical', 'frontend', 'content', 'workflow', 'instructions']
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Create readline interface
|
|
62
|
-
*/
|
|
63
|
-
function createInterface() {
|
|
64
|
-
return readline.createInterface({
|
|
65
|
-
input: process.stdin,
|
|
66
|
-
output: process.stdout
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Ask a simple text question
|
|
72
|
-
*/
|
|
73
|
-
function askText(rl, question, defaultValue = '') {
|
|
74
|
-
const prompt = defaultValue
|
|
75
|
-
? `${question} ${utils.COLORS.dim}[${defaultValue}]${utils.COLORS.reset}: `
|
|
76
|
-
: `${question}: `;
|
|
77
|
-
|
|
78
|
-
return new Promise((resolve) => {
|
|
79
|
-
rl.question(prompt, (answer) => {
|
|
80
|
-
resolve(answer.trim() || defaultValue);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Ask a single choice question
|
|
87
|
-
*/
|
|
88
|
-
function askChoice(rl, question, options, defaultIndex = 0) {
|
|
89
|
-
return new Promise((resolve) => {
|
|
90
|
-
console.log(`\n${utils.COLORS.bold}${question}${utils.COLORS.reset}`);
|
|
91
|
-
|
|
92
|
-
options.forEach((opt, i) => {
|
|
93
|
-
const marker = i === defaultIndex
|
|
94
|
-
? `${utils.COLORS.cyan}→${utils.COLORS.reset}`
|
|
95
|
-
: ' ';
|
|
96
|
-
const label = typeof opt === 'object' ? opt.label : opt;
|
|
97
|
-
const desc = typeof opt === 'object' && opt.description
|
|
98
|
-
? ` ${utils.COLORS.dim}- ${opt.description}${utils.COLORS.reset}`
|
|
99
|
-
: '';
|
|
100
|
-
console.log(` ${marker} ${i + 1}. ${label}${desc}`);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
rl.question(`\n${utils.COLORS.dim}Select [1-${options.length}]${utils.COLORS.reset}: `, (answer) => {
|
|
104
|
-
const index = parseInt(answer, 10) - 1;
|
|
105
|
-
const selectedIndex = (index >= 0 && index < options.length) ? index : defaultIndex;
|
|
106
|
-
const selected = options[selectedIndex];
|
|
107
|
-
resolve(typeof selected === 'object' ? selected.value : selected);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Ask a multi-select question
|
|
114
|
-
*/
|
|
115
|
-
function askMultiSelect(rl, question, options, defaults = []) {
|
|
116
|
-
return new Promise((resolve) => {
|
|
117
|
-
console.log(`\n${utils.COLORS.bold}${question}${utils.COLORS.reset}`);
|
|
118
|
-
console.log(`${utils.COLORS.dim}(Enter comma-separated numbers, or 'all' / 'none')${utils.COLORS.reset}`);
|
|
119
|
-
|
|
120
|
-
options.forEach((opt, i) => {
|
|
121
|
-
const isDefault = defaults.includes(typeof opt === 'object' ? opt.value : opt);
|
|
122
|
-
const marker = isDefault ? `${utils.COLORS.green}✓${utils.COLORS.reset}` : ' ';
|
|
123
|
-
const label = typeof opt === 'object' ? opt.label : opt;
|
|
124
|
-
console.log(` ${marker} ${i + 1}. ${label}`);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
rl.question(`\n${utils.COLORS.dim}Select${utils.COLORS.reset}: `, (answer) => {
|
|
128
|
-
const trimmed = answer.trim().toLowerCase();
|
|
129
|
-
|
|
130
|
-
if (trimmed === 'all') {
|
|
131
|
-
resolve(options.map(o => typeof o === 'object' ? o.value : o));
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (trimmed === 'none' || trimmed === '') {
|
|
135
|
-
resolve(defaults);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const indices = trimmed.split(',').map(s => parseInt(s.trim(), 10) - 1);
|
|
140
|
-
const selected = indices
|
|
141
|
-
.filter(i => i >= 0 && i < options.length)
|
|
142
|
-
.map(i => {
|
|
143
|
-
const opt = options[i];
|
|
144
|
-
return typeof opt === 'object' ? opt.value : opt;
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
resolve(selected.length > 0 ? selected : defaults);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Ask a yes/no question
|
|
154
|
-
*/
|
|
155
|
-
function askYesNo(rl, question, defaultYes = true) {
|
|
156
|
-
const hint = defaultYes
|
|
157
|
-
? `${utils.COLORS.dim}[Y/n]${utils.COLORS.reset}`
|
|
158
|
-
: `${utils.COLORS.dim}[y/N]${utils.COLORS.reset}`;
|
|
159
|
-
|
|
160
|
-
return new Promise((resolve) => {
|
|
161
|
-
rl.question(`${question} ${hint}: `, (answer) => {
|
|
162
|
-
const a = answer.trim().toLowerCase();
|
|
163
|
-
if (a === '') {
|
|
164
|
-
resolve(defaultYes);
|
|
165
|
-
} else {
|
|
166
|
-
resolve(a === 'y' || a === 'yes');
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Display a section header
|
|
174
|
-
*/
|
|
175
|
-
function displaySectionHeader(sectionNumber, totalSections, title, description) {
|
|
176
|
-
console.log('\n');
|
|
177
|
-
console.log(`${utils.COLORS.cyan}${'─'.repeat(60)}${utils.COLORS.reset}`);
|
|
178
|
-
console.log(`${utils.COLORS.bold}Section ${sectionNumber}/${totalSections}: ${title}${utils.COLORS.reset}`);
|
|
179
|
-
if (description) {
|
|
180
|
-
console.log(`${utils.COLORS.dim}${description}${utils.COLORS.reset}`);
|
|
181
|
-
}
|
|
182
|
-
console.log(`${utils.COLORS.cyan}${'─'.repeat(60)}${utils.COLORS.reset}`);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Display progress indicator
|
|
187
|
-
*/
|
|
188
|
-
function displayProgress(current, total) {
|
|
189
|
-
const percentage = Math.round((current / total) * 100);
|
|
190
|
-
const barWidth = 30;
|
|
191
|
-
const filled = Math.round((current / total) * barWidth);
|
|
192
|
-
const empty = barWidth - filled;
|
|
193
|
-
|
|
194
|
-
const bar = `${utils.COLORS.green}${'█'.repeat(filled)}${utils.COLORS.dim}${'░'.repeat(empty)}${utils.COLORS.reset}`;
|
|
195
|
-
console.log(`\n${bar} ${percentage}% complete`);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Questionnaire class
|
|
200
|
-
*/
|
|
201
|
-
class Questionnaire {
|
|
202
|
-
constructor(preset = 'standard') {
|
|
203
|
-
this.preset = preset;
|
|
204
|
-
this.sections = QUESTIONNAIRE_CONFIG.presets[preset] || QUESTIONNAIRE_CONFIG.presets.standard;
|
|
205
|
-
this.answers = {};
|
|
206
|
-
this.rl = null;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Run the questionnaire
|
|
211
|
-
*/
|
|
212
|
-
async run() {
|
|
213
|
-
this.rl = createInterface();
|
|
214
|
-
this.answers = {};
|
|
215
|
-
|
|
216
|
-
console.log(`\n${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Project Setup${utils.COLORS.reset}`);
|
|
217
|
-
console.log(`${utils.COLORS.dim}Preset: ${this.preset} (${this.sections.length} sections)${utils.COLORS.reset}`);
|
|
218
|
-
|
|
219
|
-
try {
|
|
220
|
-
for (let i = 0; i < this.sections.length; i++) {
|
|
221
|
-
const sectionName = this.sections[i];
|
|
222
|
-
const section = require(`./sections/${sectionName}`);
|
|
223
|
-
|
|
224
|
-
displaySectionHeader(
|
|
225
|
-
i + 1,
|
|
226
|
-
this.sections.length,
|
|
227
|
-
section.title,
|
|
228
|
-
section.description
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
// Check skip conditions
|
|
232
|
-
if (section.shouldSkip && section.shouldSkip(this.answers)) {
|
|
233
|
-
console.log(`${utils.COLORS.dim}Skipping (based on previous answers)...${utils.COLORS.reset}`);
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Run section questions
|
|
238
|
-
const sectionAnswers = await section.run(this.rl, this.answers, {
|
|
239
|
-
askText,
|
|
240
|
-
askChoice,
|
|
241
|
-
askMultiSelect,
|
|
242
|
-
askYesNo
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// Merge answers
|
|
246
|
-
this.answers = { ...this.answers, ...sectionAnswers };
|
|
247
|
-
|
|
248
|
-
displayProgress(i + 1, this.sections.length);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
this.rl.close();
|
|
252
|
-
|
|
253
|
-
console.log(`\n${utils.COLORS.green}${utils.COLORS.bold}✓ Questionnaire complete!${utils.COLORS.reset}\n`);
|
|
254
|
-
|
|
255
|
-
return this.answers;
|
|
256
|
-
} catch (error) {
|
|
257
|
-
this.rl.close();
|
|
258
|
-
throw error;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Build configuration from answers
|
|
264
|
-
*/
|
|
265
|
-
buildConfig() {
|
|
266
|
-
return {
|
|
267
|
-
project: {
|
|
268
|
-
name: this.answers.projectName || 'untitled',
|
|
269
|
-
description: this.answers.projectDescription || '',
|
|
270
|
-
version: this.answers.projectVersion || '1.0.0',
|
|
271
|
-
status: this.answers.projectStatus || 'development',
|
|
272
|
-
type: this.answers.appType || 'saas',
|
|
273
|
-
mvpScope: this.answers.mvpScope || 'single',
|
|
274
|
-
primaryUseCase: this.answers.primaryUseCase || '',
|
|
275
|
-
targetUsers: this.answers.targetUsers || 'b2c'
|
|
276
|
-
},
|
|
277
|
-
stack: {
|
|
278
|
-
framework: this.answers.framework || 'nextjs',
|
|
279
|
-
language: this.answers.language || 'typescript',
|
|
280
|
-
database: this.answers.database || 'postgresql',
|
|
281
|
-
orm: this.answers.orm || 'prisma',
|
|
282
|
-
hosting: this.answers.hosting || 'vercel'
|
|
283
|
-
},
|
|
284
|
-
frontend: {
|
|
285
|
-
uiLibrary: this.answers.uiLibrary || 'shadcn',
|
|
286
|
-
styling: this.answers.styling || 'tailwind',
|
|
287
|
-
stateManagement: this.answers.stateManagement || 'context',
|
|
288
|
-
dataFetching: this.answers.dataFetching || 'tanstack',
|
|
289
|
-
features: this.answers.frontendFeatures || []
|
|
290
|
-
},
|
|
291
|
-
backend: {
|
|
292
|
-
apiStyle: this.answers.apiStyle || 'rest',
|
|
293
|
-
validation: this.answers.validation || 'zod',
|
|
294
|
-
caching: this.answers.caching || 'none',
|
|
295
|
-
backgroundJobs: this.answers.enableBackgroundJobs ? {
|
|
296
|
-
enabled: true,
|
|
297
|
-
processor: this.answers.jobProcessor || 'inngest'
|
|
298
|
-
} : { enabled: false },
|
|
299
|
-
fileStorage: this.answers.enableFileStorage ? {
|
|
300
|
-
enabled: true,
|
|
301
|
-
provider: this.answers.fileStorage || 'uploadthing'
|
|
302
|
-
} : { enabled: false },
|
|
303
|
-
email: this.answers.enableEmail ? {
|
|
304
|
-
enabled: true,
|
|
305
|
-
provider: this.answers.emailProvider || 'resend'
|
|
306
|
-
} : { enabled: false }
|
|
307
|
-
},
|
|
308
|
-
plugins: {
|
|
309
|
-
auth: {
|
|
310
|
-
enabled: this.answers.enableAuth || false,
|
|
311
|
-
provider: this.answers.authProvider || 'clerk',
|
|
312
|
-
methods: this.answers.authMethods || ['email'],
|
|
313
|
-
features: this.answers.authFeatures || []
|
|
314
|
-
},
|
|
315
|
-
payments: {
|
|
316
|
-
enabled: this.answers.enablePayments || false,
|
|
317
|
-
provider: this.answers.paymentsProvider || 'stripe',
|
|
318
|
-
types: this.answers.paymentTypes || [],
|
|
319
|
-
tiers: this.answers.pricingTiers || null,
|
|
320
|
-
features: this.answers.paymentFeatures || []
|
|
321
|
-
},
|
|
322
|
-
database: {
|
|
323
|
-
enabled: this.answers.database !== 'none',
|
|
324
|
-
provider: this.answers.orm || 'prisma'
|
|
325
|
-
},
|
|
326
|
-
testing: {
|
|
327
|
-
enabled: this.answers.enableTesting !== false,
|
|
328
|
-
runner: this.answers.testRunner || 'vitest',
|
|
329
|
-
types: this.answers.testTypes || ['unit'],
|
|
330
|
-
e2eFramework: this.answers.e2eFramework || null,
|
|
331
|
-
componentTesting: this.answers.componentTesting || null,
|
|
332
|
-
coverageTarget: this.answers.coverageTarget || 'standard',
|
|
333
|
-
runInCI: this.answers.testInCI !== false
|
|
334
|
-
},
|
|
335
|
-
security: {
|
|
336
|
-
enabled: true,
|
|
337
|
-
level: this.answers.securityLevel || 'standard',
|
|
338
|
-
features: this.answers.securityFeatures || [],
|
|
339
|
-
compliance: this.answers.compliance || [],
|
|
340
|
-
dataHandling: this.answers.dataHandling || [],
|
|
341
|
-
scanning: this.answers.enableSecurityScanning ? {
|
|
342
|
-
enabled: true,
|
|
343
|
-
scanner: this.answers.securityScanner || 'dependabot'
|
|
344
|
-
} : { enabled: false }
|
|
345
|
-
},
|
|
346
|
-
ai: {
|
|
347
|
-
enabled: this.answers.enableAI || false,
|
|
348
|
-
provider: this.answers.aiProvider || 'anthropic',
|
|
349
|
-
features: this.answers.aiFeatures || [],
|
|
350
|
-
vectorDb: this.answers.vectorDb || null,
|
|
351
|
-
streaming: this.answers.aiStreaming !== false,
|
|
352
|
-
rateLimiting: this.answers.aiRateLimiting !== false
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
deployment: {
|
|
356
|
-
environments: this.answers.environments || 'prod-preview',
|
|
357
|
-
ciPlatform: this.answers.ciPlatform || 'github',
|
|
358
|
-
branchStrategy: this.answers.branchStrategy || 'github-flow',
|
|
359
|
-
pipelineSteps: this.answers.pipelineSteps || ['lint', 'build'],
|
|
360
|
-
monitoring: this.answers.enableMonitoring ? {
|
|
361
|
-
enabled: true,
|
|
362
|
-
provider: this.answers.monitoringProvider || 'sentry'
|
|
363
|
-
} : { enabled: false },
|
|
364
|
-
featureFlags: this.answers.enableFeatureFlags ? {
|
|
365
|
-
enabled: true,
|
|
366
|
-
provider: this.answers.featureFlagProvider || 'posthog'
|
|
367
|
-
} : { enabled: false }
|
|
368
|
-
},
|
|
369
|
-
features: {
|
|
370
|
-
core: this.answers.coreFeatures || ['dashboard', 'settings']
|
|
371
|
-
},
|
|
372
|
-
workflow: {
|
|
373
|
-
gitStrategy: this.answers.gitStrategy || 'feature-branch',
|
|
374
|
-
teamSize: this.answers.teamSize || 'solo',
|
|
375
|
-
commitStyle: this.answers.commitStyle || 'conventional'
|
|
376
|
-
},
|
|
377
|
-
instructions: this.answers.customInstructions || {},
|
|
378
|
-
business: {
|
|
379
|
-
model: this.answers.businessModel || null,
|
|
380
|
-
pricing: this.answers.pricingStrategy || null,
|
|
381
|
-
targetMarket: this.answers.targetMarket || null
|
|
382
|
-
},
|
|
383
|
-
advanced: {
|
|
384
|
-
security: this.answers.securityLevel || 'standard',
|
|
385
|
-
compliance: this.answers.compliance || [],
|
|
386
|
-
infrastructure: this.answers.infrastructure || 'managed'
|
|
387
|
-
},
|
|
388
|
-
dashboard: { port: 3456, autoOpen: false },
|
|
389
|
-
quality: { preCommit: true, prePush: false, strictMode: false },
|
|
390
|
-
paths: { context: 'CLAUDE.md', config: 'bootspring.config.js', todo: 'todo.md' }
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Run questionnaire with preset
|
|
397
|
-
*/
|
|
398
|
-
async function runQuestionnaire(preset = 'standard') {
|
|
399
|
-
const questionnaire = new Questionnaire(preset);
|
|
400
|
-
await questionnaire.run();
|
|
401
|
-
return questionnaire.buildConfig();
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
module.exports = {
|
|
405
|
-
Questionnaire,
|
|
406
|
-
runQuestionnaire,
|
|
407
|
-
askText,
|
|
408
|
-
askChoice,
|
|
409
|
-
askMultiSelect,
|
|
410
|
-
askYesNo,
|
|
411
|
-
displaySectionHeader,
|
|
412
|
-
displayProgress,
|
|
413
|
-
QUESTIONNAIRE_CONFIG
|
|
414
|
-
};
|