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.
- package/dist/advisors-J3S64IZK.js +7 -0
- package/dist/chunk-FWQNLNTI.js +565 -0
- package/dist/chunk-RCC7FYEU.js +319 -0
- package/dist/chunk-YGVDLNXY.js +326 -0
- package/dist/index.js +3704 -1907
- package/dist/prd-HBUCYLVG.js +7 -0
- package/package.json +1 -1
- package/src/commands/build.ts +989 -0
- package/src/commands/code.ts +102 -5
- package/src/commands/integrate.ts +985 -0
- package/src/commands/prd-maker.ts +587 -0
- package/src/index.ts +134 -4
- package/src/utils/files.ts +418 -0
- package/src/utils/nlp.ts +312 -0
- package/src/utils/voice.ts +323 -0
|
@@ -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
|
+
};
|