codebakers 2.0.4 → 2.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.
@@ -0,0 +1,7 @@
1
+ import {
2
+ advisorsCommand
3
+ } from "./chunk-FWQNLNTI.js";
4
+ import "./chunk-RCC7FYEU.js";
5
+ export {
6
+ advisorsCommand
7
+ };
@@ -0,0 +1,565 @@
1
+ import {
2
+ Config
3
+ } from "./chunk-RCC7FYEU.js";
4
+
5
+ // src/commands/advisors.ts
6
+ import * as p from "@clack/prompts";
7
+ import chalk from "chalk";
8
+ import * as fs from "fs-extra";
9
+ import * as path from "path";
10
+ import Anthropic from "@anthropic-ai/sdk";
11
+ var DREAM_TEAM = [
12
+ {
13
+ name: "Sarah Chen",
14
+ role: "CEO & Strategist",
15
+ icon: "\u{1F469}\u200D\u{1F4BC}",
16
+ expertise: "Business strategy, market positioning, fundraising, go-to-market",
17
+ personality: "Direct, strategic thinker, asks hard questions about market fit and business viability"
18
+ },
19
+ {
20
+ name: "Marcus Johnson",
21
+ role: "Full Stack Engineer",
22
+ icon: "\u{1F468}\u200D\u{1F4BB}",
23
+ expertise: "System architecture, scalability, tech stack selection, development timeline",
24
+ personality: "Pragmatic, focused on what can actually be built, warns about technical debt"
25
+ },
26
+ {
27
+ name: "Elena Rodriguez",
28
+ role: "UX/UI Specialist",
29
+ icon: "\u{1F469}\u200D\u{1F3A8}",
30
+ expertise: "User research, interface design, user journeys, accessibility, design systems",
31
+ personality: "User-obsessed, pushes back on features that hurt UX, advocates for simplicity"
32
+ },
33
+ {
34
+ name: "David Park",
35
+ role: "Marketing Director",
36
+ icon: "\u{1F4E3}",
37
+ expertise: "Growth strategy, content marketing, social media, brand positioning, launch campaigns",
38
+ personality: "Creative, data-driven, thinks about virality and word-of-mouth"
39
+ },
40
+ {
41
+ name: "Aisha Patel",
42
+ role: "Product Manager",
43
+ icon: "\u{1F4CB}",
44
+ expertise: "Feature prioritization, roadmaps, user stories, MVP scoping, competitive analysis",
45
+ personality: "Organized, balances user needs with business goals, ruthless prioritizer"
46
+ }
47
+ ];
48
+ async function advisorsCommand() {
49
+ const config = new Config();
50
+ if (!config.isConfigured()) {
51
+ p.log.error("Please run `codebakers setup` first.");
52
+ return;
53
+ }
54
+ const anthropicCreds = config.getCredentials("anthropic");
55
+ if (!anthropicCreds?.apiKey) {
56
+ p.log.error("Anthropic API key not configured.");
57
+ return;
58
+ }
59
+ console.log(chalk.cyan(`
60
+ \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E
61
+ \u2502 \u2502
62
+ \u2502 \u{1F31F} CODEBAKERS DREAM TEAM ADVISORS \u{1F31F} \u2502
63
+ \u2502 \u2502
64
+ \u2502 Meet your advisory board: \u2502
65
+ \u2502 \u2502
66
+ \u2502 \u{1F469}\u200D\u{1F4BC} Sarah Chen - CEO & Strategist \u2502
67
+ \u2502 \u{1F468}\u200D\u{1F4BB} Marcus Johnson - Full Stack Engineer \u2502
68
+ \u2502 \u{1F469}\u200D\u{1F3A8} Elena Rodriguez - UX/UI Specialist \u2502
69
+ \u2502 \u{1F4E3} David Park - Marketing Director \u2502
70
+ \u2502 \u{1F4CB} Aisha Patel - Product Manager \u2502
71
+ \u2502 \u2502
72
+ \u2502 They'll interview you about your project, provide expert \u2502
73
+ \u2502 feedback, and create a comprehensive plan including: \u2502
74
+ \u2502 \u2502
75
+ \u2502 \u2022 Technical architecture & implementation plan \u2502
76
+ \u2502 \u2022 Marketing & social media strategy \u2502
77
+ \u2502 \u2022 UX/UI recommendations & user journeys \u2502
78
+ \u2502 \u2022 Business model & revenue projections \u2502
79
+ \u2502 \u2022 Risk assessment & mitigation strategies \u2502
80
+ \u2502 \u2022 Prioritized action items \u2502
81
+ \u2502 \u2502
82
+ \u2502 \u{1F4C4} You'll receive a complete PDF report at the end. \u2502
83
+ \u2502 \u2502
84
+ \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F
85
+ `));
86
+ const start = await p.confirm({
87
+ message: "Ready to meet the Dream Team?",
88
+ initialValue: true
89
+ });
90
+ if (!start || p.isCancel(start)) {
91
+ p.cancel("Maybe next time!");
92
+ return;
93
+ }
94
+ const brief = await conductInterview();
95
+ if (!brief) return;
96
+ const anthropic = new Anthropic({ apiKey: anthropicCreds.apiKey });
97
+ console.log(chalk.bold("\n\n\u{1F3AF} The Dream Team is reviewing your project...\n"));
98
+ const advisorFeedback = [];
99
+ for (const advisor of DREAM_TEAM) {
100
+ const spinner3 = p.spinner();
101
+ spinner3.start(`${advisor.icon} ${advisor.name} is analyzing...`);
102
+ const feedback = await getAdvisorFeedback(anthropic, advisor, brief);
103
+ advisorFeedback.push(feedback);
104
+ spinner3.stop(`${advisor.icon} ${advisor.name} complete`);
105
+ console.log(chalk.dim(` Score: ${feedback.score}/10 - "${feedback.feedback.slice(0, 80)}..."
106
+ `));
107
+ }
108
+ const spinner2 = p.spinner();
109
+ spinner2.start("Generating comprehensive report...");
110
+ const report = await generateReport(anthropic, brief, advisorFeedback);
111
+ spinner2.stop("Report generated");
112
+ displayReportSummary(report);
113
+ const savePath = await saveReport(report, brief.name);
114
+ p.outro(chalk.green(`
115
+ \u2713 Dream Team consultation complete!
116
+
117
+ \u{1F4C4} Full report saved to: ${savePath}
118
+
119
+ ${chalk.bold("Next steps:")}
120
+ ${chalk.cyan(`codebakers prd ${savePath.replace(".pdf", ".md")}`)} - Build from this plan
121
+ ${chalk.cyan("codebakers init")} - Start with standard setup
122
+ `));
123
+ }
124
+ async function conductInterview() {
125
+ p.intro(chalk.bgMagenta.white(" Project Interview "));
126
+ console.log(chalk.dim("\nLet's learn about your project. Answer as thoroughly as you can.\n"));
127
+ const name = await p.text({
128
+ message: "\u{1F469}\u200D\u{1F4BC} Sarah: What's your project called?",
129
+ placeholder: "My App Name",
130
+ validate: (v) => !v ? "Project name is required" : void 0
131
+ });
132
+ if (p.isCancel(name)) return null;
133
+ const idea = await p.text({
134
+ message: "\u{1F469}\u200D\u{1F4BC} Sarah: Describe your idea in 2-3 sentences. What does it do?",
135
+ placeholder: "A platform that helps...",
136
+ validate: (v) => !v ? "Please describe your idea" : void 0
137
+ });
138
+ if (p.isCancel(idea)) return null;
139
+ const problem = await p.text({
140
+ message: "\u{1F4CB} Aisha: What problem are you solving? Why does this need to exist?",
141
+ placeholder: "Currently, people struggle with...",
142
+ validate: (v) => !v ? "Understanding the problem is crucial" : void 0
143
+ });
144
+ if (p.isCancel(problem)) return null;
145
+ const targetAudience = await p.text({
146
+ message: "\u{1F4E3} David: Who is this for? Describe your ideal user.",
147
+ placeholder: "Small business owners who...",
148
+ validate: (v) => !v ? "We need to know your target audience" : void 0
149
+ });
150
+ if (p.isCancel(targetAudience)) return null;
151
+ const solution = await p.text({
152
+ message: "\u{1F469}\u200D\u{1F3A8} Elena: How does your product solve the problem? What's the core experience?",
153
+ placeholder: "Users can easily...",
154
+ validate: (v) => !v ? "Please describe your solution" : void 0
155
+ });
156
+ if (p.isCancel(solution)) return null;
157
+ const competitors = await p.text({
158
+ message: "\u{1F469}\u200D\u{1F4BC} Sarah: Who are your competitors? How are you different?",
159
+ placeholder: "Competitor X does Y, but we..."
160
+ });
161
+ if (p.isCancel(competitors)) return null;
162
+ const monetization = await p.select({
163
+ message: "\u{1F469}\u200D\u{1F4BC} Sarah: How will you make money?",
164
+ options: [
165
+ { value: "subscription", label: "Subscription (monthly/yearly)" },
166
+ { value: "freemium", label: "Freemium (free tier + paid)" },
167
+ { value: "one-time", label: "One-time purchase" },
168
+ { value: "marketplace", label: "Marketplace (take a cut)" },
169
+ { value: "ads", label: "Advertising" },
170
+ { value: "enterprise", label: "Enterprise sales" },
171
+ { value: "unsure", label: "Not sure yet" }
172
+ ]
173
+ });
174
+ if (p.isCancel(monetization)) return null;
175
+ const timeline = await p.select({
176
+ message: "\u{1F468}\u200D\u{1F4BB} Marcus: What's your timeline for launching?",
177
+ options: [
178
+ { value: "2-weeks", label: "2 weeks (MVP)" },
179
+ { value: "1-month", label: "1 month" },
180
+ { value: "3-months", label: "3 months" },
181
+ { value: "6-months", label: "6 months" },
182
+ { value: "flexible", label: "Flexible / No rush" }
183
+ ]
184
+ });
185
+ if (p.isCancel(timeline)) return null;
186
+ const budget = await p.select({
187
+ message: "\u{1F469}\u200D\u{1F4BC} Sarah: What's your budget for this project?",
188
+ options: [
189
+ { value: "bootstrap", label: "Bootstrap ($0 - using free tiers)" },
190
+ { value: "small", label: "Small ($100-500/month)" },
191
+ { value: "medium", label: "Medium ($500-2000/month)" },
192
+ { value: "funded", label: "Funded ($2000+/month)" }
193
+ ]
194
+ });
195
+ if (p.isCancel(budget)) return null;
196
+ const techPreferences = await p.text({
197
+ message: '\u{1F468}\u200D\u{1F4BB} Marcus: Any tech preferences or requirements? (or "none")',
198
+ placeholder: "Must use React, need mobile app, etc.",
199
+ initialValue: "none"
200
+ });
201
+ if (p.isCancel(techPreferences)) return null;
202
+ const additional = await p.text({
203
+ message: "\u{1F4CB} Aisha: Anything else we should know?",
204
+ placeholder: "Optional: special requirements, existing users, etc."
205
+ });
206
+ if (p.isCancel(additional)) return null;
207
+ return {
208
+ name,
209
+ idea,
210
+ targetAudience,
211
+ problem,
212
+ solution,
213
+ competitors: competitors || "Not specified",
214
+ monetization,
215
+ timeline,
216
+ budget,
217
+ techPreferences: techPreferences || "none"
218
+ };
219
+ }
220
+ async function getAdvisorFeedback(anthropic, advisor, brief) {
221
+ const response = await anthropic.messages.create({
222
+ model: "claude-sonnet-4-20250514",
223
+ max_tokens: 2048,
224
+ messages: [{
225
+ role: "user",
226
+ content: `You are ${advisor.name}, ${advisor.role} on a startup advisory board.
227
+
228
+ Your expertise: ${advisor.expertise}
229
+ Your personality: ${advisor.personality}
230
+
231
+ Review this project brief and provide your expert feedback:
232
+
233
+ Project: ${brief.name}
234
+ Idea: ${brief.idea}
235
+ Problem: ${brief.problem}
236
+ Target Audience: ${brief.targetAudience}
237
+ Solution: ${brief.solution}
238
+ Competitors: ${brief.competitors}
239
+ Monetization: ${brief.monetization}
240
+ Timeline: ${brief.timeline}
241
+ Budget: ${brief.budget}
242
+ Tech Preferences: ${brief.techPreferences}
243
+
244
+ Respond with JSON only:
245
+ {
246
+ "feedback": "2-3 sentence overall assessment in your voice/personality",
247
+ "recommendations": ["specific recommendation 1", "recommendation 2", "recommendation 3"],
248
+ "questions": ["question you'd want answered", "another question"],
249
+ "risks": ["risk 1", "risk 2"],
250
+ "score": 7
251
+ }
252
+
253
+ Score 1-10 based on your area of expertise. Be honest but constructive.`
254
+ }]
255
+ });
256
+ const text2 = response.content[0].type === "text" ? response.content[0].text : "";
257
+ const jsonMatch = text2.match(/\{[\s\S]*\}/);
258
+ if (!jsonMatch) {
259
+ return {
260
+ advisor: advisor.name,
261
+ role: advisor.role,
262
+ icon: advisor.icon,
263
+ feedback: "Unable to generate feedback",
264
+ recommendations: [],
265
+ questions: [],
266
+ risks: [],
267
+ score: 5
268
+ };
269
+ }
270
+ const parsed = JSON.parse(jsonMatch[0]);
271
+ return {
272
+ advisor: advisor.name,
273
+ role: advisor.role,
274
+ icon: advisor.icon,
275
+ ...parsed
276
+ };
277
+ }
278
+ async function generateReport(anthropic, brief, advisorFeedback) {
279
+ const avgScore = advisorFeedback.reduce((sum, f) => sum + f.score, 0) / advisorFeedback.length;
280
+ const response = await anthropic.messages.create({
281
+ model: "claude-sonnet-4-20250514",
282
+ max_tokens: 8192,
283
+ messages: [{
284
+ role: "user",
285
+ content: `Generate a comprehensive startup plan based on this project brief and advisor feedback.
286
+
287
+ PROJECT BRIEF:
288
+ ${JSON.stringify(brief, null, 2)}
289
+
290
+ ADVISOR FEEDBACK:
291
+ ${JSON.stringify(advisorFeedback, null, 2)}
292
+
293
+ Generate a complete JSON report:
294
+ {
295
+ "executiveSummary": "3-4 paragraph executive summary",
296
+ "goNoGo": "GO" or "CAUTION" or "PIVOT",
297
+ "marketingPlan": {
298
+ "positioning": "positioning statement",
299
+ "targetSegments": ["segment 1", "segment 2"],
300
+ "channels": ["channel 1", "channel 2"],
301
+ "launchStrategy": "detailed launch strategy",
302
+ "contentPlan": ["content idea 1", "content idea 2"],
303
+ "socialMediaPlan": {
304
+ "platforms": ["platform 1", "platform 2"],
305
+ "postFrequency": "frequency",
306
+ "contentTypes": ["type 1", "type 2"]
307
+ },
308
+ "budget": "recommended budget breakdown"
309
+ },
310
+ "technicalPlan": {
311
+ "architecture": "high-level architecture description",
312
+ "stack": ["Next.js", "Supabase", "etc"],
313
+ "phases": [
314
+ {"name": "Phase 1: MVP", "duration": "2 weeks", "deliverables": ["feature 1", "feature 2"]}
315
+ ],
316
+ "mvpFeatures": ["feature 1", "feature 2"],
317
+ "futureFeatures": ["feature 1", "feature 2"]
318
+ },
319
+ "uxPlan": {
320
+ "userPersonas": [{"name": "Persona Name", "description": "desc", "goals": ["goal 1"]}],
321
+ "userJourneys": ["journey 1", "journey 2"],
322
+ "keyScreens": ["screen 1", "screen 2"],
323
+ "designPrinciples": ["principle 1", "principle 2"]
324
+ },
325
+ "businessPlan": {
326
+ "revenueModel": "detailed revenue model",
327
+ "pricing": "pricing strategy",
328
+ "projections": [{"month": 3, "users": 100, "revenue": 500}],
329
+ "kpis": ["kpi 1", "kpi 2"],
330
+ "risks": [{"risk": "risk description", "mitigation": "how to mitigate"}]
331
+ },
332
+ "actionItems": [
333
+ {"priority": "HIGH", "task": "task description", "owner": "CEO/Engineer/etc"}
334
+ ]
335
+ }
336
+
337
+ Be specific, actionable, and realistic based on the timeline and budget.`
338
+ }]
339
+ });
340
+ const text2 = response.content[0].type === "text" ? response.content[0].text : "";
341
+ const jsonMatch = text2.match(/\{[\s\S]*\}/);
342
+ const parsed = jsonMatch ? JSON.parse(jsonMatch[0]) : {};
343
+ return {
344
+ projectName: brief.name,
345
+ brief,
346
+ advisorFeedback,
347
+ overallScore: Math.round(avgScore * 10) / 10,
348
+ goNoGo: parsed.goNoGo || (avgScore >= 7 ? "GO" : avgScore >= 5 ? "CAUTION" : "PIVOT"),
349
+ executiveSummary: parsed.executiveSummary || "",
350
+ marketingPlan: parsed.marketingPlan || {},
351
+ technicalPlan: parsed.technicalPlan || {},
352
+ uxPlan: parsed.uxPlan || {},
353
+ businessPlan: parsed.businessPlan || {},
354
+ actionItems: parsed.actionItems || []
355
+ };
356
+ }
357
+ function displayReportSummary(report) {
358
+ const goNoGoColor = {
359
+ "GO": chalk.green,
360
+ "CAUTION": chalk.yellow,
361
+ "PIVOT": chalk.red
362
+ }[report.goNoGo];
363
+ console.log(chalk.bold(`
364
+ ${"\u2550".repeat(60)}`));
365
+ console.log(chalk.bold.cyan(`
366
+ \u{1F4CA} DREAM TEAM REPORT: ${report.projectName.toUpperCase()}
367
+ `));
368
+ console.log(chalk.bold(`${"\u2550".repeat(60)}
369
+ `));
370
+ console.log(chalk.bold("Overall Assessment:"));
371
+ console.log(` Score: ${chalk.bold(report.overallScore.toString())}/10`);
372
+ console.log(` Verdict: ${goNoGoColor(report.goNoGo)}
373
+ `);
374
+ console.log(chalk.bold("Advisor Scores:"));
375
+ for (const feedback of report.advisorFeedback) {
376
+ const bar = "\u2588".repeat(feedback.score) + "\u2591".repeat(10 - feedback.score);
377
+ console.log(` ${feedback.icon} ${feedback.advisor.padEnd(18)} ${bar} ${feedback.score}/10`);
378
+ }
379
+ console.log("");
380
+ console.log(chalk.bold("Executive Summary:"));
381
+ console.log(chalk.dim(` ${report.executiveSummary.slice(0, 300)}...`));
382
+ console.log("");
383
+ console.log(chalk.bold("Top Action Items:"));
384
+ const highPriority = report.actionItems.filter((a) => a.priority === "HIGH").slice(0, 5);
385
+ highPriority.forEach((item, i) => {
386
+ console.log(` ${chalk.red("!")} ${item.task}`);
387
+ });
388
+ console.log("");
389
+ if (report.technicalPlan.stack?.length > 0) {
390
+ console.log(chalk.bold("Recommended Stack:"));
391
+ console.log(` ${report.technicalPlan.stack.join(" \u2022 ")}`);
392
+ console.log("");
393
+ }
394
+ console.log(chalk.dim("Full report saved to PDF with complete marketing, technical, and business plans.\n"));
395
+ }
396
+ async function saveReport(report, projectName) {
397
+ const sanitizedName = projectName.toLowerCase().replace(/[^a-z0-9]/g, "-");
398
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
399
+ const filename = `${sanitizedName}-dream-team-report-${timestamp}`;
400
+ const mdPath = path.join(process.cwd(), `${filename}.md`);
401
+ const mdContent = generateMarkdownReport(report);
402
+ await fs.writeFile(mdPath, mdContent);
403
+ const jsonPath = path.join(process.cwd(), `${filename}.json`);
404
+ await fs.writeJson(jsonPath, report, { spaces: 2 });
405
+ return mdPath;
406
+ }
407
+ function generateMarkdownReport(report) {
408
+ const goNoGoEmoji = { "GO": "\u{1F7E2}", "CAUTION": "\u{1F7E1}", "PIVOT": "\u{1F534}" }[report.goNoGo];
409
+ return `# ${report.projectName} - Dream Team Report
410
+
411
+ **Generated:** ${(/* @__PURE__ */ new Date()).toLocaleDateString()}
412
+ **Overall Score:** ${report.overallScore}/10
413
+ **Verdict:** ${goNoGoEmoji} ${report.goNoGo}
414
+
415
+ ---
416
+
417
+ ## Executive Summary
418
+
419
+ ${report.executiveSummary}
420
+
421
+ ---
422
+
423
+ ## Advisor Feedback
424
+
425
+ ${report.advisorFeedback.map((f) => `
426
+ ### ${f.icon} ${f.advisor} - ${f.role}
427
+
428
+ **Score:** ${f.score}/10
429
+
430
+ ${f.feedback}
431
+
432
+ **Recommendations:**
433
+ ${f.recommendations.map((r) => `- ${r}`).join("\n")}
434
+
435
+ **Questions to Consider:**
436
+ ${f.questions.map((q) => `- ${q}`).join("\n")}
437
+
438
+ **Risks Identified:**
439
+ ${f.risks.map((r) => `- ${r}`).join("\n")}
440
+ `).join("\n")}
441
+
442
+ ---
443
+
444
+ ## Marketing Plan
445
+
446
+ ### Positioning
447
+ ${report.marketingPlan.positioning}
448
+
449
+ ### Target Segments
450
+ ${report.marketingPlan.targetSegments?.map((s) => `- ${s}`).join("\n") || "TBD"}
451
+
452
+ ### Marketing Channels
453
+ ${report.marketingPlan.channels?.map((c) => `- ${c}`).join("\n") || "TBD"}
454
+
455
+ ### Launch Strategy
456
+ ${report.marketingPlan.launchStrategy}
457
+
458
+ ### Content Plan
459
+ ${report.marketingPlan.contentPlan?.map((c) => `- ${c}`).join("\n") || "TBD"}
460
+
461
+ ### Social Media Plan
462
+ - **Platforms:** ${report.marketingPlan.socialMediaPlan?.platforms?.join(", ") || "TBD"}
463
+ - **Post Frequency:** ${report.marketingPlan.socialMediaPlan?.postFrequency || "TBD"}
464
+ - **Content Types:** ${report.marketingPlan.socialMediaPlan?.contentTypes?.join(", ") || "TBD"}
465
+
466
+ ### Budget
467
+ ${report.marketingPlan.budget}
468
+
469
+ ---
470
+
471
+ ## Technical Plan
472
+
473
+ ### Architecture
474
+ ${report.technicalPlan.architecture}
475
+
476
+ ### Tech Stack
477
+ ${report.technicalPlan.stack?.map((s) => `- ${s}`).join("\n") || "TBD"}
478
+
479
+ ### Development Phases
480
+ ${report.technicalPlan.phases?.map((p2) => `
481
+ #### ${p2.name} (${p2.duration})
482
+ ${p2.deliverables.map((d) => `- ${d}`).join("\n")}
483
+ `).join("\n") || "TBD"}
484
+
485
+ ### MVP Features
486
+ ${report.technicalPlan.mvpFeatures?.map((f) => `- ${f}`).join("\n") || "TBD"}
487
+
488
+ ### Future Features
489
+ ${report.technicalPlan.futureFeatures?.map((f) => `- ${f}`).join("\n") || "TBD"}
490
+
491
+ ---
492
+
493
+ ## UX Plan
494
+
495
+ ### User Personas
496
+ ${report.uxPlan.userPersonas?.map((p2) => `
497
+ #### ${p2.name}
498
+ ${p2.description}
499
+
500
+ **Goals:**
501
+ ${p2.goals.map((g) => `- ${g}`).join("\n")}
502
+ `).join("\n") || "TBD"}
503
+
504
+ ### User Journeys
505
+ ${report.uxPlan.userJourneys?.map((j) => `- ${j}`).join("\n") || "TBD"}
506
+
507
+ ### Key Screens
508
+ ${report.uxPlan.keyScreens?.map((s) => `- ${s}`).join("\n") || "TBD"}
509
+
510
+ ### Design Principles
511
+ ${report.uxPlan.designPrinciples?.map((p2) => `- ${p2}`).join("\n") || "TBD"}
512
+
513
+ ---
514
+
515
+ ## Business Plan
516
+
517
+ ### Revenue Model
518
+ ${report.businessPlan.revenueModel}
519
+
520
+ ### Pricing Strategy
521
+ ${report.businessPlan.pricing}
522
+
523
+ ### Projections
524
+ | Month | Users | Revenue |
525
+ |-------|-------|---------|
526
+ ${report.businessPlan.projections?.map((p2) => `| ${p2.month} | ${p2.users} | $${p2.revenue} |`).join("\n") || "| TBD | TBD | TBD |"}
527
+
528
+ ### KPIs
529
+ ${report.businessPlan.kpis?.map((k) => `- ${k}`).join("\n") || "TBD"}
530
+
531
+ ### Risks & Mitigation
532
+ | Risk | Mitigation |
533
+ |------|------------|
534
+ ${report.businessPlan.risks?.map((r) => `| ${r.risk} | ${r.mitigation} |`).join("\n") || "| TBD | TBD |"}
535
+
536
+ ---
537
+
538
+ ## Action Items
539
+
540
+ ### High Priority
541
+ ${report.actionItems.filter((a) => a.priority === "HIGH").map((a) => `- [ ] **${a.task}** (Owner: ${a.owner})`).join("\n") || "None"}
542
+
543
+ ### Medium Priority
544
+ ${report.actionItems.filter((a) => a.priority === "MEDIUM").map((a) => `- [ ] ${a.task} (Owner: ${a.owner})`).join("\n") || "None"}
545
+
546
+ ### Low Priority
547
+ ${report.actionItems.filter((a) => a.priority === "LOW").map((a) => `- [ ] ${a.task} (Owner: ${a.owner})`).join("\n") || "None"}
548
+
549
+ ---
550
+
551
+ ## Next Steps
552
+
553
+ 1. Review this report with your team
554
+ 2. Run \`codebakers prd ${report.projectName.toLowerCase().replace(/[^a-z0-9]/g, "-")}-dream-team-report.md\` to start building
555
+ 3. Or run \`codebakers init\` for standard project setup
556
+
557
+ ---
558
+
559
+ *Generated by CodeBakers Dream Team Advisors*
560
+ `;
561
+ }
562
+
563
+ export {
564
+ advisorsCommand
565
+ };