@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.
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/agents/README.md +93 -0
- package/agents/api-expert/context.md +416 -0
- package/agents/architecture-expert/context.md +454 -0
- package/agents/backend-expert/context.md +483 -0
- package/agents/code-review-expert/context.md +365 -0
- package/agents/database-expert/context.md +250 -0
- package/agents/devops-expert/context.md +446 -0
- package/agents/frontend-expert/context.md +364 -0
- package/agents/index.js +140 -0
- package/agents/performance-expert/context.md +377 -0
- package/agents/security-expert/context.md +343 -0
- package/agents/testing-expert/context.md +414 -0
- package/agents/ui-ux-expert/context.md +448 -0
- package/agents/vercel-expert/context.md +426 -0
- package/bin/bootspring.js +310 -0
- package/cli/agent.js +337 -0
- package/cli/context.js +194 -0
- package/cli/dashboard.js +150 -0
- package/cli/generate.js +294 -0
- package/cli/init.js +410 -0
- package/cli/loop.js +421 -0
- package/cli/mcp.js +241 -0
- package/cli/memory.js +303 -0
- package/cli/orchestrator.js +400 -0
- package/cli/plugin.js +451 -0
- package/cli/quality.js +332 -0
- package/cli/skill.js +369 -0
- package/cli/task.js +628 -0
- package/cli/telemetry.js +114 -0
- package/cli/todo.js +614 -0
- package/cli/update.js +312 -0
- package/core/config.js +245 -0
- package/core/context.js +329 -0
- package/core/entitlements.js +209 -0
- package/core/index.js +43 -0
- package/core/policies.js +68 -0
- package/core/telemetry.js +247 -0
- package/core/utils.js +380 -0
- package/dashboard/server.js +818 -0
- package/docs/integrations/claude-code.md +42 -0
- package/docs/integrations/codex.md +42 -0
- package/docs/mcp-api-platform.md +102 -0
- package/generators/generate.js +598 -0
- package/generators/index.js +18 -0
- package/hooks/context-detector.js +177 -0
- package/hooks/index.js +35 -0
- package/hooks/prompt-enhancer.js +289 -0
- package/intelligence/git-memory.js +551 -0
- package/intelligence/index.js +59 -0
- package/intelligence/orchestrator.js +964 -0
- package/intelligence/prd.js +447 -0
- package/intelligence/recommendation-weights.json +18 -0
- package/intelligence/recommendations.js +234 -0
- package/mcp/capabilities.js +71 -0
- package/mcp/contracts/mcp-contract.v1.json +497 -0
- package/mcp/registry.js +213 -0
- package/mcp/response-formatter.js +462 -0
- package/mcp/server.js +99 -0
- package/mcp/tools/agent-tool.js +137 -0
- package/mcp/tools/capabilities-tool.js +54 -0
- package/mcp/tools/context-tool.js +49 -0
- package/mcp/tools/dashboard-tool.js +58 -0
- package/mcp/tools/generate-tool.js +46 -0
- package/mcp/tools/loop-tool.js +134 -0
- package/mcp/tools/memory-tool.js +180 -0
- package/mcp/tools/orchestrator-tool.js +232 -0
- package/mcp/tools/plugin-tool.js +76 -0
- package/mcp/tools/quality-tool.js +47 -0
- package/mcp/tools/skill-tool.js +233 -0
- package/mcp/tools/telemetry-tool.js +95 -0
- package/mcp/tools/todo-tool.js +133 -0
- package/package.json +98 -0
- package/plugins/index.js +141 -0
- package/quality/index.js +380 -0
- package/quality/lint-budgets.json +19 -0
- package/skills/index.js +787 -0
- package/skills/patterns/README.md +163 -0
- package/skills/patterns/api/route-handler.md +217 -0
- package/skills/patterns/api/server-action.md +249 -0
- package/skills/patterns/auth/clerk.md +132 -0
- package/skills/patterns/database/prisma.md +180 -0
- package/skills/patterns/payments/stripe.md +272 -0
- package/skills/patterns/security/validation.md +268 -0
- package/skills/patterns/testing/vitest.md +307 -0
- package/templates/bootspring.config.js +83 -0
- package/templates/mcp.json +9 -0
package/cli/plugin.js
ADDED
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootspring Plugin Command
|
|
3
|
+
* Manage project plugins
|
|
4
|
+
*
|
|
5
|
+
* @package bootspring
|
|
6
|
+
* @command plugin
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const config = require('../core/config');
|
|
11
|
+
const utils = require('../core/utils');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Plugin definitions
|
|
15
|
+
*/
|
|
16
|
+
const PLUGINS = {
|
|
17
|
+
auth: {
|
|
18
|
+
name: 'Authentication',
|
|
19
|
+
description: 'User authentication and authorization',
|
|
20
|
+
providers: ['clerk', 'nextauth', 'auth0', 'supabase'],
|
|
21
|
+
defaultProvider: 'clerk',
|
|
22
|
+
features: ['social_login', 'email_password', 'magic_link', 'organizations', 'rbac'],
|
|
23
|
+
requiredEnv: {
|
|
24
|
+
clerk: ['NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY', 'CLERK_SECRET_KEY'],
|
|
25
|
+
nextauth: ['NEXTAUTH_SECRET', 'NEXTAUTH_URL'],
|
|
26
|
+
auth0: ['AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'AUTH0_ISSUER'],
|
|
27
|
+
supabase: ['NEXT_PUBLIC_SUPABASE_URL', 'SUPABASE_SERVICE_ROLE_KEY']
|
|
28
|
+
},
|
|
29
|
+
skills: ['auth/clerk', 'auth/nextauth']
|
|
30
|
+
},
|
|
31
|
+
payments: {
|
|
32
|
+
name: 'Payments',
|
|
33
|
+
description: 'Payment processing and subscriptions',
|
|
34
|
+
providers: ['stripe', 'paddle', 'lemonsqueezy'],
|
|
35
|
+
defaultProvider: 'stripe',
|
|
36
|
+
features: ['checkout', 'subscriptions', 'webhooks', 'invoices', 'usage_billing'],
|
|
37
|
+
requiredEnv: {
|
|
38
|
+
stripe: ['STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET'],
|
|
39
|
+
paddle: ['PADDLE_VENDOR_ID', 'PADDLE_API_KEY'],
|
|
40
|
+
lemonsqueezy: ['LEMONSQUEEZY_API_KEY', 'LEMONSQUEEZY_SIGNING_SECRET']
|
|
41
|
+
},
|
|
42
|
+
skills: ['payments/stripe', 'payments/webhooks']
|
|
43
|
+
},
|
|
44
|
+
database: {
|
|
45
|
+
name: 'Database',
|
|
46
|
+
description: 'Database ORM and migrations',
|
|
47
|
+
providers: ['prisma', 'drizzle', 'typeorm', 'mongoose'],
|
|
48
|
+
defaultProvider: 'prisma',
|
|
49
|
+
features: ['migrations', 'transactions', 'soft_deletes', 'seeding'],
|
|
50
|
+
requiredEnv: {
|
|
51
|
+
prisma: ['DATABASE_URL'],
|
|
52
|
+
drizzle: ['DATABASE_URL'],
|
|
53
|
+
typeorm: ['DATABASE_URL'],
|
|
54
|
+
mongoose: ['MONGODB_URI']
|
|
55
|
+
},
|
|
56
|
+
skills: ['database/prisma', 'database/drizzle']
|
|
57
|
+
},
|
|
58
|
+
testing: {
|
|
59
|
+
name: 'Testing',
|
|
60
|
+
description: 'Testing frameworks and utilities',
|
|
61
|
+
providers: ['vitest', 'jest', 'playwright'],
|
|
62
|
+
defaultProvider: 'vitest',
|
|
63
|
+
features: ['unit', 'integration', 'e2e', 'coverage', 'mocking'],
|
|
64
|
+
requiredEnv: {},
|
|
65
|
+
skills: ['testing/vitest', 'testing/playwright']
|
|
66
|
+
},
|
|
67
|
+
security: {
|
|
68
|
+
name: 'Security',
|
|
69
|
+
description: 'Security checks and protections',
|
|
70
|
+
providers: ['default'],
|
|
71
|
+
defaultProvider: 'default',
|
|
72
|
+
features: ['input_validation', 'rate_limiting', 'csrf', 'cors', 'owasp_checks'],
|
|
73
|
+
requiredEnv: {},
|
|
74
|
+
skills: ['security/validation', 'security/rate-limiting']
|
|
75
|
+
},
|
|
76
|
+
ai: {
|
|
77
|
+
name: 'AI Integration',
|
|
78
|
+
description: 'AI model integration and utilities',
|
|
79
|
+
providers: ['anthropic', 'openai', 'google'],
|
|
80
|
+
defaultProvider: 'anthropic',
|
|
81
|
+
features: ['streaming', 'tool_use', 'structured_output', 'embeddings', 'rag'],
|
|
82
|
+
requiredEnv: {
|
|
83
|
+
anthropic: ['ANTHROPIC_API_KEY'],
|
|
84
|
+
openai: ['OPENAI_API_KEY'],
|
|
85
|
+
google: ['GOOGLE_AI_API_KEY']
|
|
86
|
+
},
|
|
87
|
+
skills: ['ai/streaming', 'ai/tool-use']
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* List all plugins
|
|
93
|
+
*/
|
|
94
|
+
function listPlugins() {
|
|
95
|
+
const cfg = config.load();
|
|
96
|
+
|
|
97
|
+
console.log(`
|
|
98
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Plugins${utils.COLORS.reset}
|
|
99
|
+
${utils.COLORS.dim}Extensible functionality for your project${utils.COLORS.reset}
|
|
100
|
+
`);
|
|
101
|
+
|
|
102
|
+
for (const [id, plugin] of Object.entries(PLUGINS)) {
|
|
103
|
+
const userPlugin = cfg.plugins?.[id] || {};
|
|
104
|
+
const enabled = userPlugin.enabled !== false && (userPlugin.enabled || userPlugin.provider);
|
|
105
|
+
const provider = userPlugin.provider || plugin.defaultProvider;
|
|
106
|
+
|
|
107
|
+
const statusIcon = enabled
|
|
108
|
+
? `${utils.COLORS.green}●${utils.COLORS.reset}`
|
|
109
|
+
: `${utils.COLORS.dim}○${utils.COLORS.reset}`;
|
|
110
|
+
|
|
111
|
+
const statusText = enabled
|
|
112
|
+
? `${utils.COLORS.green}enabled${utils.COLORS.reset} (${provider})`
|
|
113
|
+
: `${utils.COLORS.dim}disabled${utils.COLORS.reset}`;
|
|
114
|
+
|
|
115
|
+
console.log(` ${statusIcon} ${utils.COLORS.cyan}${id}${utils.COLORS.reset}`);
|
|
116
|
+
console.log(` ${plugin.description}`);
|
|
117
|
+
console.log(` Status: ${statusText}`);
|
|
118
|
+
console.log();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
utils.print.dim('Use "bootspring plugin show <name>" for details');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Show plugin details
|
|
126
|
+
*/
|
|
127
|
+
function showPlugin(pluginId) {
|
|
128
|
+
const plugin = PLUGINS[pluginId];
|
|
129
|
+
|
|
130
|
+
if (!plugin) {
|
|
131
|
+
utils.print.error(`Plugin not found: ${pluginId}`);
|
|
132
|
+
utils.print.dim('Use "bootspring plugin list" to see available plugins');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const cfg = config.load();
|
|
137
|
+
const userPlugin = cfg.plugins?.[pluginId] || {};
|
|
138
|
+
const enabled = userPlugin.enabled !== false && (userPlugin.enabled || userPlugin.provider);
|
|
139
|
+
const currentProvider = userPlugin.provider || plugin.defaultProvider;
|
|
140
|
+
const enabledFeatures = userPlugin.features || [];
|
|
141
|
+
|
|
142
|
+
console.log(`
|
|
143
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ ${plugin.name} Plugin${utils.COLORS.reset}
|
|
144
|
+
${utils.COLORS.dim}${plugin.description}${utils.COLORS.reset}
|
|
145
|
+
|
|
146
|
+
${utils.COLORS.bold}Status${utils.COLORS.reset}
|
|
147
|
+
Enabled: ${enabled ? `${utils.COLORS.green}yes${utils.COLORS.reset}` : `${utils.COLORS.dim}no${utils.COLORS.reset}`}
|
|
148
|
+
Provider: ${currentProvider}
|
|
149
|
+
|
|
150
|
+
${utils.COLORS.bold}Available Providers${utils.COLORS.reset}
|
|
151
|
+
${plugin.providers.map(p => {
|
|
152
|
+
const isCurrent = p === currentProvider;
|
|
153
|
+
const icon = isCurrent ? `${utils.COLORS.green}●${utils.COLORS.reset}` : `${utils.COLORS.dim}○${utils.COLORS.reset}`;
|
|
154
|
+
return ` ${icon} ${p}${isCurrent ? ' (current)' : ''}`;
|
|
155
|
+
}).join('\n')}
|
|
156
|
+
|
|
157
|
+
${utils.COLORS.bold}Available Features${utils.COLORS.reset}
|
|
158
|
+
${plugin.features.map(f => {
|
|
159
|
+
const isEnabled = enabledFeatures.includes(f);
|
|
160
|
+
const icon = isEnabled ? `${utils.COLORS.green}✓${utils.COLORS.reset}` : `${utils.COLORS.dim}○${utils.COLORS.reset}`;
|
|
161
|
+
return ` ${icon} ${f}`;
|
|
162
|
+
}).join('\n')}
|
|
163
|
+
`);
|
|
164
|
+
|
|
165
|
+
// Show required environment variables
|
|
166
|
+
const requiredEnv = plugin.requiredEnv[currentProvider];
|
|
167
|
+
if (requiredEnv && requiredEnv.length > 0) {
|
|
168
|
+
console.log(`${utils.COLORS.bold}Required Environment Variables${utils.COLORS.reset}`);
|
|
169
|
+
for (const envVar of requiredEnv) {
|
|
170
|
+
const hasValue = !!process.env[envVar];
|
|
171
|
+
const icon = hasValue
|
|
172
|
+
? `${utils.COLORS.green}✓${utils.COLORS.reset}`
|
|
173
|
+
: `${utils.COLORS.red}✗${utils.COLORS.reset}`;
|
|
174
|
+
console.log(` ${icon} ${envVar}`);
|
|
175
|
+
}
|
|
176
|
+
console.log();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Show related skills
|
|
180
|
+
if (plugin.skills.length > 0) {
|
|
181
|
+
console.log(`${utils.COLORS.bold}Related Skills${utils.COLORS.reset}`);
|
|
182
|
+
for (const skill of plugin.skills) {
|
|
183
|
+
console.log(` ${utils.COLORS.dim}bootspring skill show ${skill}${utils.COLORS.reset}`);
|
|
184
|
+
}
|
|
185
|
+
console.log();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
console.log(`${utils.COLORS.bold}Configuration${utils.COLORS.reset}
|
|
189
|
+
Edit ${utils.COLORS.cyan}bootspring.config.js${utils.COLORS.reset}:
|
|
190
|
+
|
|
191
|
+
plugins: {
|
|
192
|
+
${pluginId}: {
|
|
193
|
+
enabled: true,
|
|
194
|
+
provider: '${currentProvider}',
|
|
195
|
+
features: ['${plugin.features.slice(0, 3).join("', '")}']
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Enable a plugin
|
|
203
|
+
*/
|
|
204
|
+
function enablePlugin(pluginId, options = {}) {
|
|
205
|
+
const plugin = PLUGINS[pluginId];
|
|
206
|
+
|
|
207
|
+
if (!plugin) {
|
|
208
|
+
utils.print.error(`Plugin not found: ${pluginId}`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const provider = options.provider || plugin.defaultProvider;
|
|
213
|
+
|
|
214
|
+
if (!plugin.providers.includes(provider)) {
|
|
215
|
+
utils.print.error(`Invalid provider: ${provider}`);
|
|
216
|
+
utils.print.dim(`Valid providers: ${plugin.providers.join(', ')}`);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
utils.print.success(`To enable ${pluginId} plugin with ${provider}:`);
|
|
221
|
+
console.log(`
|
|
222
|
+
Edit ${utils.COLORS.cyan}bootspring.config.js${utils.COLORS.reset}:
|
|
223
|
+
|
|
224
|
+
plugins: {
|
|
225
|
+
${pluginId}: {
|
|
226
|
+
enabled: true,
|
|
227
|
+
provider: '${provider}',
|
|
228
|
+
features: ['${plugin.features.slice(0, 3).join("', '")}']
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
`);
|
|
232
|
+
|
|
233
|
+
// Show required env vars
|
|
234
|
+
const requiredEnv = plugin.requiredEnv[provider];
|
|
235
|
+
if (requiredEnv && requiredEnv.length > 0) {
|
|
236
|
+
console.log(`${utils.COLORS.bold}Add to .env:${utils.COLORS.reset}`);
|
|
237
|
+
for (const envVar of requiredEnv) {
|
|
238
|
+
console.log(` ${envVar}=your_value_here`);
|
|
239
|
+
}
|
|
240
|
+
console.log();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
console.log(`${utils.COLORS.dim}Then run: bootspring generate${utils.COLORS.reset}`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Disable a plugin
|
|
248
|
+
*/
|
|
249
|
+
function disablePlugin(pluginId) {
|
|
250
|
+
const plugin = PLUGINS[pluginId];
|
|
251
|
+
|
|
252
|
+
if (!plugin) {
|
|
253
|
+
utils.print.error(`Plugin not found: ${pluginId}`);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
utils.print.success(`To disable ${pluginId} plugin:`);
|
|
258
|
+
console.log(`
|
|
259
|
+
Edit ${utils.COLORS.cyan}bootspring.config.js${utils.COLORS.reset}:
|
|
260
|
+
|
|
261
|
+
plugins: {
|
|
262
|
+
${pluginId}: {
|
|
263
|
+
enabled: false
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
`);
|
|
267
|
+
console.log(`${utils.COLORS.dim}Then run: bootspring generate${utils.COLORS.reset}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Validate plugins
|
|
272
|
+
*/
|
|
273
|
+
function validatePlugins() {
|
|
274
|
+
const cfg = config.load();
|
|
275
|
+
|
|
276
|
+
console.log(`
|
|
277
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Plugin Validation${utils.COLORS.reset}
|
|
278
|
+
`);
|
|
279
|
+
|
|
280
|
+
let issues = 0;
|
|
281
|
+
|
|
282
|
+
for (const [id, plugin] of Object.entries(PLUGINS)) {
|
|
283
|
+
const userPlugin = cfg.plugins?.[id] || {};
|
|
284
|
+
const enabled = userPlugin.enabled !== false && (userPlugin.enabled || userPlugin.provider);
|
|
285
|
+
|
|
286
|
+
if (!enabled) continue;
|
|
287
|
+
|
|
288
|
+
const provider = userPlugin.provider || plugin.defaultProvider;
|
|
289
|
+
const requiredEnv = plugin.requiredEnv[provider] || [];
|
|
290
|
+
|
|
291
|
+
let pluginOk = true;
|
|
292
|
+
const missingEnv = [];
|
|
293
|
+
|
|
294
|
+
for (const envVar of requiredEnv) {
|
|
295
|
+
if (!process.env[envVar]) {
|
|
296
|
+
missingEnv.push(envVar);
|
|
297
|
+
pluginOk = false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (pluginOk) {
|
|
302
|
+
console.log(` ${utils.COLORS.green}✓${utils.COLORS.reset} ${id} (${provider})`);
|
|
303
|
+
} else {
|
|
304
|
+
console.log(` ${utils.COLORS.red}✗${utils.COLORS.reset} ${id} (${provider})`);
|
|
305
|
+
console.log(` ${utils.COLORS.dim}Missing: ${missingEnv.join(', ')}${utils.COLORS.reset}`);
|
|
306
|
+
issues++;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
console.log();
|
|
311
|
+
|
|
312
|
+
if (issues === 0) {
|
|
313
|
+
utils.print.success('All enabled plugins are properly configured');
|
|
314
|
+
} else {
|
|
315
|
+
utils.print.warning(`${issues} plugin(s) have missing configuration`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Show skills for a plugin
|
|
321
|
+
*/
|
|
322
|
+
function showPluginSkills(pluginId) {
|
|
323
|
+
const plugin = PLUGINS[pluginId];
|
|
324
|
+
|
|
325
|
+
if (!plugin) {
|
|
326
|
+
utils.print.error(`Plugin not found: ${pluginId}`);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
console.log(`
|
|
331
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ ${plugin.name} Skills${utils.COLORS.reset}
|
|
332
|
+
`);
|
|
333
|
+
|
|
334
|
+
if (plugin.skills.length === 0) {
|
|
335
|
+
utils.print.dim('No skills available for this plugin');
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
for (const skill of plugin.skills) {
|
|
340
|
+
console.log(` ${utils.COLORS.cyan}${skill}${utils.COLORS.reset}`);
|
|
341
|
+
console.log(` ${utils.COLORS.dim}bootspring skill show ${skill}${utils.COLORS.reset}`);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
console.log();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Show plugin help
|
|
349
|
+
*/
|
|
350
|
+
function showHelp() {
|
|
351
|
+
console.log(`
|
|
352
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Plugin${utils.COLORS.reset}
|
|
353
|
+
${utils.COLORS.dim}Manage project plugins${utils.COLORS.reset}
|
|
354
|
+
|
|
355
|
+
${utils.COLORS.bold}Usage:${utils.COLORS.reset}
|
|
356
|
+
bootspring plugin <command> [args]
|
|
357
|
+
|
|
358
|
+
${utils.COLORS.bold}Commands:${utils.COLORS.reset}
|
|
359
|
+
${utils.COLORS.cyan}list${utils.COLORS.reset} List all plugins with status
|
|
360
|
+
${utils.COLORS.cyan}show${utils.COLORS.reset} <name> Show plugin details
|
|
361
|
+
${utils.COLORS.cyan}enable${utils.COLORS.reset} <name> Instructions to enable plugin
|
|
362
|
+
${utils.COLORS.cyan}disable${utils.COLORS.reset} <name> Instructions to disable plugin
|
|
363
|
+
${utils.COLORS.cyan}validate${utils.COLORS.reset} Check plugin configuration
|
|
364
|
+
${utils.COLORS.cyan}skills${utils.COLORS.reset} <name> Show skills for a plugin
|
|
365
|
+
|
|
366
|
+
${utils.COLORS.bold}Options:${utils.COLORS.reset}
|
|
367
|
+
--provider <name> Specify provider when enabling
|
|
368
|
+
|
|
369
|
+
${utils.COLORS.bold}Examples:${utils.COLORS.reset}
|
|
370
|
+
bootspring plugin list
|
|
371
|
+
bootspring plugin show auth
|
|
372
|
+
bootspring plugin enable auth --provider clerk
|
|
373
|
+
bootspring plugin validate
|
|
374
|
+
bootspring plugin skills payments
|
|
375
|
+
`);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Run plugin command
|
|
380
|
+
*/
|
|
381
|
+
async function run(args) {
|
|
382
|
+
const parsedArgs = utils.parseArgs(args);
|
|
383
|
+
const subcommand = parsedArgs._[0] || 'list';
|
|
384
|
+
const subargs = parsedArgs._.slice(1);
|
|
385
|
+
|
|
386
|
+
switch (subcommand) {
|
|
387
|
+
case 'list':
|
|
388
|
+
case 'ls':
|
|
389
|
+
listPlugins();
|
|
390
|
+
break;
|
|
391
|
+
|
|
392
|
+
case 'show':
|
|
393
|
+
case 'info':
|
|
394
|
+
if (!subargs[0]) {
|
|
395
|
+
utils.print.error('Please specify a plugin name');
|
|
396
|
+
utils.print.dim('Usage: bootspring plugin show <name>');
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
showPlugin(subargs[0]);
|
|
400
|
+
break;
|
|
401
|
+
|
|
402
|
+
case 'enable':
|
|
403
|
+
if (!subargs[0]) {
|
|
404
|
+
utils.print.error('Please specify a plugin name');
|
|
405
|
+
utils.print.dim('Usage: bootspring plugin enable <name>');
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
enablePlugin(subargs[0], { provider: parsedArgs.provider });
|
|
409
|
+
break;
|
|
410
|
+
|
|
411
|
+
case 'disable':
|
|
412
|
+
if (!subargs[0]) {
|
|
413
|
+
utils.print.error('Please specify a plugin name');
|
|
414
|
+
utils.print.dim('Usage: bootspring plugin disable <name>');
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
disablePlugin(subargs[0]);
|
|
418
|
+
break;
|
|
419
|
+
|
|
420
|
+
case 'validate':
|
|
421
|
+
case 'check':
|
|
422
|
+
validatePlugins();
|
|
423
|
+
break;
|
|
424
|
+
|
|
425
|
+
case 'skills':
|
|
426
|
+
if (!subargs[0]) {
|
|
427
|
+
utils.print.error('Please specify a plugin name');
|
|
428
|
+
utils.print.dim('Usage: bootspring plugin skills <name>');
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
showPluginSkills(subargs[0]);
|
|
432
|
+
break;
|
|
433
|
+
|
|
434
|
+
case 'help':
|
|
435
|
+
case '-h':
|
|
436
|
+
case '--help':
|
|
437
|
+
showHelp();
|
|
438
|
+
break;
|
|
439
|
+
|
|
440
|
+
default:
|
|
441
|
+
// Check if it's a plugin name (shortcut for show)
|
|
442
|
+
if (PLUGINS[subcommand]) {
|
|
443
|
+
showPlugin(subcommand);
|
|
444
|
+
} else {
|
|
445
|
+
utils.print.error(`Unknown subcommand: ${subcommand}`);
|
|
446
|
+
showHelp();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
module.exports = { run, PLUGINS, listPlugins, showPlugin, enablePlugin, disablePlugin, validatePlugins };
|