@girardmedia/bootspring 2.1.3 → 2.2.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/bin/bootspring.js +102 -82
- package/generators/api-docs.js +3 -3
- package/generators/decisions.js +14 -14
- package/generators/health.js +6 -6
- package/generators/sprint.js +4 -4
- package/generators/templates/build-planning.template.js +2 -2
- package/generators/visual-doc-generator.js +1 -1
- package/package.json +2 -15
- package/cli/agent.js +0 -799
- package/cli/auth.js +0 -896
- package/cli/billing.js +0 -320
- package/cli/build.js +0 -1442
- package/cli/dashboard.js +0 -123
- package/cli/init.js +0 -669
- package/cli/mcp.js +0 -240
- package/cli/orchestrator.js +0 -240
- package/cli/project.js +0 -825
- package/cli/quality.js +0 -281
- package/cli/skill.js +0 -503
- package/cli/switch.js +0 -453
- package/cli/todo.js +0 -629
- package/cli/update.js +0 -132
package/cli/agent.js
DELETED
|
@@ -1,799 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bootspring Agent Command
|
|
3
|
-
* Work with specialized AI agents
|
|
4
|
-
*
|
|
5
|
-
* @package bootspring
|
|
6
|
-
* @command agent
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const crypto = require('crypto');
|
|
10
|
-
const utils = require('../core/utils');
|
|
11
|
-
const telemetry = require('../core/telemetry');
|
|
12
|
-
const tierEnforcement = require('../core/tier-enforcement');
|
|
13
|
-
const api = require('../core/api-client');
|
|
14
|
-
const auth = require('../core/auth');
|
|
15
|
-
|
|
16
|
-
// Re-export AGENT_TIERS from tier-enforcement for compatibility
|
|
17
|
-
const { AGENT_TIERS, checkAgentAccess: canAccessAgent } = tierEnforcement;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Track agent invocation via telemetry
|
|
21
|
-
*/
|
|
22
|
-
function trackAgentInvocation(agentId, topic = null) {
|
|
23
|
-
try {
|
|
24
|
-
telemetry.emitEvent('agent.invoked', {
|
|
25
|
-
agent: agentId,
|
|
26
|
-
topic: topic ? topic.substring(0, 100) : null, // Truncate for privacy
|
|
27
|
-
timestamp: new Date().toISOString()
|
|
28
|
-
});
|
|
29
|
-
} catch {
|
|
30
|
-
// Telemetry should never break the command
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function trackTelemetry(event, payload = {}) {
|
|
35
|
-
try {
|
|
36
|
-
telemetry.emitEvent(event, payload);
|
|
37
|
-
} catch {
|
|
38
|
-
// Never block command flow on telemetry issues.
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getUpgradePromptContext(agentId, requiredTier = 'pro') {
|
|
43
|
-
if (typeof tierEnforcement.getUpgradePromptContext === 'function') {
|
|
44
|
-
return tierEnforcement.getUpgradePromptContext(`agent: ${agentId}`, requiredTier, {
|
|
45
|
-
capability: 'agent_access',
|
|
46
|
-
action: 'agent_invoke'
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
feature: `agent: ${agentId}`,
|
|
52
|
-
featureType: 'agent',
|
|
53
|
-
featureLabel: `Agent ${agentId}`,
|
|
54
|
-
capability: 'agent_access',
|
|
55
|
-
action: 'agent_invoke',
|
|
56
|
-
requiredTier,
|
|
57
|
-
userTier: typeof tierEnforcement.getTier === 'function' ? tierEnforcement.getTier() : 'free',
|
|
58
|
-
placement: 'inline',
|
|
59
|
-
variant: 'control'
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function trackUpgradePrompted(agentId, requiredTier, reason = 'agent_subscription_required') {
|
|
64
|
-
const promptContext = getUpgradePromptContext(agentId, requiredTier || 'pro');
|
|
65
|
-
trackTelemetry('premium_prompted', {
|
|
66
|
-
...promptContext,
|
|
67
|
-
agent: agentId,
|
|
68
|
-
reason
|
|
69
|
-
});
|
|
70
|
-
return promptContext;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function trackUpgradeUnlocked(agentId, requiredTier) {
|
|
74
|
-
const promptContext = getUpgradePromptContext(agentId, requiredTier || 'pro');
|
|
75
|
-
trackTelemetry('premium_unlocked', {
|
|
76
|
-
...promptContext,
|
|
77
|
-
agent: agentId
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function normalizeChecksum(checksum) {
|
|
82
|
-
const raw = String(checksum || '').trim().toLowerCase();
|
|
83
|
-
if (!raw) return '';
|
|
84
|
-
return raw.startsWith('sha256:') ? raw.slice(7) : raw;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function verifyPayloadIntegrity(agentId, content, checksum, options = {}) {
|
|
88
|
-
const { requireChecksum = false } = options;
|
|
89
|
-
const expected = normalizeChecksum(checksum);
|
|
90
|
-
if (requireChecksum && !expected) {
|
|
91
|
-
throw new Error(`Integrity metadata missing for agent payload: ${agentId}`);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const digest = crypto.createHash('sha256').update(String(content || ''), 'utf8').digest('hex');
|
|
95
|
-
if (expected && expected !== digest) {
|
|
96
|
-
throw new Error(`Integrity check failed for agent payload: ${agentId}`);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
algorithm: 'sha256',
|
|
101
|
-
checksum: `sha256:${digest}`,
|
|
102
|
-
expected: expected ? `sha256:${expected}` : null,
|
|
103
|
-
verified: !!expected
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Fetch agent context from API (thin client model)
|
|
109
|
-
* Agent context is not bundled locally - must be fetched from API
|
|
110
|
-
* @param {string} agentId - Agent ID
|
|
111
|
-
* @returns {Promise<{context: string, name: string}|null>}
|
|
112
|
-
*/
|
|
113
|
-
async function fetchAgentContext(agentId) {
|
|
114
|
-
if (!auth.isAuthenticated()) {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
const response = await api.getAgentContext(agentId);
|
|
120
|
-
const responseTier = String(response?.tier || AGENT_TIERS[agentId] || 'free').toLowerCase();
|
|
121
|
-
const requiredTier = AGENT_TIERS[agentId] || (responseTier === 'pro' || responseTier === 'premium' ? 'pro' : 'free');
|
|
122
|
-
if (requiredTier !== 'free' && !tierEnforcement.meetsTierRequirement(requiredTier, auth.getTier())) {
|
|
123
|
-
return { error: 'upgrade_required', requiredTier };
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const integrity = verifyPayloadIntegrity(agentId, response?.context || '', response?.checksum, {
|
|
127
|
-
requireChecksum: Boolean(response?.checksum)
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
return { ...response, integrity };
|
|
131
|
-
} catch (error) {
|
|
132
|
-
if (error.message && error.message.toLowerCase().includes('integrity')) {
|
|
133
|
-
return { error: 'integrity_error', message: error.message };
|
|
134
|
-
}
|
|
135
|
-
if (error.status === 403) {
|
|
136
|
-
// Tier not sufficient - will be handled by canAccessAgent
|
|
137
|
-
return { error: 'upgrade_required', requiredTier: error.requiredTier };
|
|
138
|
-
}
|
|
139
|
-
if (error.status === 401) {
|
|
140
|
-
return { error: 'auth_required' };
|
|
141
|
-
}
|
|
142
|
-
// Network error or other issue
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async function fetchHostedAgentCatalog() {
|
|
148
|
-
if (!auth.isAuthenticated()) {
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const response = await api.listAgents();
|
|
154
|
-
return response.agents || null;
|
|
155
|
-
} catch {
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async function resolveAgentDefinition(agentId) {
|
|
161
|
-
if (auth.isAuthenticated()) {
|
|
162
|
-
try {
|
|
163
|
-
const response = await api.getAgent(agentId);
|
|
164
|
-
return response.agent || response;
|
|
165
|
-
} catch {
|
|
166
|
-
// Fall back to bundled metadata for discovery.
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return AGENTS[agentId] || null;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Agent definitions - these will be loaded from agents/profiles/ in production
|
|
174
|
-
const AGENTS = {
|
|
175
|
-
'database-expert': {
|
|
176
|
-
name: 'Database Expert',
|
|
177
|
-
category: 'Backend',
|
|
178
|
-
description: 'Specializes in database design, queries, migrations, and optimization',
|
|
179
|
-
expertise: ['SQL', 'NoSQL', 'Prisma', 'Drizzle', 'PostgreSQL', 'MongoDB'],
|
|
180
|
-
triggers: ['database', 'schema', 'migration', 'query', 'prisma', 'sql']
|
|
181
|
-
},
|
|
182
|
-
'security-expert': {
|
|
183
|
-
name: 'Security Expert',
|
|
184
|
-
category: 'Security',
|
|
185
|
-
description: 'Focuses on application security, OWASP, authentication, and authorization',
|
|
186
|
-
expertise: ['OWASP', 'Authentication', 'Authorization', 'Input Validation', 'XSS', 'CSRF'],
|
|
187
|
-
triggers: ['security', 'auth', 'owasp', 'vulnerability', 'xss', 'csrf', 'injection']
|
|
188
|
-
},
|
|
189
|
-
'frontend-expert': {
|
|
190
|
-
name: 'Frontend Expert',
|
|
191
|
-
category: 'Frontend',
|
|
192
|
-
description: 'Expert in React, Next.js, UI components, and modern frontend patterns',
|
|
193
|
-
expertise: ['React', 'Next.js', 'TypeScript', 'Tailwind', 'Components', 'State Management'],
|
|
194
|
-
triggers: ['component', 'react', 'frontend', 'ui', 'tailwind', 'css', 'styling']
|
|
195
|
-
},
|
|
196
|
-
'backend-expert': {
|
|
197
|
-
name: 'Backend Expert',
|
|
198
|
-
category: 'Backend',
|
|
199
|
-
description: 'Specializes in server-side development, APIs, and business logic',
|
|
200
|
-
expertise: ['Node.js', 'APIs', 'Server Actions', 'Middleware', 'Business Logic'],
|
|
201
|
-
triggers: ['api', 'backend', 'server', 'endpoint', 'route', 'middleware']
|
|
202
|
-
},
|
|
203
|
-
'api-expert': {
|
|
204
|
-
name: 'API Expert',
|
|
205
|
-
category: 'Backend',
|
|
206
|
-
description: 'Focuses on API design, REST, GraphQL, and integration patterns',
|
|
207
|
-
expertise: ['REST', 'GraphQL', 'tRPC', 'OpenAPI', 'Webhooks', 'Integration'],
|
|
208
|
-
triggers: ['api', 'rest', 'graphql', 'trpc', 'webhook', 'endpoint']
|
|
209
|
-
},
|
|
210
|
-
'testing-expert': {
|
|
211
|
-
name: 'Testing Expert',
|
|
212
|
-
category: 'Quality',
|
|
213
|
-
description: 'Expert in testing strategies, test frameworks, and quality assurance',
|
|
214
|
-
expertise: ['Unit Testing', 'Integration Testing', 'E2E', 'Vitest', 'Jest', 'Playwright'],
|
|
215
|
-
triggers: ['test', 'testing', 'jest', 'vitest', 'playwright', 'coverage']
|
|
216
|
-
},
|
|
217
|
-
'performance-expert': {
|
|
218
|
-
name: 'Performance Expert',
|
|
219
|
-
category: 'DevOps',
|
|
220
|
-
description: 'Specializes in performance optimization, caching, and monitoring',
|
|
221
|
-
expertise: ['Optimization', 'Caching', 'Profiling', 'Core Web Vitals', 'Load Testing'],
|
|
222
|
-
triggers: ['performance', 'optimize', 'cache', 'slow', 'speed', 'profiling']
|
|
223
|
-
},
|
|
224
|
-
'devops-expert': {
|
|
225
|
-
name: 'DevOps Expert',
|
|
226
|
-
category: 'DevOps',
|
|
227
|
-
description: 'Focuses on deployment, CI/CD, infrastructure, and monitoring',
|
|
228
|
-
expertise: ['CI/CD', 'Docker', 'Kubernetes', 'Monitoring', 'Infrastructure'],
|
|
229
|
-
triggers: ['deploy', 'ci', 'cd', 'docker', 'kubernetes', 'infrastructure']
|
|
230
|
-
},
|
|
231
|
-
'ui-ux-expert': {
|
|
232
|
-
name: 'UI/UX Expert',
|
|
233
|
-
category: 'Frontend',
|
|
234
|
-
description: 'Expert in user interface design, user experience, and accessibility',
|
|
235
|
-
expertise: ['Design Systems', 'Accessibility', 'Responsive Design', 'Animation'],
|
|
236
|
-
triggers: ['ui', 'ux', 'design', 'accessibility', 'a11y', 'responsive']
|
|
237
|
-
},
|
|
238
|
-
'architecture-expert': {
|
|
239
|
-
name: 'Architecture Expert',
|
|
240
|
-
category: 'Backend',
|
|
241
|
-
description: 'Specializes in system architecture, design patterns, and scalability',
|
|
242
|
-
expertise: ['System Design', 'Design Patterns', 'Microservices', 'Scalability'],
|
|
243
|
-
triggers: ['architecture', 'design', 'pattern', 'scalability', 'structure']
|
|
244
|
-
},
|
|
245
|
-
'code-review-expert': {
|
|
246
|
-
name: 'Code Review Expert',
|
|
247
|
-
category: 'Quality',
|
|
248
|
-
description: 'Focuses on code quality, best practices, and constructive feedback',
|
|
249
|
-
expertise: ['Code Quality', 'Best Practices', 'Refactoring', 'Clean Code'],
|
|
250
|
-
triggers: ['review', 'refactor', 'quality', 'clean', 'improve']
|
|
251
|
-
},
|
|
252
|
-
'vercel-expert': {
|
|
253
|
-
name: 'Vercel Expert',
|
|
254
|
-
category: 'DevOps',
|
|
255
|
-
description: 'Expert in Vercel deployment, serverless, and edge functions',
|
|
256
|
-
expertise: ['Vercel', 'Serverless', 'Edge Functions', 'ISR', 'Deployment'],
|
|
257
|
-
triggers: ['vercel', 'serverless', 'edge', 'deployment', 'hosting']
|
|
258
|
-
},
|
|
259
|
-
// Business Agents
|
|
260
|
-
'business-strategy-expert': {
|
|
261
|
-
name: 'Business Strategy Expert',
|
|
262
|
-
category: 'Business',
|
|
263
|
-
description: 'Specializes in business model design, market analysis, and strategic planning',
|
|
264
|
-
expertise: ['Business Models', 'Market Analysis', 'Competitive Strategy', 'Go-to-Market', 'Unit Economics'],
|
|
265
|
-
triggers: ['business', 'strategy', 'market', 'model', 'gtm', 'positioning']
|
|
266
|
-
},
|
|
267
|
-
'financial-expert': {
|
|
268
|
-
name: 'Financial Expert',
|
|
269
|
-
category: 'Business',
|
|
270
|
-
description: 'Expert in financial modeling, projections, and startup finance',
|
|
271
|
-
expertise: ['Financial Modeling', 'Revenue Projections', 'Unit Economics', 'Cash Flow', 'Budgeting'],
|
|
272
|
-
triggers: ['financial', 'finance', 'revenue', 'projection', 'budget', 'cash', 'model']
|
|
273
|
-
},
|
|
274
|
-
'fundraising-expert': {
|
|
275
|
-
name: 'Fundraising Expert',
|
|
276
|
-
category: 'Business',
|
|
277
|
-
description: 'Specializes in investor relations, pitch decks, and fundraising strategy',
|
|
278
|
-
expertise: ['Pitch Decks', 'Investor Relations', 'Term Sheets', 'Due Diligence', 'Fundraising Strategy'],
|
|
279
|
-
triggers: ['fundraise', 'investor', 'pitch', 'deck', 'seed', 'series', 'vc', 'angel']
|
|
280
|
-
},
|
|
281
|
-
'private-equity-expert': {
|
|
282
|
-
name: 'Private Equity Expert',
|
|
283
|
-
category: 'Business',
|
|
284
|
-
description: 'Expert in PE/VC dynamics, valuation, and deal structuring',
|
|
285
|
-
expertise: ['Valuation', 'Deal Structure', 'Cap Tables', 'Term Sheets', 'Exit Strategy'],
|
|
286
|
-
triggers: ['pe', 'equity', 'valuation', 'cap table', 'term sheet', 'dilution']
|
|
287
|
-
},
|
|
288
|
-
'investor-relations-expert': {
|
|
289
|
-
name: 'Investor Relations Expert',
|
|
290
|
-
category: 'Business',
|
|
291
|
-
description: 'Specializes in investor communications, reporting, and stakeholder management',
|
|
292
|
-
expertise: ['Investor Updates', 'Board Management', 'KPI Reporting', 'Stakeholder Communication'],
|
|
293
|
-
triggers: ['investor', 'board', 'update', 'reporting', 'stakeholder']
|
|
294
|
-
},
|
|
295
|
-
'legal-expert': {
|
|
296
|
-
name: 'Legal Expert',
|
|
297
|
-
category: 'Business',
|
|
298
|
-
description: 'Expert in startup legal matters, contracts, and compliance',
|
|
299
|
-
expertise: ['Terms of Service', 'Privacy Policy', 'Contracts', 'IP', 'Compliance', 'GDPR'],
|
|
300
|
-
triggers: ['legal', 'terms', 'privacy', 'contract', 'compliance', 'gdpr', 'ip']
|
|
301
|
-
},
|
|
302
|
-
'marketing-expert': {
|
|
303
|
-
name: 'Marketing Expert',
|
|
304
|
-
category: 'Business',
|
|
305
|
-
description: 'Specializes in digital marketing, content strategy, and brand building',
|
|
306
|
-
expertise: ['Content Marketing', 'SEO', 'Social Media', 'Email Marketing', 'Brand Strategy'],
|
|
307
|
-
triggers: ['marketing', 'content', 'seo', 'social', 'brand', 'campaign']
|
|
308
|
-
},
|
|
309
|
-
'sales-expert': {
|
|
310
|
-
name: 'Sales Expert',
|
|
311
|
-
category: 'Business',
|
|
312
|
-
description: 'Expert in sales strategy, pipeline management, and customer acquisition',
|
|
313
|
-
expertise: ['Sales Strategy', 'Pipeline Management', 'CRM', 'Lead Generation', 'Closing'],
|
|
314
|
-
triggers: ['sales', 'pipeline', 'lead', 'crm', 'close', 'deal', 'prospect']
|
|
315
|
-
},
|
|
316
|
-
'growth-expert': {
|
|
317
|
-
name: 'Growth Expert',
|
|
318
|
-
category: 'Business',
|
|
319
|
-
description: 'Specializes in growth hacking, metrics, and user acquisition',
|
|
320
|
-
expertise: ['Growth Hacking', 'User Acquisition', 'Retention', 'Viral Loops', 'A/B Testing'],
|
|
321
|
-
triggers: ['growth', 'acquisition', 'retention', 'viral', 'metrics', 'experiment']
|
|
322
|
-
},
|
|
323
|
-
'operations-expert': {
|
|
324
|
-
name: 'Operations Expert',
|
|
325
|
-
category: 'Business',
|
|
326
|
-
description: 'Expert in operational efficiency, processes, and team management',
|
|
327
|
-
expertise: ['Process Design', 'Team Management', 'Hiring', 'OKRs', 'Operational Efficiency'],
|
|
328
|
-
triggers: ['operations', 'ops', 'process', 'team', 'hiring', 'okr', 'efficiency']
|
|
329
|
-
},
|
|
330
|
-
'competitive-analysis-expert': {
|
|
331
|
-
name: 'Competitive Analysis Expert',
|
|
332
|
-
category: 'Business',
|
|
333
|
-
description: 'Specializes in market research, competitor analysis, and positioning',
|
|
334
|
-
expertise: ['Competitor Analysis', 'Market Research', 'SWOT', 'Positioning', 'Differentiation'],
|
|
335
|
-
triggers: ['competitive', 'competitor', 'analysis', 'market', 'swot', 'positioning']
|
|
336
|
-
},
|
|
337
|
-
'partnerships-expert': {
|
|
338
|
-
name: 'Partnerships Expert',
|
|
339
|
-
category: 'Business',
|
|
340
|
-
description: 'Expert in partnership development, BD, and strategic alliances',
|
|
341
|
-
expertise: ['Partnership Development', 'Business Development', 'Strategic Alliances', 'Channel Partners'],
|
|
342
|
-
triggers: ['partnership', 'partner', 'bd', 'alliance', 'channel', 'integration']
|
|
343
|
-
},
|
|
344
|
-
// DevOps Agents
|
|
345
|
-
'railway-expert': {
|
|
346
|
-
name: 'Railway Expert',
|
|
347
|
-
category: 'DevOps',
|
|
348
|
-
description: 'Expert in Railway deployment, databases, and infrastructure',
|
|
349
|
-
expertise: ['Railway', 'PostgreSQL', 'Redis', 'Deployment', 'Scaling'],
|
|
350
|
-
triggers: ['railway', 'deploy', 'postgres', 'redis', 'infrastructure']
|
|
351
|
-
},
|
|
352
|
-
'monitoring-expert': {
|
|
353
|
-
name: 'Monitoring Expert',
|
|
354
|
-
category: 'DevOps',
|
|
355
|
-
description: 'Specializes in observability, logging, metrics, and alerting',
|
|
356
|
-
expertise: ['Observability', 'Logging', 'Metrics', 'Alerting', 'APM', 'Sentry', 'Datadog'],
|
|
357
|
-
triggers: ['monitoring', 'logging', 'metrics', 'alerts', 'observability', 'sentry']
|
|
358
|
-
},
|
|
359
|
-
// Research Agents
|
|
360
|
-
'research-expert': {
|
|
361
|
-
name: 'Research Expert',
|
|
362
|
-
category: 'Research',
|
|
363
|
-
description: 'Expert in market research, user research, and data analysis',
|
|
364
|
-
expertise: ['Market Research', 'User Research', 'Surveys', 'Interviews', 'Data Analysis'],
|
|
365
|
-
triggers: ['research', 'survey', 'interview', 'user research', 'market research']
|
|
366
|
-
},
|
|
367
|
-
'data-modeling-expert': {
|
|
368
|
-
name: 'Data Modeling Expert',
|
|
369
|
-
category: 'Research',
|
|
370
|
-
description: 'Specializes in data architecture, ERD design, and schema optimization',
|
|
371
|
-
expertise: ['ERD Design', 'Schema Design', 'Normalization', 'Indexing', 'Data Architecture'],
|
|
372
|
-
triggers: ['data model', 'erd', 'schema', 'entity', 'relationship', 'normalization']
|
|
373
|
-
},
|
|
374
|
-
// Integration Agents
|
|
375
|
-
'payment-expert': {
|
|
376
|
-
name: 'Payment Expert',
|
|
377
|
-
category: 'Integration',
|
|
378
|
-
description: 'Expert in payment processing, Stripe integration, and subscription billing',
|
|
379
|
-
expertise: ['Stripe', 'Subscriptions', 'Billing', 'Webhooks', 'Checkout', 'Payment Processing'],
|
|
380
|
-
triggers: ['payment', 'stripe', 'subscription', 'billing', 'checkout', 'invoice']
|
|
381
|
-
},
|
|
382
|
-
'ai-integration-expert': {
|
|
383
|
-
name: 'AI Integration Expert',
|
|
384
|
-
category: 'Integration',
|
|
385
|
-
description: 'Specializes in AI/LLM integration, Anthropic Claude, and AI SDK',
|
|
386
|
-
expertise: ['Claude API', 'AI SDK', 'Streaming', 'Tool Use', 'RAG', 'Embeddings'],
|
|
387
|
-
triggers: ['ai', 'llm', 'claude', 'anthropic', 'openai', 'streaming', 'embedding']
|
|
388
|
-
},
|
|
389
|
-
'email-expert': {
|
|
390
|
-
name: 'Email Expert',
|
|
391
|
-
category: 'Integration',
|
|
392
|
-
description: 'Expert in email integration, Resend, and transactional emails',
|
|
393
|
-
expertise: ['Resend', 'React Email', 'Transactional Email', 'Templates', 'Email Delivery'],
|
|
394
|
-
triggers: ['email', 'resend', 'sendgrid', 'template', 'notification', 'transactional']
|
|
395
|
-
},
|
|
396
|
-
'auth-expert': {
|
|
397
|
-
name: 'Auth Expert',
|
|
398
|
-
category: 'Integration',
|
|
399
|
-
description: 'Specializes in authentication, Clerk, NextAuth, and session management',
|
|
400
|
-
expertise: ['Clerk', 'NextAuth', 'OAuth', 'JWT', 'Session Management', 'RBAC'],
|
|
401
|
-
triggers: ['auth', 'authentication', 'login', 'session', 'oauth', 'clerk', 'nextauth']
|
|
402
|
-
},
|
|
403
|
-
// Content Agents
|
|
404
|
-
'content-expert': {
|
|
405
|
-
name: 'Content Expert',
|
|
406
|
-
category: 'Content',
|
|
407
|
-
description: 'Expert in technical writing, documentation, blogs, marketing copy, and content strategy',
|
|
408
|
-
expertise: ['Technical Writing', 'Documentation', 'Blog Posts', 'Release Notes', 'README', 'API Docs', 'SEO', 'Content Strategy'],
|
|
409
|
-
triggers: ['content', 'writing', 'documentation', 'docs', 'blog', 'readme', 'changelog', 'copy', 'article', 'marketing']
|
|
410
|
-
},
|
|
411
|
-
// Product Agents
|
|
412
|
-
'product-expert': {
|
|
413
|
-
name: 'Product Expert',
|
|
414
|
-
category: 'Product',
|
|
415
|
-
description: 'Expert in product management, roadmapping, feature prioritization, and user research',
|
|
416
|
-
expertise: ['Product Strategy', 'Roadmapping', 'Feature Prioritization', 'User Research', 'PRDs', 'OKRs', 'Metrics', 'Product-Market Fit'],
|
|
417
|
-
triggers: ['product', 'roadmap', 'feature', 'prioritization', 'prd', 'requirements', 'user research', 'okr', 'metrics', 'backlog']
|
|
418
|
-
},
|
|
419
|
-
// Mobile Agents
|
|
420
|
-
'mobile-expert': {
|
|
421
|
-
name: 'Mobile Expert',
|
|
422
|
-
category: 'Mobile',
|
|
423
|
-
description: 'Expert in mobile development with React Native, Flutter, iOS, and Android',
|
|
424
|
-
expertise: ['React Native', 'Flutter', 'iOS', 'Android', 'Mobile Architecture', 'App Store', 'Push Notifications', 'Offline-First'],
|
|
425
|
-
triggers: ['mobile', 'react native', 'flutter', 'ios', 'android', 'app', 'native', 'swift', 'kotlin', 'expo']
|
|
426
|
-
},
|
|
427
|
-
// Infrastructure Agents
|
|
428
|
-
'infrastructure-expert': {
|
|
429
|
-
name: 'Infrastructure Expert',
|
|
430
|
-
category: 'DevOps',
|
|
431
|
-
description: 'Expert in cloud infrastructure, Terraform, Kubernetes, and DevOps practices',
|
|
432
|
-
expertise: ['AWS', 'GCP', 'Azure', 'Terraform', 'Kubernetes', 'Docker', 'CI/CD', 'Infrastructure-as-Code', 'Cloud Architecture'],
|
|
433
|
-
triggers: ['infrastructure', 'cloud', 'aws', 'gcp', 'terraform', 'kubernetes', 'k8s', 'docker', 'devops', 'iac']
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* List all available agents
|
|
439
|
-
*/
|
|
440
|
-
async function listAgents() {
|
|
441
|
-
const userTier = tierEnforcement.getTier();
|
|
442
|
-
const hostedAgents = await fetchHostedAgentCatalog();
|
|
443
|
-
|
|
444
|
-
console.log(`
|
|
445
|
-
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Agents${utils.COLORS.reset}
|
|
446
|
-
${utils.COLORS.dim}Specialized AI expertise on demand${utils.COLORS.reset}
|
|
447
|
-
${utils.COLORS.dim}Your tier: ${userTier}${utils.COLORS.reset}
|
|
448
|
-
`);
|
|
449
|
-
|
|
450
|
-
const catalog = Array.isArray(hostedAgents) && hostedAgents.length > 0
|
|
451
|
-
? hostedAgents.map((agent) => ({
|
|
452
|
-
id: agent.id,
|
|
453
|
-
name: agent.name,
|
|
454
|
-
category: agent.category || 'Hosted',
|
|
455
|
-
description: agent.description,
|
|
456
|
-
expertise: agent.expertise || [],
|
|
457
|
-
accessible: agent.accessible,
|
|
458
|
-
requiredTier: agent.requiredTier || AGENT_TIERS[agent.id] || 'free'
|
|
459
|
-
}))
|
|
460
|
-
: Object.entries(AGENTS).map(([id, agent]) => ({
|
|
461
|
-
id,
|
|
462
|
-
...agent,
|
|
463
|
-
accessible: canAccessAgent(id).allowed,
|
|
464
|
-
requiredTier: AGENT_TIERS[id] || 'free'
|
|
465
|
-
}));
|
|
466
|
-
|
|
467
|
-
const categories = {};
|
|
468
|
-
for (const agent of catalog) {
|
|
469
|
-
if (!categories[agent.category]) {
|
|
470
|
-
categories[agent.category] = [];
|
|
471
|
-
}
|
|
472
|
-
categories[agent.category].push(agent);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
let accessibleCount = 0;
|
|
476
|
-
let lockedCount = 0;
|
|
477
|
-
|
|
478
|
-
for (const [category, agents] of Object.entries(categories)) {
|
|
479
|
-
console.log(`${utils.COLORS.bold}${category}${utils.COLORS.reset}`);
|
|
480
|
-
for (const agent of agents) {
|
|
481
|
-
const accessible = agent.accessible !== false;
|
|
482
|
-
const requiredTier = agent.requiredTier || AGENT_TIERS[agent.id];
|
|
483
|
-
const tierBadge = requiredTier && requiredTier !== 'free'
|
|
484
|
-
? ` ${utils.COLORS.yellow}[${requiredTier}]${utils.COLORS.reset}`
|
|
485
|
-
: '';
|
|
486
|
-
const lockIcon = accessible ? '' : ` ${utils.COLORS.red}🔒${utils.COLORS.reset}`;
|
|
487
|
-
|
|
488
|
-
if (accessible) {
|
|
489
|
-
accessibleCount++;
|
|
490
|
-
} else {
|
|
491
|
-
lockedCount++;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
console.log(` ${utils.COLORS.cyan}${agent.id}${utils.COLORS.reset}${tierBadge}${lockIcon}`);
|
|
495
|
-
console.log(` ${utils.COLORS.dim}${agent.description}${utils.COLORS.reset}`);
|
|
496
|
-
}
|
|
497
|
-
console.log();
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
utils.print.dim(`${accessibleCount} agents available, ${lockedCount} locked`);
|
|
501
|
-
utils.print.dim('Use "bootspring agent show <name>" for details');
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Show agent details
|
|
506
|
-
*/
|
|
507
|
-
async function showAgent(agentId) {
|
|
508
|
-
const agent = await resolveAgentDefinition(agentId);
|
|
509
|
-
|
|
510
|
-
if (!agent) {
|
|
511
|
-
utils.print.error(`Agent not found: ${agentId}`);
|
|
512
|
-
utils.print.dim('Use "bootspring agent list" to see available agents');
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const expertise = Array.isArray(agent.expertise) ? agent.expertise : [];
|
|
517
|
-
const triggers = Array.isArray(agent.triggers) ? agent.triggers : [];
|
|
518
|
-
|
|
519
|
-
console.log(`
|
|
520
|
-
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ ${agent.name}${utils.COLORS.reset}
|
|
521
|
-
${utils.COLORS.dim}Category: ${agent.category || 'Hosted'}${utils.COLORS.reset}
|
|
522
|
-
|
|
523
|
-
${utils.COLORS.bold}Description${utils.COLORS.reset}
|
|
524
|
-
${agent.description}
|
|
525
|
-
|
|
526
|
-
${utils.COLORS.bold}Expertise${utils.COLORS.reset}
|
|
527
|
-
${expertise.length > 0 ? expertise.map(e => ` ${utils.COLORS.green}●${utils.COLORS.reset} ${e}`).join('\n') : ` ${utils.COLORS.dim}Hosted agent expertise${utils.COLORS.reset}`}
|
|
528
|
-
|
|
529
|
-
${utils.COLORS.bold}Trigger Keywords${utils.COLORS.reset}
|
|
530
|
-
${triggers.length > 0 ? triggers.map(t => ` ${utils.COLORS.dim}${t}${utils.COLORS.reset}`).join(', ') : ` ${utils.COLORS.dim}Server-managed${utils.COLORS.reset}`}
|
|
531
|
-
|
|
532
|
-
${utils.COLORS.bold}Usage${utils.COLORS.reset}
|
|
533
|
-
bootspring agent invoke ${agentId} --topic "your question"
|
|
534
|
-
`);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/**
|
|
538
|
-
* Invoke an agent
|
|
539
|
-
*/
|
|
540
|
-
async function invokeAgent(agentId, args) {
|
|
541
|
-
const agent = await resolveAgentDefinition(agentId);
|
|
542
|
-
|
|
543
|
-
if (!agent) {
|
|
544
|
-
utils.print.error(`Agent not found: ${agentId}`);
|
|
545
|
-
utils.print.dim('Use "bootspring agent list" to see available agents');
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// Check authentication first
|
|
550
|
-
if (!auth.isAuthenticated()) {
|
|
551
|
-
console.log(`
|
|
552
|
-
${utils.COLORS.yellow}${utils.COLORS.bold}⚡ ${agent.name}${utils.COLORS.reset}
|
|
553
|
-
${utils.COLORS.red}Authentication required${utils.COLORS.reset}
|
|
554
|
-
|
|
555
|
-
${utils.COLORS.dim}Agent context is served from the API. Please log in:${utils.COLORS.reset}
|
|
556
|
-
${utils.COLORS.cyan}bootspring auth login${utils.COLORS.reset}
|
|
557
|
-
`);
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Check tier access (client-side check for UX, server enforces)
|
|
562
|
-
const access = canAccessAgent(agentId);
|
|
563
|
-
if (!access.allowed) {
|
|
564
|
-
const promptContext = trackUpgradePrompted(agentId, access.requiredTier || 'pro');
|
|
565
|
-
console.log(`
|
|
566
|
-
${utils.COLORS.yellow}${utils.COLORS.bold}⚡ ${agent.name}${utils.COLORS.reset}
|
|
567
|
-
${utils.COLORS.red}This agent requires ${access.requiredTier} tier or higher.${utils.COLORS.reset}
|
|
568
|
-
`);
|
|
569
|
-
console.log(tierEnforcement.getUpgradePrompt(`agent: ${agentId}`, access.requiredTier || 'pro', {
|
|
570
|
-
capability: promptContext.capability,
|
|
571
|
-
action: promptContext.action,
|
|
572
|
-
placement: promptContext.placement,
|
|
573
|
-
variant: promptContext.variant
|
|
574
|
-
}));
|
|
575
|
-
return;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
const isMCP = utils.isMCPContext();
|
|
579
|
-
const parsedArgs = utils.parseArgs(args);
|
|
580
|
-
const topic = parsedArgs.topic || args.filter(a => !a.startsWith('--')).join(' ');
|
|
581
|
-
|
|
582
|
-
// Track agent invocation
|
|
583
|
-
trackAgentInvocation(agentId, topic);
|
|
584
|
-
|
|
585
|
-
console.log(`
|
|
586
|
-
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ ${agent.name}${utils.COLORS.reset}
|
|
587
|
-
${utils.COLORS.dim}${agent.description}${utils.COLORS.reset}
|
|
588
|
-
`);
|
|
589
|
-
|
|
590
|
-
// Fetch agent context from API (thin client - no local content)
|
|
591
|
-
const spinner = utils.createSpinner('Loading agent context...');
|
|
592
|
-
spinner.start();
|
|
593
|
-
|
|
594
|
-
const contextResult = await fetchAgentContext(agentId);
|
|
595
|
-
|
|
596
|
-
if (!contextResult) {
|
|
597
|
-
spinner.fail('Failed to load agent context');
|
|
598
|
-
console.log(`${utils.COLORS.dim}Check your internet connection and try again.${utils.COLORS.reset}`);
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
if (contextResult.error === 'upgrade_required') {
|
|
603
|
-
const promptContext = trackUpgradePrompted(agentId, contextResult.requiredTier || 'pro');
|
|
604
|
-
spinner.fail('Upgrade required');
|
|
605
|
-
console.log(tierEnforcement.getUpgradePrompt(`agent: ${agentId}`, contextResult.requiredTier || 'pro', {
|
|
606
|
-
capability: promptContext.capability,
|
|
607
|
-
action: promptContext.action,
|
|
608
|
-
placement: promptContext.placement,
|
|
609
|
-
variant: promptContext.variant
|
|
610
|
-
}));
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
if (contextResult.error === 'auth_required') {
|
|
615
|
-
spinner.fail('Authentication required');
|
|
616
|
-
console.log(`${utils.COLORS.dim}Run: bootspring auth login${utils.COLORS.reset}`);
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
if (contextResult.error === 'integrity_error') {
|
|
621
|
-
spinner.fail('Integrity verification failed');
|
|
622
|
-
console.log(`${utils.COLORS.dim}${contextResult.message || 'Agent payload checksum mismatch.'}${utils.COLORS.reset}`);
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
spinner.succeed('Agent context loaded');
|
|
627
|
-
const responseTier = String(contextResult.tier || AGENT_TIERS[agentId] || 'free').toLowerCase();
|
|
628
|
-
const requiredTier = AGENT_TIERS[agentId] || (responseTier === 'pro' || responseTier === 'premium' ? 'pro' : 'free');
|
|
629
|
-
if (requiredTier !== 'free') {
|
|
630
|
-
trackUpgradeUnlocked(agentId, requiredTier);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// In MCP mode, output the context for the AI to use
|
|
634
|
-
if (isMCP) {
|
|
635
|
-
console.log(`\n${utils.COLORS.bold}Agent Context:${utils.COLORS.reset}\n`);
|
|
636
|
-
console.log(contextResult.context);
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
// CLI mode - show context and guidance
|
|
641
|
-
console.log(`\n${utils.COLORS.bold}Agent Context:${utils.COLORS.reset}`);
|
|
642
|
-
console.log(`${utils.COLORS.dim}─────────────────────────────────────${utils.COLORS.reset}`);
|
|
643
|
-
|
|
644
|
-
// Show truncated context in CLI mode
|
|
645
|
-
const contextLines = contextResult.context.split('\n');
|
|
646
|
-
const previewLines = contextLines.slice(0, 20);
|
|
647
|
-
console.log(previewLines.join('\n'));
|
|
648
|
-
|
|
649
|
-
if (contextLines.length > 20) {
|
|
650
|
-
console.log(`\n${utils.COLORS.dim}... (${contextLines.length - 20} more lines)${utils.COLORS.reset}`);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
console.log(`${utils.COLORS.dim}─────────────────────────────────────${utils.COLORS.reset}`);
|
|
654
|
-
|
|
655
|
-
if (topic) {
|
|
656
|
-
console.log(`\n${utils.COLORS.bold}Your topic:${utils.COLORS.reset} "${topic}"
|
|
657
|
-
${utils.COLORS.dim}Use this context with your AI assistant for the topic above.${utils.COLORS.reset}
|
|
658
|
-
`);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
console.log(`
|
|
662
|
-
${utils.COLORS.bold}Usage:${utils.COLORS.reset}
|
|
663
|
-
Copy the context above and use it with your AI assistant.
|
|
664
|
-
|
|
665
|
-
${utils.COLORS.yellow}${utils.COLORS.bold}Enhanced Mode${utils.COLORS.reset}
|
|
666
|
-
${utils.COLORS.dim}With MCP integration, agents activate automatically.${utils.COLORS.reset}
|
|
667
|
-
${utils.COLORS.cyan}bootspring mcp start${utils.COLORS.reset}
|
|
668
|
-
`);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Search for agents by keyword
|
|
673
|
-
*/
|
|
674
|
-
async function searchAgents(query) {
|
|
675
|
-
const hostedAgents = await fetchHostedAgentCatalog();
|
|
676
|
-
const queryLower = query.toLowerCase();
|
|
677
|
-
|
|
678
|
-
const catalog = Array.isArray(hostedAgents) && hostedAgents.length > 0
|
|
679
|
-
? hostedAgents.map((agent) => [agent.id, {
|
|
680
|
-
name: agent.name,
|
|
681
|
-
description: agent.description,
|
|
682
|
-
expertise: agent.expertise || [],
|
|
683
|
-
triggers: agent.triggers || []
|
|
684
|
-
}])
|
|
685
|
-
: Object.entries(AGENTS);
|
|
686
|
-
|
|
687
|
-
const matches = catalog.filter(([id, agent]) => (
|
|
688
|
-
id.includes(queryLower) ||
|
|
689
|
-
agent.name.toLowerCase().includes(queryLower) ||
|
|
690
|
-
agent.description.toLowerCase().includes(queryLower) ||
|
|
691
|
-
agent.expertise.some(e => e.toLowerCase().includes(queryLower)) ||
|
|
692
|
-
agent.triggers.some(t => t.includes(queryLower))
|
|
693
|
-
));
|
|
694
|
-
|
|
695
|
-
if (matches.length === 0) {
|
|
696
|
-
utils.print.warning(`No agents found matching "${query}"`);
|
|
697
|
-
utils.print.dim('Use "bootspring agent list" to see all agents');
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
console.log(`
|
|
702
|
-
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Agent Search: "${query}"${utils.COLORS.reset}
|
|
703
|
-
`);
|
|
704
|
-
|
|
705
|
-
for (const [id, agent] of matches) {
|
|
706
|
-
console.log(` ${utils.COLORS.cyan}${id}${utils.COLORS.reset} - ${agent.description}`);
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
console.log();
|
|
710
|
-
utils.print.dim(`${matches.length} agents found`);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Show agent help
|
|
715
|
-
*/
|
|
716
|
-
function showHelp() {
|
|
717
|
-
console.log(`
|
|
718
|
-
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring Agent${utils.COLORS.reset}
|
|
719
|
-
${utils.COLORS.dim}Work with specialized AI agents${utils.COLORS.reset}
|
|
720
|
-
|
|
721
|
-
${utils.COLORS.bold}Usage:${utils.COLORS.reset}
|
|
722
|
-
bootspring agent <command> [args]
|
|
723
|
-
|
|
724
|
-
${utils.COLORS.bold}Commands:${utils.COLORS.reset}
|
|
725
|
-
${utils.COLORS.cyan}list${utils.COLORS.reset} List all available agents
|
|
726
|
-
${utils.COLORS.cyan}show${utils.COLORS.reset} <name> Show agent details
|
|
727
|
-
${utils.COLORS.cyan}invoke${utils.COLORS.reset} <name> Invoke an agent
|
|
728
|
-
${utils.COLORS.cyan}search${utils.COLORS.reset} <query> Search for agents
|
|
729
|
-
|
|
730
|
-
${utils.COLORS.bold}Examples:${utils.COLORS.reset}
|
|
731
|
-
bootspring agent list
|
|
732
|
-
bootspring agent show security-expert
|
|
733
|
-
bootspring agent invoke database-expert --topic "optimize queries"
|
|
734
|
-
bootspring agent search performance
|
|
735
|
-
`);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* Run agent command
|
|
740
|
-
*/
|
|
741
|
-
async function run(args) {
|
|
742
|
-
const subcommand = args[0] || 'list';
|
|
743
|
-
const subargs = args.slice(1);
|
|
744
|
-
|
|
745
|
-
switch (subcommand) {
|
|
746
|
-
case 'list':
|
|
747
|
-
case 'ls':
|
|
748
|
-
await listAgents();
|
|
749
|
-
break;
|
|
750
|
-
|
|
751
|
-
case 'show':
|
|
752
|
-
case 'info':
|
|
753
|
-
if (!subargs[0]) {
|
|
754
|
-
utils.print.error('Please specify an agent name');
|
|
755
|
-
utils.print.dim('Usage: bootspring agent show <name>');
|
|
756
|
-
return;
|
|
757
|
-
}
|
|
758
|
-
await showAgent(subargs[0]);
|
|
759
|
-
break;
|
|
760
|
-
|
|
761
|
-
case 'invoke':
|
|
762
|
-
case 'use':
|
|
763
|
-
case 'call':
|
|
764
|
-
if (!subargs[0]) {
|
|
765
|
-
utils.print.error('Please specify an agent name');
|
|
766
|
-
utils.print.dim('Usage: bootspring agent invoke <name> --topic "your question"');
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
await invokeAgent(subargs[0], subargs.slice(1));
|
|
770
|
-
break;
|
|
771
|
-
|
|
772
|
-
case 'search':
|
|
773
|
-
case 'find':
|
|
774
|
-
if (!subargs[0]) {
|
|
775
|
-
utils.print.error('Please specify a search query');
|
|
776
|
-
utils.print.dim('Usage: bootspring agent search <query>');
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
await searchAgents(subargs.join(' '));
|
|
780
|
-
break;
|
|
781
|
-
|
|
782
|
-
case 'help':
|
|
783
|
-
case '-h':
|
|
784
|
-
case '--help':
|
|
785
|
-
showHelp();
|
|
786
|
-
break;
|
|
787
|
-
|
|
788
|
-
default:
|
|
789
|
-
// Check if it's an agent name (shortcut for show)
|
|
790
|
-
if (AGENTS[subcommand]) {
|
|
791
|
-
await showAgent(subcommand);
|
|
792
|
-
} else {
|
|
793
|
-
utils.print.error(`Unknown subcommand: ${subcommand}`);
|
|
794
|
-
showHelp();
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
module.exports = { run, AGENTS, listAgents, showAgent, invokeAgent, searchAgents };
|