@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
package/cli/context.js ADDED
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Bootspring Context Command
3
+ * View and manage project context
4
+ *
5
+ * @package bootspring
6
+ * @command context
7
+ */
8
+
9
+ const path = require('path');
10
+ const config = require('../core/config');
11
+ const context = require('../core/context');
12
+ const utils = require('../core/utils');
13
+
14
+ /**
15
+ * Show project context summary
16
+ */
17
+ function showContext() {
18
+ const cfg = config.load();
19
+ const ctx = context.get({ config: cfg });
20
+
21
+ console.log(`
22
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Context${utils.COLORS.reset}
23
+ ${utils.COLORS.dim}Project: ${cfg._projectRoot}${utils.COLORS.reset}
24
+ `);
25
+
26
+ // Project Info
27
+ console.log(`${utils.COLORS.bold}Project${utils.COLORS.reset}`);
28
+ console.log(` Name: ${ctx.project.name}`);
29
+ console.log(` Version: ${ctx.project.version}`);
30
+ if (ctx.project.description) {
31
+ console.log(` Description: ${ctx.project.description}`);
32
+ }
33
+ console.log();
34
+
35
+ // Stack
36
+ console.log(`${utils.COLORS.bold}Stack${utils.COLORS.reset}`);
37
+ console.log(` Framework: ${utils.COLORS.cyan}${ctx.stack.framework}${utils.COLORS.reset}`);
38
+ console.log(` Language: ${ctx.stack.language}`);
39
+ console.log(` Database: ${ctx.stack.database}`);
40
+ console.log(` Hosting: ${ctx.stack.hosting}`);
41
+ console.log();
42
+
43
+ // Plugins
44
+ const plugins = Object.keys(ctx.plugins);
45
+ if (plugins.length > 0) {
46
+ console.log(`${utils.COLORS.bold}Enabled Plugins${utils.COLORS.reset}`);
47
+ for (const [name, plugin] of Object.entries(ctx.plugins)) {
48
+ console.log(` ${utils.COLORS.green}●${utils.COLORS.reset} ${name} (${plugin.provider})`);
49
+ }
50
+ console.log();
51
+ }
52
+
53
+ // State
54
+ const healthColor = ctx.state.health === 'good' ? utils.COLORS.green :
55
+ ctx.state.health === 'fair' ? utils.COLORS.yellow :
56
+ utils.COLORS.red;
57
+
58
+ console.log(`${utils.COLORS.bold}State${utils.COLORS.reset}`);
59
+ console.log(` Phase: ${ctx.state.phase}`);
60
+ console.log(` Health: ${healthColor}${ctx.state.health}${utils.COLORS.reset}`);
61
+ console.log(` Open Todos: ${ctx.state.todos}`);
62
+ if (ctx.state.lastGenerated) {
63
+ console.log(` Context Updated: ${utils.formatRelativeTime(ctx.state.lastGenerated)}`);
64
+ }
65
+ console.log();
66
+
67
+ // Git
68
+ if (ctx.git.initialized) {
69
+ console.log(`${utils.COLORS.bold}Git${utils.COLORS.reset}`);
70
+ console.log(` Branch: ${ctx.git.branch || 'unknown'}`);
71
+ console.log(` Remote: ${ctx.git.hasRemote ? 'configured' : 'not configured'}`);
72
+ console.log();
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Validate project context
78
+ */
79
+ function validateContext() {
80
+ const cfg = config.load();
81
+ const validation = context.validate({ config: cfg });
82
+
83
+ console.log(`
84
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Context Validation${utils.COLORS.reset}
85
+ `);
86
+
87
+ for (const check of validation.checks) {
88
+ const icon = check.status === 'pass' ? utils.COLORS.green + '✓' :
89
+ check.status === 'fail' ? utils.COLORS.red + '✗' :
90
+ check.status === 'warn' ? utils.COLORS.yellow + '⚠' :
91
+ utils.COLORS.dim + 'ℹ';
92
+ const color = check.status === 'pass' ? '' :
93
+ check.status === 'fail' ? utils.COLORS.red :
94
+ check.status === 'warn' ? utils.COLORS.yellow :
95
+ utils.COLORS.dim;
96
+ console.log(` ${icon}${utils.COLORS.reset} ${check.name}`);
97
+ console.log(` ${utils.COLORS.dim}${check.message}${utils.COLORS.reset}`);
98
+ }
99
+
100
+ console.log();
101
+
102
+ // Score bar
103
+ const barWidth = 30;
104
+ const filled = Math.round((validation.percentage / 100) * barWidth);
105
+ const empty = barWidth - filled;
106
+ const scoreColor = validation.percentage >= 80 ? utils.COLORS.green :
107
+ validation.percentage >= 50 ? utils.COLORS.yellow :
108
+ utils.COLORS.red;
109
+
110
+ console.log(`${utils.COLORS.bold}Score${utils.COLORS.reset}`);
111
+ console.log(` ${scoreColor}${'█'.repeat(filled)}${utils.COLORS.dim}${'░'.repeat(empty)}${utils.COLORS.reset} ${validation.percentage}%`);
112
+ console.log(` ${validation.score}/${validation.maxScore} checks passed`);
113
+ console.log();
114
+
115
+ if (validation.valid) {
116
+ utils.print.success('Context validation passed');
117
+ } else {
118
+ utils.print.warning('Context needs attention - fix the issues above');
119
+ utils.print.dim('Run "bootspring generate" to regenerate context');
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Refresh project context
125
+ */
126
+ function refreshContext() {
127
+ console.log(`
128
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Context Refresh${utils.COLORS.reset}
129
+ `);
130
+
131
+ utils.print.info('Refreshing context...');
132
+
133
+ // This triggers a regeneration
134
+ const generateModule = require('./generate');
135
+ generateModule.run([]);
136
+ }
137
+
138
+ /**
139
+ * Show context help
140
+ */
141
+ function showHelp() {
142
+ console.log(`
143
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Context${utils.COLORS.reset}
144
+ ${utils.COLORS.dim}View and manage project context${utils.COLORS.reset}
145
+
146
+ ${utils.COLORS.bold}Usage:${utils.COLORS.reset}
147
+ bootspring context <command>
148
+
149
+ ${utils.COLORS.bold}Commands:${utils.COLORS.reset}
150
+ ${utils.COLORS.cyan}show${utils.COLORS.reset} Show context summary (default)
151
+ ${utils.COLORS.cyan}validate${utils.COLORS.reset} Validate project setup
152
+ ${utils.COLORS.cyan}refresh${utils.COLORS.reset} Regenerate context files
153
+
154
+ ${utils.COLORS.bold}Examples:${utils.COLORS.reset}
155
+ bootspring context
156
+ bootspring context validate
157
+ bootspring context refresh
158
+ `);
159
+ }
160
+
161
+ /**
162
+ * Run context command
163
+ */
164
+ async function run(args) {
165
+ const subcommand = args[0] || 'show';
166
+
167
+ switch (subcommand) {
168
+ case 'show':
169
+ showContext();
170
+ break;
171
+
172
+ case 'validate':
173
+ case 'check':
174
+ validateContext();
175
+ break;
176
+
177
+ case 'refresh':
178
+ case 'regenerate':
179
+ refreshContext();
180
+ break;
181
+
182
+ case 'help':
183
+ case '-h':
184
+ case '--help':
185
+ showHelp();
186
+ break;
187
+
188
+ default:
189
+ utils.print.error(`Unknown subcommand: ${subcommand}`);
190
+ showHelp();
191
+ }
192
+ }
193
+
194
+ module.exports = { run, showContext, validateContext, refreshContext };
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Bootspring Dashboard Command
3
+ * Control the real-time dashboard
4
+ *
5
+ * @package bootspring
6
+ * @command dashboard
7
+ */
8
+
9
+ const path = require('path');
10
+ const { spawn } = require('child_process');
11
+ const config = require('../core/config');
12
+ const utils = require('../core/utils');
13
+
14
+ /**
15
+ * Start the dashboard server
16
+ */
17
+ function startDashboard(options = {}) {
18
+ const cfg = config.load();
19
+ const port = options.port || cfg.dashboard?.port || 3456;
20
+
21
+ const dashboardPath = path.resolve(__dirname, '../dashboard/server.js');
22
+
23
+ // Check if dashboard server exists
24
+ if (!utils.fileExists(dashboardPath)) {
25
+ utils.print.warning('Dashboard server not yet implemented');
26
+ utils.print.dim('Coming soon in a future release');
27
+ return;
28
+ }
29
+
30
+ console.log(`
31
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Dashboard${utils.COLORS.reset}
32
+ ${utils.COLORS.dim}Real-time project visibility${utils.COLORS.reset}
33
+ `);
34
+
35
+ utils.print.info(`Starting dashboard on port ${port}...`);
36
+
37
+ // Start the server
38
+ const server = spawn('node', [dashboardPath], {
39
+ env: {
40
+ ...process.env,
41
+ PORT: port,
42
+ BOOTSPRING_ROOT: cfg._projectRoot
43
+ },
44
+ stdio: 'inherit'
45
+ });
46
+
47
+ server.on('error', (error) => {
48
+ utils.print.error(`Failed to start dashboard: ${error.message}`);
49
+ });
50
+
51
+ server.on('close', (code) => {
52
+ if (code !== 0) {
53
+ utils.print.error(`Dashboard exited with code ${code}`);
54
+ }
55
+ });
56
+
57
+ // Handle graceful shutdown
58
+ process.on('SIGINT', () => {
59
+ utils.print.info('Shutting down dashboard...');
60
+ server.kill('SIGINT');
61
+ process.exit(0);
62
+ });
63
+
64
+ process.on('SIGTERM', () => {
65
+ server.kill('SIGTERM');
66
+ process.exit(0);
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Show dashboard status
72
+ */
73
+ function showStatus() {
74
+ const cfg = config.load();
75
+ const port = cfg.dashboard?.port || 3456;
76
+
77
+ console.log(`
78
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Dashboard Status${utils.COLORS.reset}
79
+
80
+ ${utils.COLORS.bold}Configuration:${utils.COLORS.reset}
81
+ Port: ${port}
82
+ Auto-open: ${cfg.dashboard?.autoOpen ? 'yes' : 'no'}
83
+
84
+ ${utils.COLORS.bold}To start:${utils.COLORS.reset}
85
+ bootspring dashboard
86
+
87
+ ${utils.COLORS.bold}URL:${utils.COLORS.reset}
88
+ http://localhost:${port}
89
+ `);
90
+ }
91
+
92
+ /**
93
+ * Show dashboard help
94
+ */
95
+ function showHelp() {
96
+ console.log(`
97
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Dashboard${utils.COLORS.reset}
98
+ ${utils.COLORS.dim}Real-time project visibility${utils.COLORS.reset}
99
+
100
+ ${utils.COLORS.bold}Usage:${utils.COLORS.reset}
101
+ bootspring dashboard [command] [options]
102
+
103
+ ${utils.COLORS.bold}Commands:${utils.COLORS.reset}
104
+ ${utils.COLORS.cyan}start${utils.COLORS.reset} Start the dashboard (default)
105
+ ${utils.COLORS.cyan}status${utils.COLORS.reset} Show dashboard status
106
+
107
+ ${utils.COLORS.bold}Options:${utils.COLORS.reset}
108
+ --port <port> Use a specific port (default: 3456)
109
+
110
+ ${utils.COLORS.bold}Examples:${utils.COLORS.reset}
111
+ bootspring dashboard
112
+ bootspring dashboard --port 8080
113
+ bootspring dashboard status
114
+ `);
115
+ }
116
+
117
+ /**
118
+ * Run dashboard command
119
+ */
120
+ async function run(args) {
121
+ const parsedArgs = utils.parseArgs(args);
122
+ const subcommand = parsedArgs._[0] || 'start';
123
+
124
+ switch (subcommand) {
125
+ case 'start':
126
+ startDashboard({ port: parsedArgs.port });
127
+ break;
128
+
129
+ case 'status':
130
+ showStatus();
131
+ break;
132
+
133
+ case 'help':
134
+ case '-h':
135
+ case '--help':
136
+ showHelp();
137
+ break;
138
+
139
+ default:
140
+ // Treat unknown as start with possible port
141
+ if (!isNaN(parseInt(subcommand, 10))) {
142
+ startDashboard({ port: parseInt(subcommand, 10) });
143
+ } else {
144
+ utils.print.error(`Unknown subcommand: ${subcommand}`);
145
+ showHelp();
146
+ }
147
+ }
148
+ }
149
+
150
+ module.exports = { run, startDashboard, showStatus };
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Bootspring Generate Command
3
+ * Generate and regenerate AI context files
4
+ *
5
+ * @package bootspring
6
+ * @command generate
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const config = require('../core/config');
12
+ const context = require('../core/context');
13
+ const utils = require('../core/utils');
14
+ const gitMemory = require('../intelligence/git-memory');
15
+
16
+ /**
17
+ * Generate CLAUDE.md content from config and project state
18
+ */
19
+ function generateClaudeMd(cfg, ctx) {
20
+ const date = utils.formatDate();
21
+
22
+ const sections = [];
23
+
24
+ // Header
25
+ sections.push(`# ${cfg.project.name} - AI Context
26
+
27
+ **Generated by**: Bootspring v1.0.0
28
+ **Last Updated**: ${date}
29
+ **Status**: ${ctx.state.phase}
30
+ **Health**: ${ctx.state.health}
31
+
32
+ ---`);
33
+
34
+ // Project Overview
35
+ sections.push(`## Project Overview
36
+
37
+ ${cfg.project.description || 'A modern web application built with Bootspring.'}
38
+
39
+ ---`);
40
+
41
+ // Tech Stack
42
+ sections.push(`## Tech Stack
43
+
44
+ | Component | Technology |
45
+ |-----------|------------|
46
+ | Framework | ${cfg.stack.framework} |
47
+ | Language | ${cfg.stack.language} |
48
+ | Database | ${cfg.stack.database} |
49
+ | Hosting | ${cfg.stack.hosting} |
50
+
51
+ ---`);
52
+
53
+ // Enabled Plugins
54
+ const enabledPlugins = Object.entries(cfg.plugins)
55
+ .filter(([_, p]) => p.enabled !== false);
56
+
57
+ if (enabledPlugins.length > 0) {
58
+ sections.push(`## Enabled Plugins
59
+
60
+ ${enabledPlugins.map(([name, plugin]) => `### ${name.charAt(0).toUpperCase() + name.slice(1)}
61
+ - **Provider**: ${plugin.provider || 'default'}
62
+ - **Features**: ${(plugin.features || []).join(', ') || 'default'}`).join('\n\n')}
63
+
64
+ ---`);
65
+ }
66
+
67
+ // Bootspring Commands
68
+ sections.push(`## Bootspring Commands
69
+
70
+ Quick commands for your AI assistant:
71
+
72
+ ### Todo Management
73
+ \`\`\`bash
74
+ bootspring todo add "task" # Add a new todo
75
+ bootspring todo list # List all todos
76
+ bootspring todo done <id> # Mark as complete
77
+ bootspring todo clear # Clear completed
78
+ \`\`\`
79
+
80
+ ### Agents & Skills
81
+ \`\`\`bash
82
+ bootspring agent list # List available agents
83
+ bootspring agent invoke <n> # Get specialized help
84
+ bootspring skill search <q> # Find code patterns
85
+ bootspring skill show <name> # View a skill
86
+ \`\`\`
87
+
88
+ ### Project Tools
89
+ \`\`\`bash
90
+ bootspring dashboard # Start real-time dashboard
91
+ bootspring generate # Regenerate this context
92
+ bootspring quality pre-commit # Run quality checks
93
+ bootspring context validate # Validate project setup
94
+ \`\`\`
95
+
96
+ ---`);
97
+
98
+ // Project State
99
+ sections.push(`## Current State
100
+
101
+ - **Phase**: ${ctx.state.phase}
102
+ - **Health**: ${ctx.state.health}
103
+ - **Open Todos**: ${ctx.state.todos}
104
+ ${ctx.state.issues.length > 0 ? `- **Issues**: ${ctx.state.issues.join(', ')}` : ''}
105
+
106
+ ---`);
107
+
108
+ // Git Info
109
+ if (ctx.git.initialized) {
110
+ sections.push(`## Git Repository
111
+
112
+ - **Branch**: ${ctx.git.branch || 'unknown'}
113
+ - **Remote**: ${ctx.git.hasRemote ? 'configured' : 'not configured'}
114
+
115
+ ---`);
116
+
117
+ // Extract git learnings
118
+ try {
119
+ const { learnings } = gitMemory.extractLearnings({
120
+ limit: 30,
121
+ since: '2 months ago',
122
+ cwd: cfg._projectRoot
123
+ });
124
+
125
+ if (learnings && learnings.length > 0) {
126
+ const learningsSection = gitMemory.toCompactSummary(learnings, { maxItems: 12 });
127
+ sections.push(learningsSection + '\n---');
128
+ }
129
+ } catch (e) {
130
+ // Git memory extraction failed silently
131
+ }
132
+ }
133
+
134
+ // Project Structure
135
+ sections.push(`## Project Structure
136
+
137
+ - **Structure Type**: ${ctx.files.structure}
138
+ - **Has TypeScript**: ${ctx.files.hasTsConfig ? 'yes' : 'no'}
139
+ - **Has Package.json**: ${ctx.files.hasPackageJson ? 'yes' : 'no'}
140
+
141
+ ---`);
142
+
143
+ // Development Guidelines
144
+ sections.push(`## Development Guidelines
145
+
146
+ ### Code Style
147
+ - Use ${cfg.stack.language === 'typescript' ? 'TypeScript' : 'JavaScript'} for all new code
148
+ - Follow existing naming conventions in the codebase
149
+ - Keep files focused and under 300 lines when possible
150
+
151
+ ### Best Practices
152
+ - Use Server Components by default (if Next.js)
153
+ - Prefer Server Actions over API routes for mutations
154
+ - Use Zod for all input validation
155
+ - Never expose API keys to client-side code
156
+ - Write tests for new features
157
+
158
+ ### Git Commits
159
+ - Use conventional commit format: \`feat:\`, \`fix:\`, \`docs:\`, \`refactor:\`
160
+ - Keep commits focused and atomic
161
+ - Never commit sensitive data or API keys
162
+
163
+ ---`);
164
+
165
+ // Custom Instructions
166
+ if (cfg.customInstructions) {
167
+ sections.push(`## Custom Instructions
168
+
169
+ ${cfg.customInstructions}
170
+
171
+ ---`);
172
+ }
173
+
174
+ // Footer
175
+ sections.push(`---
176
+
177
+ *Generated by [Bootspring](https://bootspring.com) - Development scaffolding with intelligence*
178
+ `);
179
+
180
+ return sections.join('\n\n');
181
+ }
182
+
183
+ /**
184
+ * Run generate command
185
+ */
186
+ async function run(args) {
187
+ const parsedArgs = utils.parseArgs(args);
188
+ const full = parsedArgs.full || parsedArgs.f;
189
+
190
+ console.log(`
191
+ ${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Generate${utils.COLORS.reset}
192
+ ${utils.COLORS.dim}Regenerating AI context...${utils.COLORS.reset}
193
+ `);
194
+
195
+ // Load config
196
+ const cfg = config.load();
197
+
198
+ if (!cfg._configPath) {
199
+ utils.print.error('No bootspring.config.js found');
200
+ utils.print.dim('Run "bootspring init" first to initialize your project');
201
+ return;
202
+ }
203
+
204
+ // Get context
205
+ const ctx = context.get({ config: cfg });
206
+
207
+ // Generate CLAUDE.md
208
+ const claudePath = path.join(cfg._projectRoot, cfg.paths?.context || 'CLAUDE.md');
209
+ const spinner = utils.createSpinner('Generating CLAUDE.md').start();
210
+
211
+ try {
212
+ const content = generateClaudeMd(cfg, ctx);
213
+ utils.writeFile(claudePath, content);
214
+ spinner.succeed('Generated CLAUDE.md');
215
+ } catch (error) {
216
+ spinner.fail(`Failed to generate CLAUDE.md: ${error.message}`);
217
+ return;
218
+ }
219
+
220
+ // Validate context
221
+ const validation = context.validate({ config: cfg });
222
+
223
+ console.log(`
224
+ ${utils.COLORS.bold}Context Validation${utils.COLORS.reset}
225
+ `);
226
+
227
+ for (const check of validation.checks) {
228
+ const icon = check.status === 'pass' ? utils.COLORS.green + '✓' :
229
+ check.status === 'fail' ? utils.COLORS.red + '✗' :
230
+ check.status === 'warn' ? utils.COLORS.yellow + '⚠' :
231
+ utils.COLORS.dim + 'ℹ';
232
+ console.log(` ${icon}${utils.COLORS.reset} ${check.name}: ${utils.COLORS.dim}${check.message}${utils.COLORS.reset}`);
233
+ }
234
+
235
+ console.log(`
236
+ ${utils.COLORS.bold}Score:${utils.COLORS.reset} ${validation.score}/${validation.maxScore} (${validation.percentage}%)
237
+ `);
238
+
239
+ if (validation.valid) {
240
+ utils.print.success('Context is valid and ready for AI assistants');
241
+ } else {
242
+ utils.print.warning('Context has some issues - review the checks above');
243
+ }
244
+
245
+ // Full generation includes additional files
246
+ if (full) {
247
+ console.log(`\n${utils.COLORS.bold}Full Generation${utils.COLORS.reset}\n`);
248
+
249
+ // Generate .mcp.json if missing
250
+ const mcpPath = path.join(cfg._projectRoot, '.mcp.json');
251
+ if (!utils.fileExists(mcpPath)) {
252
+ const mcpSpinner = utils.createSpinner('Generating .mcp.json').start();
253
+ const mcpConfig = {
254
+ mcpServers: {
255
+ bootspring: {
256
+ command: 'npx',
257
+ args: ['bootspring', 'mcp'],
258
+ env: {}
259
+ }
260
+ }
261
+ };
262
+ utils.writeFile(mcpPath, JSON.stringify(mcpConfig, null, 2));
263
+ mcpSpinner.succeed('Generated .mcp.json');
264
+ }
265
+
266
+ // Generate todo.md if missing
267
+ const todoPath = path.join(cfg._projectRoot, cfg.paths?.todo || 'todo.md');
268
+ if (!utils.fileExists(todoPath)) {
269
+ const todoSpinner = utils.createSpinner('Generating todo.md').start();
270
+ const todoContent = `# ${cfg.project.name} - Todo List
271
+
272
+ > Last updated: ${utils.formatDate()}
273
+
274
+ ## In Progress
275
+
276
+ ## Pending
277
+
278
+ - [ ] Review generated context
279
+ - [ ] Configure environment variables
280
+
281
+ ## Completed
282
+
283
+ `;
284
+ utils.writeFile(todoPath, todoContent);
285
+ todoSpinner.succeed('Generated todo.md');
286
+ }
287
+ }
288
+
289
+ console.log(`
290
+ ${utils.COLORS.dim}Tip: Run 'bootspring generate --full' to regenerate all files${utils.COLORS.reset}
291
+ `);
292
+ }
293
+
294
+ module.exports = { run, generateClaudeMd };