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