@girardmedia/bootspring 1.2.0 → 2.0.3
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 +107 -14
- package/bin/bootspring.js +166 -27
- package/cli/agent.js +189 -17
- package/cli/analyze.js +499 -0
- package/cli/audit.js +557 -0
- package/cli/auth.js +495 -38
- package/cli/billing.js +302 -0
- package/cli/build.js +695 -0
- package/cli/business.js +109 -26
- package/cli/checkpoint-utils.js +168 -0
- package/cli/checkpoint.js +639 -0
- package/cli/cloud-sync.js +447 -0
- package/cli/content.js +198 -0
- package/cli/context.js +1 -1
- package/cli/deploy.js +543 -0
- package/cli/fundraise.js +112 -50
- package/cli/github-cmd.js +435 -0
- package/cli/health.js +477 -0
- package/cli/init.js +84 -13
- package/cli/legal.js +107 -95
- package/cli/log.js +2 -2
- package/cli/loop.js +976 -73
- package/cli/manager.js +711 -0
- package/cli/metrics.js +480 -0
- package/cli/monitor.js +812 -0
- package/cli/onboard.js +521 -0
- package/cli/orchestrator.js +12 -24
- package/cli/prd.js +594 -0
- package/cli/preseed-start.js +1483 -0
- package/cli/preseed.js +2302 -0
- package/cli/project.js +436 -0
- package/cli/quality.js +233 -0
- package/cli/security.js +913 -0
- package/cli/seed.js +1441 -5
- package/cli/skill.js +273 -211
- package/cli/suggest.js +989 -0
- package/cli/switch.js +453 -0
- package/cli/visualize.js +527 -0
- package/cli/watch.js +769 -0
- package/cli/workspace.js +607 -0
- package/core/analyze-workflow.js +1134 -0
- package/core/api-client.js +535 -22
- package/core/audit-workflow.js +1350 -0
- package/core/build-orchestrator.js +480 -0
- package/core/build-state.js +577 -0
- package/core/checkpoint-engine.js +408 -0
- package/core/config.js +1109 -26
- package/core/context-loader.js +21 -1
- package/core/deploy-workflow.js +836 -0
- package/core/entitlements.js +93 -22
- package/core/github-sync.js +610 -0
- package/core/index.js +8 -1
- package/core/ingest.js +1111 -0
- package/core/metrics-engine.js +768 -0
- package/core/onboard-workflow.js +1007 -0
- package/core/preseed-workflow.js +934 -0
- package/core/preseed.js +1617 -0
- package/core/project-context.js +325 -0
- package/core/project-state.js +694 -0
- package/core/r2-sync.js +583 -0
- package/core/scaffold.js +525 -7
- package/core/session.js +258 -0
- package/core/task-extractor.js +758 -0
- package/core/telemetry.js +28 -6
- package/core/tier-enforcement.js +737 -0
- package/core/utils.js +38 -14
- package/generators/questionnaire.js +15 -12
- package/generators/sections/ai.js +7 -7
- package/generators/sections/content.js +300 -0
- package/generators/sections/index.js +3 -0
- package/generators/sections/plugins.js +7 -6
- package/generators/templates/build-planning.template.js +596 -0
- package/generators/templates/content.template.js +819 -0
- package/generators/templates/index.js +2 -1
- package/hooks/git-autopilot.js +1250 -0
- package/hooks/index.js +9 -0
- package/intelligence/agent-collab.js +2057 -0
- package/intelligence/auto-suggest.js +634 -0
- package/intelligence/content-gen.js +1589 -0
- package/intelligence/cross-project.js +1647 -0
- package/intelligence/index.js +184 -0
- package/intelligence/learning/insights.json +517 -7
- package/intelligence/learning/pattern-learner.js +1008 -14
- package/intelligence/memory/decision-tracker.js +1431 -31
- package/intelligence/memory/decisions.jsonl +0 -0
- package/intelligence/orchestrator.js +2896 -1
- package/intelligence/prd.js +92 -1
- package/intelligence/recommendation-weights.json +14 -2
- package/intelligence/recommendations.js +463 -9
- package/intelligence/workflow-composer.js +1451 -0
- package/marketplace/index.d.ts +324 -0
- package/marketplace/index.js +1921 -0
- package/mcp/contracts/mcp-contract.v1.json +342 -4
- package/mcp/registry.js +680 -3
- package/mcp/response-formatter.js +23 -0
- package/mcp/tools/assist-tool.js +78 -4
- package/mcp/tools/autopilot-tool.js +408 -0
- package/mcp/tools/content-tool.js +571 -0
- package/mcp/tools/dashboard-tool.js +251 -5
- package/mcp/tools/mvp-tool.js +344 -0
- package/mcp/tools/plugin-tool.js +23 -1
- package/mcp/tools/prd-tool.js +579 -0
- package/mcp/tools/seed-tool.js +447 -0
- package/mcp/tools/skill-tool.js +43 -14
- package/mcp/tools/suggest-tool.js +147 -0
- package/package.json +15 -6
- package/agents/README.md +0 -93
- package/agents/ai-integration-expert/context.md +0 -386
- package/agents/api-expert/context.md +0 -416
- package/agents/architecture-expert/context.md +0 -454
- package/agents/auth-expert/context.md +0 -399
- package/agents/backend-expert/context.md +0 -483
- package/agents/business-strategy-expert/context.md +0 -180
- package/agents/code-review-expert/context.md +0 -365
- package/agents/competitive-analysis-expert/context.md +0 -239
- package/agents/data-modeling-expert/context.md +0 -352
- package/agents/database-expert/context.md +0 -250
- package/agents/devops-expert/context.md +0 -446
- package/agents/email-expert/context.md +0 -379
- package/agents/financial-expert/context.md +0 -213
- package/agents/frontend-expert/context.md +0 -364
- package/agents/fundraising-expert/context.md +0 -257
- package/agents/growth-expert/context.md +0 -249
- package/agents/index.js +0 -140
- package/agents/investor-relations-expert/context.md +0 -266
- package/agents/legal-expert/context.md +0 -284
- package/agents/marketing-expert/context.md +0 -236
- package/agents/monitoring-expert/context.md +0 -362
- package/agents/operations-expert/context.md +0 -279
- package/agents/partnerships-expert/context.md +0 -286
- package/agents/payment-expert/context.md +0 -340
- package/agents/performance-expert/context.md +0 -377
- package/agents/private-equity-expert/context.md +0 -246
- package/agents/railway-expert/context.md +0 -284
- package/agents/research-expert/context.md +0 -245
- package/agents/sales-expert/context.md +0 -241
- package/agents/security-expert/context.md +0 -343
- package/agents/testing-expert/context.md +0 -414
- package/agents/ui-ux-expert/context.md +0 -448
- package/agents/vercel-expert/context.md +0 -426
- package/skills/index.js +0 -787
- package/skills/patterns/README.md +0 -163
- package/skills/patterns/ai/agents.md +0 -281
- package/skills/patterns/ai/claude.md +0 -138
- package/skills/patterns/ai/embeddings.md +0 -150
- package/skills/patterns/ai/rag.md +0 -266
- package/skills/patterns/ai/streaming.md +0 -170
- package/skills/patterns/ai/structured-output.md +0 -162
- package/skills/patterns/ai/tools.md +0 -154
- package/skills/patterns/analytics/tracking.md +0 -220
- package/skills/patterns/api/errors.md +0 -296
- package/skills/patterns/api/graphql.md +0 -440
- package/skills/patterns/api/middleware.md +0 -279
- package/skills/patterns/api/openapi.md +0 -285
- package/skills/patterns/api/rate-limiting.md +0 -231
- package/skills/patterns/api/route-handler.md +0 -217
- package/skills/patterns/api/server-action.md +0 -249
- package/skills/patterns/api/versioning.md +0 -443
- package/skills/patterns/api/webhooks.md +0 -247
- package/skills/patterns/auth/clerk.md +0 -132
- package/skills/patterns/auth/mfa.md +0 -313
- package/skills/patterns/auth/nextauth.md +0 -140
- package/skills/patterns/auth/oauth.md +0 -237
- package/skills/patterns/auth/rbac.md +0 -152
- package/skills/patterns/auth/session-management.md +0 -367
- package/skills/patterns/auth/session.md +0 -120
- package/skills/patterns/database/audit.md +0 -177
- package/skills/patterns/database/migrations.md +0 -177
- package/skills/patterns/database/pagination.md +0 -230
- package/skills/patterns/database/pooling.md +0 -357
- package/skills/patterns/database/prisma.md +0 -180
- package/skills/patterns/database/relations.md +0 -187
- package/skills/patterns/database/seeding.md +0 -246
- package/skills/patterns/database/soft-delete.md +0 -153
- package/skills/patterns/database/transactions.md +0 -162
- package/skills/patterns/deployment/ci-cd.md +0 -231
- package/skills/patterns/deployment/docker.md +0 -188
- package/skills/patterns/deployment/monitoring.md +0 -387
- package/skills/patterns/deployment/vercel.md +0 -160
- package/skills/patterns/email/resend.md +0 -143
- package/skills/patterns/email/templates.md +0 -245
- package/skills/patterns/email/transactional.md +0 -503
- package/skills/patterns/email/verification.md +0 -176
- package/skills/patterns/files/download.md +0 -243
- package/skills/patterns/files/upload.md +0 -239
- package/skills/patterns/i18n/nextintl.md +0 -188
- package/skills/patterns/logging/structured.md +0 -292
- package/skills/patterns/notifications/email-queue.md +0 -248
- package/skills/patterns/notifications/push.md +0 -279
- package/skills/patterns/payments/checkout.md +0 -303
- package/skills/patterns/payments/invoices.md +0 -287
- package/skills/patterns/payments/portal.md +0 -245
- package/skills/patterns/payments/stripe.md +0 -272
- package/skills/patterns/payments/subscriptions.md +0 -300
- package/skills/patterns/payments/usage.md +0 -279
- package/skills/patterns/performance/caching.md +0 -276
- package/skills/patterns/performance/code-splitting.md +0 -233
- package/skills/patterns/performance/edge.md +0 -254
- package/skills/patterns/performance/isr.md +0 -266
- package/skills/patterns/performance/lazy-loading.md +0 -281
- package/skills/patterns/realtime/sse.md +0 -327
- package/skills/patterns/realtime/websockets.md +0 -336
- package/skills/patterns/search/filtering.md +0 -329
- package/skills/patterns/search/fulltext.md +0 -260
- package/skills/patterns/security/audit-logging.md +0 -444
- package/skills/patterns/security/csrf.md +0 -234
- package/skills/patterns/security/headers.md +0 -252
- package/skills/patterns/security/sanitization.md +0 -258
- package/skills/patterns/security/secrets.md +0 -261
- package/skills/patterns/security/validation.md +0 -268
- package/skills/patterns/security/xss.md +0 -229
- package/skills/patterns/seo/metadata.md +0 -252
- package/skills/patterns/state/context.md +0 -349
- package/skills/patterns/state/react-query.md +0 -313
- package/skills/patterns/state/url-state.md +0 -482
- package/skills/patterns/state/zustand.md +0 -262
- package/skills/patterns/testing/api.md +0 -259
- package/skills/patterns/testing/component.md +0 -233
- package/skills/patterns/testing/coverage.md +0 -207
- package/skills/patterns/testing/fixtures.md +0 -225
- package/skills/patterns/testing/integration.md +0 -436
- package/skills/patterns/testing/mocking.md +0 -177
- package/skills/patterns/testing/playwright.md +0 -162
- package/skills/patterns/testing/snapshot.md +0 -175
- package/skills/patterns/testing/vitest.md +0 -307
- package/skills/patterns/ui/accordions.md +0 -395
- package/skills/patterns/ui/cards.md +0 -299
- package/skills/patterns/ui/dropdowns.md +0 -476
- package/skills/patterns/ui/empty-states.md +0 -320
- package/skills/patterns/ui/forms.md +0 -405
- package/skills/patterns/ui/inputs.md +0 -319
- package/skills/patterns/ui/layouts.md +0 -282
- package/skills/patterns/ui/loading.md +0 -291
- package/skills/patterns/ui/modals.md +0 -338
- package/skills/patterns/ui/navigation.md +0 -374
- package/skills/patterns/ui/tables.md +0 -407
- package/skills/patterns/ui/toasts.md +0 -300
- package/skills/patterns/ui/tooltips.md +0 -396
- package/skills/patterns/utils/dates.md +0 -435
- package/skills/patterns/utils/errors.md +0 -451
- package/skills/patterns/utils/formatting.md +0 -345
- package/skills/patterns/utils/validation.md +0 -434
- package/templates/bootspring.config.js +0 -83
- package/templates/business/business-model-canvas.md +0 -246
- package/templates/business/business-plan.md +0 -266
- package/templates/business/competitive-analysis.md +0 -312
- package/templates/fundraising/data-room-checklist.md +0 -300
- package/templates/fundraising/investor-research.md +0 -243
- package/templates/fundraising/pitch-deck-outline.md +0 -253
- package/templates/legal/gdpr-checklist.md +0 -339
- package/templates/legal/privacy-policy.md +0 -285
- package/templates/legal/terms-of-service.md +0 -222
- package/templates/mcp.json +0 -9
package/cli/onboard.js
ADDED
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootspring Onboard CLI
|
|
3
|
+
*
|
|
4
|
+
* Layer Bootspring onto existing projects with stack detection,
|
|
5
|
+
* pattern scanning, and configuration generation.
|
|
6
|
+
*
|
|
7
|
+
* @package bootspring
|
|
8
|
+
* @module cli/onboard
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const utils = require('../core/utils');
|
|
13
|
+
const { OnboardWorkflowEngine, ONBOARD_PHASES } = require('../core/onboard-workflow');
|
|
14
|
+
|
|
15
|
+
// Get project root
|
|
16
|
+
const projectRoot = process.cwd();
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Show onboard help
|
|
20
|
+
*/
|
|
21
|
+
function showHelp() {
|
|
22
|
+
console.log(`
|
|
23
|
+
${utils.COLORS.bold}Bootspring Onboard${utils.COLORS.reset}
|
|
24
|
+
Layer Bootspring onto existing projects
|
|
25
|
+
|
|
26
|
+
${utils.COLORS.bold}Usage:${utils.COLORS.reset}
|
|
27
|
+
bootspring onboard Start interactive onboarding
|
|
28
|
+
bootspring onboard status Show progress
|
|
29
|
+
bootspring onboard resume Continue from checkpoint
|
|
30
|
+
bootspring onboard detect Run detection only
|
|
31
|
+
bootspring onboard generate Generate config only
|
|
32
|
+
bootspring onboard reset Reset workflow
|
|
33
|
+
|
|
34
|
+
${utils.COLORS.bold}Options:${utils.COLORS.reset}
|
|
35
|
+
--dry-run Preview without changes
|
|
36
|
+
--skip-optional Skip optional phases
|
|
37
|
+
--quick Force fast mode (auto for 500+ files)
|
|
38
|
+
--apply Apply generated files
|
|
39
|
+
|
|
40
|
+
${utils.COLORS.bold}Notes:${utils.COLORS.reset}
|
|
41
|
+
Large codebases (500+ files) automatically use fast mode to skip
|
|
42
|
+
heavy dependency analysis. Use --quick to force it on smaller projects.
|
|
43
|
+
|
|
44
|
+
${utils.COLORS.bold}Examples:${utils.COLORS.reset}
|
|
45
|
+
bootspring onboard Auto-detects and adjusts for codebase size
|
|
46
|
+
bootspring onboard status
|
|
47
|
+
bootspring onboard --dry-run
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Start onboarding workflow
|
|
53
|
+
*/
|
|
54
|
+
async function onboardStart(args) {
|
|
55
|
+
const workflow = new OnboardWorkflowEngine(projectRoot);
|
|
56
|
+
|
|
57
|
+
// Check for existing workflow
|
|
58
|
+
if (workflow.hasWorkflow()) {
|
|
59
|
+
workflow.loadState();
|
|
60
|
+
const progress = workflow.getProgress();
|
|
61
|
+
|
|
62
|
+
if (!progress.isComplete) {
|
|
63
|
+
utils.print.info('Existing onboarding workflow found.');
|
|
64
|
+
console.log(` Progress: ${progress.overall.percentage}% complete`);
|
|
65
|
+
console.log(` Current phase: ${progress.currentPhase || 'none'}`);
|
|
66
|
+
console.log('');
|
|
67
|
+
utils.print.info('Use "bootspring onboard resume" to continue');
|
|
68
|
+
utils.print.info('Use "bootspring onboard reset" to start fresh');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Initialize new workflow
|
|
74
|
+
utils.print.header('Bootspring Onboarding');
|
|
75
|
+
console.log('Analyzing your existing codebase...\n');
|
|
76
|
+
|
|
77
|
+
workflow.initializeWorkflow();
|
|
78
|
+
|
|
79
|
+
// Run workflow
|
|
80
|
+
await runWorkflowLoop(workflow, args);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Resume onboarding workflow
|
|
85
|
+
*/
|
|
86
|
+
async function onboardResume(args) {
|
|
87
|
+
const workflow = new OnboardWorkflowEngine(projectRoot);
|
|
88
|
+
|
|
89
|
+
if (!workflow.hasWorkflow()) {
|
|
90
|
+
utils.print.error('No existing workflow found.');
|
|
91
|
+
utils.print.info('Run "bootspring onboard" to start.');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
workflow.loadState();
|
|
96
|
+
const resumePoint = workflow.getResumePoint();
|
|
97
|
+
|
|
98
|
+
if (!resumePoint) {
|
|
99
|
+
utils.print.success('Onboarding workflow already complete!');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
utils.print.header('Resuming Onboarding');
|
|
104
|
+
console.log(`Continuing from: ${resumePoint.phaseName}`);
|
|
105
|
+
console.log('');
|
|
106
|
+
|
|
107
|
+
await runWorkflowLoop(workflow, args);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Run the workflow loop
|
|
112
|
+
*/
|
|
113
|
+
async function runWorkflowLoop(workflow, args) {
|
|
114
|
+
const dryRun = args['dry-run'] || false;
|
|
115
|
+
const skipOptional = args['skip-optional'] || false;
|
|
116
|
+
const quickMode = args.quick || false;
|
|
117
|
+
|
|
118
|
+
while (true) {
|
|
119
|
+
const nextPhaseId = workflow.getNextPhase();
|
|
120
|
+
|
|
121
|
+
if (!nextPhaseId) {
|
|
122
|
+
// Workflow complete
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const phase = ONBOARD_PHASES[nextPhaseId];
|
|
127
|
+
|
|
128
|
+
// Skip optional phases if requested
|
|
129
|
+
if (skipOptional && !phase.required) {
|
|
130
|
+
workflow.skipPhase(nextPhaseId);
|
|
131
|
+
utils.print.dim(`Skipping optional phase: ${phase.name}`);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Run the phase
|
|
136
|
+
workflow.startPhase(nextPhaseId);
|
|
137
|
+
const spinner = utils.createSpinner(`Running: ${phase.name}`).start();
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
let result;
|
|
141
|
+
|
|
142
|
+
switch (nextPhaseId) {
|
|
143
|
+
case 'detection':
|
|
144
|
+
result = await workflow.runDetection();
|
|
145
|
+
spinner.succeed(`Detection complete: Found ${result.stack.detected.length} technologies`);
|
|
146
|
+
displayDetectionResults(result);
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
case 'patterns':
|
|
150
|
+
if (quickMode) {
|
|
151
|
+
// Quick mode: skip heavy dependency analysis, just detect features
|
|
152
|
+
result = await workflow.runQuickPatternScan();
|
|
153
|
+
spinner.succeed('Quick pattern scan complete');
|
|
154
|
+
} else {
|
|
155
|
+
result = await workflow.runPatternScan();
|
|
156
|
+
if (result.quickMode) {
|
|
157
|
+
// Auto-detected large codebase
|
|
158
|
+
spinner.succeed('Pattern scan complete (large codebase - quick mode)');
|
|
159
|
+
} else {
|
|
160
|
+
spinner.succeed(`Pattern scan complete: ${result.architecture.patterns.length} patterns found`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
displayPatternResults(result);
|
|
164
|
+
break;
|
|
165
|
+
|
|
166
|
+
case 'docs':
|
|
167
|
+
result = await workflow.runDocDiscovery();
|
|
168
|
+
spinner.succeed(`Doc discovery complete: ${result.found.length} docs found, ${result.missing.length} missing`);
|
|
169
|
+
displayDocResults(result);
|
|
170
|
+
break;
|
|
171
|
+
|
|
172
|
+
case 'config':
|
|
173
|
+
result = await workflow.runConfigGeneration();
|
|
174
|
+
spinner.succeed('Configuration generated');
|
|
175
|
+
displayConfigResults(result, dryRun);
|
|
176
|
+
break;
|
|
177
|
+
|
|
178
|
+
case 'baseline':
|
|
179
|
+
result = await workflow.runBaselineCapture();
|
|
180
|
+
spinner.succeed('Baseline captured');
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case 'reverse':
|
|
184
|
+
// Skip for now - optional
|
|
185
|
+
spinner.info('Skipping reverse engineering (optional)');
|
|
186
|
+
workflow.skipPhase(nextPhaseId);
|
|
187
|
+
continue;
|
|
188
|
+
|
|
189
|
+
default:
|
|
190
|
+
spinner.warn(`Unknown phase: ${nextPhaseId}`);
|
|
191
|
+
workflow.skipPhase(nextPhaseId);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
workflow.completePhase(nextPhaseId, result);
|
|
196
|
+
|
|
197
|
+
} catch (error) {
|
|
198
|
+
spinner.fail(`Failed: ${error.message}`);
|
|
199
|
+
workflow.failPhase(nextPhaseId, error.message);
|
|
200
|
+
|
|
201
|
+
if (phase.required) {
|
|
202
|
+
utils.print.error('Required phase failed. Cannot continue.');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.log('');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Workflow complete
|
|
211
|
+
utils.print.success('Onboarding complete!');
|
|
212
|
+
console.log('');
|
|
213
|
+
|
|
214
|
+
const progress = workflow.getProgress();
|
|
215
|
+
|
|
216
|
+
// Apply files if requested
|
|
217
|
+
const shouldApply = args.apply || false;
|
|
218
|
+
if (shouldApply && !dryRun) {
|
|
219
|
+
utils.print.info('Applying generated files...');
|
|
220
|
+
workflow.applyGeneratedFiles();
|
|
221
|
+
utils.print.success('bootspring.config.js and CLAUDE.md created');
|
|
222
|
+
} else if (!dryRun) {
|
|
223
|
+
utils.print.info('Generated files are in .bootspring/onboard/generated/');
|
|
224
|
+
utils.print.info('Run with --apply to copy them to project root');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Show summary
|
|
228
|
+
console.log('');
|
|
229
|
+
utils.print.header('Summary');
|
|
230
|
+
console.log(` Stack: ${formatStack(progress.detection?.stack)}`);
|
|
231
|
+
console.log(` Phases completed: ${progress.overall.completed}/${progress.overall.total}`);
|
|
232
|
+
console.log('');
|
|
233
|
+
utils.print.info('Next steps:');
|
|
234
|
+
console.log(' 1. Review generated configuration');
|
|
235
|
+
console.log(' 2. Run "bootspring analyze" for deeper insights');
|
|
236
|
+
console.log(' 3. Run "bootspring audit" for quality checks');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Display detection results
|
|
241
|
+
*/
|
|
242
|
+
function displayDetectionResults(result) {
|
|
243
|
+
console.log('');
|
|
244
|
+
|
|
245
|
+
if (result.stack.framework) {
|
|
246
|
+
console.log(` ${utils.COLORS.cyan}Framework:${utils.COLORS.reset} ${result.stack.framework.name}`);
|
|
247
|
+
}
|
|
248
|
+
if (result.stack.language) {
|
|
249
|
+
console.log(` ${utils.COLORS.cyan}Language:${utils.COLORS.reset} ${result.stack.language.name}`);
|
|
250
|
+
}
|
|
251
|
+
if (result.stack.database) {
|
|
252
|
+
console.log(` ${utils.COLORS.cyan}Database:${utils.COLORS.reset} ${result.stack.database.name}`);
|
|
253
|
+
}
|
|
254
|
+
if (result.stack.hosting) {
|
|
255
|
+
console.log(` ${utils.COLORS.cyan}Hosting:${utils.COLORS.reset} ${result.stack.hosting.name}`);
|
|
256
|
+
}
|
|
257
|
+
if (result.stack.auth) {
|
|
258
|
+
console.log(` ${utils.COLORS.cyan}Auth:${utils.COLORS.reset} ${result.stack.auth.name}`);
|
|
259
|
+
}
|
|
260
|
+
if (result.stack.payments) {
|
|
261
|
+
console.log(` ${utils.COLORS.cyan}Payments:${utils.COLORS.reset} ${result.stack.payments.name}`);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log('');
|
|
265
|
+
console.log(` ${utils.COLORS.dim}Files: ${result.structure.stats.totalFiles} | Dirs: ${result.structure.stats.totalDirs}${utils.COLORS.reset}`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Display pattern results
|
|
270
|
+
*/
|
|
271
|
+
function displayPatternResults(result) {
|
|
272
|
+
if (result.architecture.patterns.length > 0) {
|
|
273
|
+
console.log('');
|
|
274
|
+
console.log(' Detected patterns:');
|
|
275
|
+
for (const pattern of result.architecture.patterns.slice(0, 3)) {
|
|
276
|
+
console.log(` - ${pattern.name} (${pattern.confidence}%)`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (result.features) {
|
|
281
|
+
const activeFeatures = Object.entries(result.features)
|
|
282
|
+
.filter(([, v]) => v)
|
|
283
|
+
.map(([k]) => k);
|
|
284
|
+
|
|
285
|
+
if (activeFeatures.length > 0) {
|
|
286
|
+
console.log('');
|
|
287
|
+
console.log(' Detected features:');
|
|
288
|
+
console.log(` ${activeFeatures.join(', ')}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Display documentation results
|
|
295
|
+
*/
|
|
296
|
+
function displayDocResults(result) {
|
|
297
|
+
if (result.found.length > 0) {
|
|
298
|
+
console.log('');
|
|
299
|
+
console.log(' Found documentation:');
|
|
300
|
+
for (const doc of result.found.slice(0, 5)) {
|
|
301
|
+
console.log(` ${utils.COLORS.green}✓${utils.COLORS.reset} ${doc.file}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (result.missing.length > 0) {
|
|
306
|
+
console.log('');
|
|
307
|
+
console.log(' Missing (recommended):');
|
|
308
|
+
for (const doc of result.missing) {
|
|
309
|
+
console.log(` ${utils.COLORS.yellow}○${utils.COLORS.reset} ${doc.file}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Display config generation results
|
|
316
|
+
*/
|
|
317
|
+
function displayConfigResults(result, dryRun) {
|
|
318
|
+
console.log('');
|
|
319
|
+
|
|
320
|
+
if (dryRun) {
|
|
321
|
+
console.log(` ${utils.COLORS.dim}[DRY RUN] Would generate:${utils.COLORS.reset}`);
|
|
322
|
+
} else {
|
|
323
|
+
console.log(' Generated:');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
console.log(' - bootspring.config.js');
|
|
327
|
+
console.log(' - CLAUDE.md');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Format stack for display
|
|
332
|
+
*/
|
|
333
|
+
function formatStack(stack) {
|
|
334
|
+
if (!stack) return 'Unknown';
|
|
335
|
+
|
|
336
|
+
const parts = [];
|
|
337
|
+
if (stack.framework) parts.push(stack.framework.name);
|
|
338
|
+
if (stack.language) parts.push(stack.language.name);
|
|
339
|
+
if (stack.database) parts.push(stack.database.name);
|
|
340
|
+
|
|
341
|
+
return parts.join(' + ') || 'Unknown';
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Show onboard status
|
|
346
|
+
*/
|
|
347
|
+
async function onboardStatus() {
|
|
348
|
+
const workflow = new OnboardWorkflowEngine(projectRoot);
|
|
349
|
+
|
|
350
|
+
if (!workflow.hasWorkflow()) {
|
|
351
|
+
utils.print.info('No onboarding workflow started.');
|
|
352
|
+
utils.print.info('Run "bootspring onboard" to begin.');
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
workflow.loadState();
|
|
357
|
+
const progress = workflow.getProgress();
|
|
358
|
+
|
|
359
|
+
utils.print.header('Onboarding Status');
|
|
360
|
+
|
|
361
|
+
// Overall progress
|
|
362
|
+
console.log(`Progress: ${progress.overall.percentage}% complete`);
|
|
363
|
+
console.log(`Started: ${progress.startedAt ? new Date(progress.startedAt).toLocaleString() : 'N/A'}`);
|
|
364
|
+
console.log(`Last updated: ${progress.lastUpdated ? utils.formatRelativeTime(new Date(progress.lastUpdated)) : 'N/A'}`);
|
|
365
|
+
console.log('');
|
|
366
|
+
|
|
367
|
+
// Phase status
|
|
368
|
+
console.log('Phases:');
|
|
369
|
+
for (const phase of progress.phases) {
|
|
370
|
+
const statusIcon = getStatusIcon(phase.status);
|
|
371
|
+
const required = phase.required ? '' : ' (optional)';
|
|
372
|
+
console.log(` ${statusIcon} ${phase.name}${required}`);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
console.log('');
|
|
376
|
+
|
|
377
|
+
// Detection summary if available
|
|
378
|
+
if (progress.detection?.stack) {
|
|
379
|
+
console.log('Detected stack:');
|
|
380
|
+
console.log(` ${formatStack(progress.detection.stack)}`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (!progress.isComplete) {
|
|
384
|
+
console.log('');
|
|
385
|
+
utils.print.info('Run "bootspring onboard resume" to continue');
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Run detection only
|
|
391
|
+
*/
|
|
392
|
+
async function onboardDetect() {
|
|
393
|
+
const workflow = new OnboardWorkflowEngine(projectRoot);
|
|
394
|
+
workflow.initializeWorkflow();
|
|
395
|
+
|
|
396
|
+
const spinner = utils.createSpinner('Detecting stack...').start();
|
|
397
|
+
|
|
398
|
+
try {
|
|
399
|
+
const result = await workflow.runDetection();
|
|
400
|
+
spinner.succeed('Detection complete');
|
|
401
|
+
|
|
402
|
+
displayDetectionResults(result);
|
|
403
|
+
} catch (error) {
|
|
404
|
+
spinner.fail(`Detection failed: ${error.message}`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Generate config only
|
|
410
|
+
*/
|
|
411
|
+
async function onboardGenerate(args) {
|
|
412
|
+
const workflow = new OnboardWorkflowEngine(projectRoot);
|
|
413
|
+
|
|
414
|
+
// Need detection first
|
|
415
|
+
if (!workflow.hasWorkflow()) {
|
|
416
|
+
workflow.initializeWorkflow();
|
|
417
|
+
|
|
418
|
+
const spinner = utils.createSpinner('Running detection first...').start();
|
|
419
|
+
await workflow.runDetection();
|
|
420
|
+
workflow.completePhase('detection');
|
|
421
|
+
|
|
422
|
+
await workflow.runPatternScan();
|
|
423
|
+
workflow.completePhase('patterns');
|
|
424
|
+
|
|
425
|
+
spinner.succeed('Detection complete');
|
|
426
|
+
} else {
|
|
427
|
+
workflow.loadState();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const spinner = utils.createSpinner('Generating configuration...').start();
|
|
431
|
+
|
|
432
|
+
try {
|
|
433
|
+
const result = await workflow.runConfigGeneration();
|
|
434
|
+
spinner.succeed('Configuration generated');
|
|
435
|
+
|
|
436
|
+
displayConfigResults(result, args['dry-run']);
|
|
437
|
+
|
|
438
|
+
if (args.apply) {
|
|
439
|
+
workflow.applyGeneratedFiles();
|
|
440
|
+
utils.print.success('Files applied to project root');
|
|
441
|
+
} else {
|
|
442
|
+
console.log('');
|
|
443
|
+
utils.print.info('Files saved to .bootspring/onboard/generated/');
|
|
444
|
+
utils.print.info('Run with --apply to copy to project root');
|
|
445
|
+
}
|
|
446
|
+
} catch (error) {
|
|
447
|
+
spinner.fail(`Generation failed: ${error.message}`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Reset onboard workflow
|
|
453
|
+
*/
|
|
454
|
+
async function onboardReset() {
|
|
455
|
+
const workflow = new OnboardWorkflowEngine(projectRoot);
|
|
456
|
+
|
|
457
|
+
if (!workflow.hasWorkflow()) {
|
|
458
|
+
utils.print.info('No workflow to reset.');
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
workflow.resetWorkflow();
|
|
463
|
+
utils.print.success('Onboarding workflow reset.');
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Get status icon
|
|
468
|
+
*/
|
|
469
|
+
function getStatusIcon(status) {
|
|
470
|
+
switch (status) {
|
|
471
|
+
case 'completed':
|
|
472
|
+
return `${utils.COLORS.green}✓${utils.COLORS.reset}`;
|
|
473
|
+
case 'in_progress':
|
|
474
|
+
return `${utils.COLORS.cyan}●${utils.COLORS.reset}`;
|
|
475
|
+
case 'failed':
|
|
476
|
+
return `${utils.COLORS.red}✗${utils.COLORS.reset}`;
|
|
477
|
+
case 'skipped':
|
|
478
|
+
return `${utils.COLORS.dim}○${utils.COLORS.reset}`;
|
|
479
|
+
default:
|
|
480
|
+
return `${utils.COLORS.dim}○${utils.COLORS.reset}`;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Main entry point
|
|
486
|
+
*/
|
|
487
|
+
async function run(args) {
|
|
488
|
+
const parsedArgs = utils.parseArgs(args);
|
|
489
|
+
const subcommand = parsedArgs._[0] || 'start';
|
|
490
|
+
|
|
491
|
+
switch (subcommand) {
|
|
492
|
+
case 'start':
|
|
493
|
+
return onboardStart(parsedArgs);
|
|
494
|
+
|
|
495
|
+
case 'status':
|
|
496
|
+
return onboardStatus();
|
|
497
|
+
|
|
498
|
+
case 'resume':
|
|
499
|
+
return onboardResume(parsedArgs);
|
|
500
|
+
|
|
501
|
+
case 'detect':
|
|
502
|
+
return onboardDetect();
|
|
503
|
+
|
|
504
|
+
case 'generate':
|
|
505
|
+
return onboardGenerate(parsedArgs);
|
|
506
|
+
|
|
507
|
+
case 'reset':
|
|
508
|
+
return onboardReset();
|
|
509
|
+
|
|
510
|
+
case 'help':
|
|
511
|
+
case '--help':
|
|
512
|
+
case '-h':
|
|
513
|
+
return showHelp();
|
|
514
|
+
|
|
515
|
+
default:
|
|
516
|
+
// If no subcommand, start workflow
|
|
517
|
+
return onboardStart(parsedArgs);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
module.exports = { run };
|
package/cli/orchestrator.js
CHANGED
|
@@ -83,15 +83,16 @@ async function run(args) {
|
|
|
83
83
|
* Analyze context and suggest agents
|
|
84
84
|
*/
|
|
85
85
|
function runAnalyze(context) {
|
|
86
|
-
|
|
87
|
-
if (!utils.requireMCP('Intelligence analysis')) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
86
|
+
const isMCP = utils.isMCPContext();
|
|
90
87
|
|
|
91
88
|
console.log(`
|
|
92
89
|
${utils.COLORS.cyan}${utils.COLORS.bold}Intelligence Analysis${utils.COLORS.reset}
|
|
93
90
|
`);
|
|
94
91
|
|
|
92
|
+
if (!isMCP) {
|
|
93
|
+
utils.print.dim('Note: Running in CLI mode. Use with Claude MCP for enhanced analysis.\n');
|
|
94
|
+
}
|
|
95
|
+
|
|
95
96
|
const analysis = intelligence.analyzeContext(context);
|
|
96
97
|
|
|
97
98
|
console.log(`${utils.COLORS.bold}Current Phase:${utils.COLORS.reset} ${analysis.phase} - ${analysis.phaseConfig?.name || 'Unknown'}`);
|
|
@@ -149,11 +150,6 @@ function runWorkflow(name, accessOptions = {}) {
|
|
|
149
150
|
return;
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
// Require MCP for workflow details
|
|
153
|
-
if (!utils.requireMCP('Workflow details')) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
153
|
const workflow = intelligence.getWorkflow(name);
|
|
158
154
|
|
|
159
155
|
if (!workflow) {
|
|
@@ -233,11 +229,6 @@ ${utils.COLORS.cyan}${utils.COLORS.bold}Available Workflows${utils.COLORS.reset}
|
|
|
233
229
|
* Start a workflow
|
|
234
230
|
*/
|
|
235
231
|
function runStartWorkflow(name, accessOptions = {}) {
|
|
236
|
-
// Require MCP for workflow execution
|
|
237
|
-
if (!utils.requireMCP('Workflow execution')) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
232
|
if (!name) {
|
|
242
233
|
utils.print.error('Usage: bootspring orchestrator start <workflow-name>');
|
|
243
234
|
return;
|
|
@@ -270,11 +261,6 @@ function runStartWorkflow(name, accessOptions = {}) {
|
|
|
270
261
|
* Advance to next workflow step
|
|
271
262
|
*/
|
|
272
263
|
function runNextStep() {
|
|
273
|
-
// Require MCP for workflow execution
|
|
274
|
-
if (!utils.requireMCP('Workflow execution')) {
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
264
|
const result = intelligence.advanceWorkflow();
|
|
279
265
|
|
|
280
266
|
if (result.success) {
|
|
@@ -298,10 +284,12 @@ function runStatus() {
|
|
|
298
284
|
const currentPhase = intelligence.getCurrentPhase();
|
|
299
285
|
const phaseConfig = intelligence.PHASE_AGENTS[currentPhase];
|
|
300
286
|
const agents = intelligence.getAvailableAgents();
|
|
287
|
+
const isMCP = utils.isMCPContext();
|
|
301
288
|
|
|
302
289
|
console.log(`
|
|
303
290
|
${utils.COLORS.cyan}${utils.COLORS.bold}Orchestrator Status${utils.COLORS.reset}
|
|
304
291
|
|
|
292
|
+
${utils.COLORS.bold}Mode:${utils.COLORS.reset} ${isMCP ? `${utils.COLORS.green}MCP (full)${utils.COLORS.reset}` : `${utils.COLORS.yellow}CLI (limited)${utils.COLORS.reset}`}
|
|
305
293
|
${utils.COLORS.bold}Current Phase:${utils.COLORS.reset} ${currentPhase} - ${phaseConfig?.name || 'Unknown'}
|
|
306
294
|
${utils.COLORS.bold}Last Analysis:${utils.COLORS.reset} ${state.lastAnalysis || 'Never'}
|
|
307
295
|
${utils.COLORS.bold}Active Workflow:${utils.COLORS.reset} ${state.activeWorkflow || 'None'}
|
|
@@ -324,14 +312,14 @@ ${utils.COLORS.bold}Active Workflow:${utils.COLORS.reset} ${state.activeWorkflow
|
|
|
324
312
|
}
|
|
325
313
|
|
|
326
314
|
console.log(`\n${utils.COLORS.bold}Available Agents:${utils.COLORS.reset} ${agents.length}`);
|
|
327
|
-
}
|
|
328
315
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return;
|
|
316
|
+
if (!isMCP) {
|
|
317
|
+
console.log(`
|
|
318
|
+
${utils.COLORS.dim}Enable MCP for enhanced orchestration: bootspring mcp start${utils.COLORS.reset}`);
|
|
333
319
|
}
|
|
320
|
+
}
|
|
334
321
|
|
|
322
|
+
function runCheckpoint(workflowName, signalRef, accessOptions = {}) {
|
|
335
323
|
const targetWorkflowName = workflowName || intelligence.loadState().activeWorkflow;
|
|
336
324
|
if (targetWorkflowName) {
|
|
337
325
|
const workflow = intelligence.getWorkflow(targetWorkflowName);
|