brains-cli 0.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/.claude/skills/founder/SKILL.md +316 -0
- package/README.md +190 -0
- package/bin/brains.js +74 -0
- package/package.json +43 -0
- package/src/commands/create.js +171 -0
- package/src/commands/explore.js +137 -0
- package/src/commands/install.js +139 -0
- package/src/commands/list.js +71 -0
- package/src/commands/publish.js +65 -0
- package/src/commands/run.js +487 -0
- package/src/registry.js +659 -0
- package/src/utils/ui.js +144 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const inquirer = require('inquirer');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const ora = require('ora');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const { getBrainById } = require('../registry');
|
|
9
|
+
const { showSuccess, showError, showInfo, showBox, ACCENT, DIM, SUCCESS, WARN } = require('../utils/ui');
|
|
10
|
+
|
|
11
|
+
const BRAINS_DIR = path.join(require('os').homedir(), '.brains');
|
|
12
|
+
const INSTALLED_FILE = path.join(BRAINS_DIR, 'installed.json');
|
|
13
|
+
|
|
14
|
+
function isInstalled(brainId) {
|
|
15
|
+
try {
|
|
16
|
+
const installed = JSON.parse(fs.readFileSync(INSTALLED_FILE, 'utf-8'));
|
|
17
|
+
return !!installed[brainId];
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function loadBrainConfig(brainId) {
|
|
24
|
+
const configPath = path.join(BRAINS_DIR, brainId, 'brain.json');
|
|
25
|
+
if (fs.existsSync(configPath)) {
|
|
26
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function run(brainName, options) {
|
|
32
|
+
const brain = getBrainById(brainName);
|
|
33
|
+
|
|
34
|
+
if (!brain) {
|
|
35
|
+
showError(`Brain "${brainName}" not found.`);
|
|
36
|
+
showInfo(`Run ${ACCENT('brains explore')} to see available brains.`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check if installed
|
|
41
|
+
if (!isInstalled(brainName)) {
|
|
42
|
+
showInfo(`${brain.name} is not installed yet.`);
|
|
43
|
+
const { doInstall } = await inquirer.prompt([
|
|
44
|
+
{
|
|
45
|
+
type: 'confirm',
|
|
46
|
+
name: 'doInstall',
|
|
47
|
+
message: `Install ${brain.name} now?`,
|
|
48
|
+
default: true,
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
if (doInstall) {
|
|
53
|
+
const { install } = require('./install');
|
|
54
|
+
await install(brainName, {});
|
|
55
|
+
} else {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const config = loadBrainConfig(brainName) || brain;
|
|
61
|
+
|
|
62
|
+
// Handle brain stacking
|
|
63
|
+
let stackedBrains = [];
|
|
64
|
+
if (options.with && options.with.length > 0) {
|
|
65
|
+
console.log('');
|
|
66
|
+
showInfo(`Stacking brains: ${chalk.bold(brainName)} + ${options.with.join(' + ')}`);
|
|
67
|
+
|
|
68
|
+
for (const extraBrain of options.with) {
|
|
69
|
+
const extra = getBrainById(extraBrain);
|
|
70
|
+
if (extra) {
|
|
71
|
+
stackedBrains.push(extra);
|
|
72
|
+
showInfo(` ${SUCCESS('+')} ${extra.name} loaded`);
|
|
73
|
+
} else {
|
|
74
|
+
showInfo(` ${WARN('⚠')} ${extraBrain} not found, skipping`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Show brain activation
|
|
80
|
+
console.log('');
|
|
81
|
+
const spinner = ora({
|
|
82
|
+
text: `Activating ${chalk.bold(brain.name)}...`,
|
|
83
|
+
color: 'magenta',
|
|
84
|
+
spinner: 'dots12',
|
|
85
|
+
}).start();
|
|
86
|
+
await new Promise((r) => setTimeout(r, 1200));
|
|
87
|
+
spinner.succeed(`${chalk.bold(brain.name)} is active`);
|
|
88
|
+
|
|
89
|
+
if (stackedBrains.length > 0) {
|
|
90
|
+
const stackSpinner = ora({
|
|
91
|
+
text: 'Merging stacked brain contexts...',
|
|
92
|
+
color: 'cyan',
|
|
93
|
+
spinner: 'dots12',
|
|
94
|
+
}).start();
|
|
95
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
96
|
+
stackSpinner.succeed('Brain stack ready');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Show session header
|
|
100
|
+
const categoryColors = {
|
|
101
|
+
builder: '#FF3366',
|
|
102
|
+
role: '#7B2FFF',
|
|
103
|
+
reviewer: '#00AAFF',
|
|
104
|
+
domain: '#00CC88',
|
|
105
|
+
};
|
|
106
|
+
const color = categoryColors[brain.category] || '#ffffff';
|
|
107
|
+
|
|
108
|
+
console.log('');
|
|
109
|
+
console.log(
|
|
110
|
+
chalk.hex(color).bold(' ┌─────────────────────────────────────────────────────')
|
|
111
|
+
);
|
|
112
|
+
console.log(
|
|
113
|
+
chalk.hex(color).bold(` │ 🧠 ${brain.name}`) +
|
|
114
|
+
DIM(` — ${brain.category}`)
|
|
115
|
+
);
|
|
116
|
+
if (stackedBrains.length > 0) {
|
|
117
|
+
console.log(
|
|
118
|
+
chalk.hex(color).bold(' │ ') +
|
|
119
|
+
DIM(`+ ${stackedBrains.map((b) => b.name).join(', ')}`)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
console.log(
|
|
123
|
+
chalk.hex(color).bold(' │ ') + DIM(`Stack: ${brain.stack.join(', ')}`)
|
|
124
|
+
);
|
|
125
|
+
console.log(
|
|
126
|
+
chalk.hex(color).bold(' └─────────────────────────────────────────────────────')
|
|
127
|
+
);
|
|
128
|
+
console.log('');
|
|
129
|
+
|
|
130
|
+
// ─── Brain-specific workflows ───
|
|
131
|
+
|
|
132
|
+
if (brain.category === 'builder') {
|
|
133
|
+
await runBuilderBrain(brain, config, options);
|
|
134
|
+
} else if (brain.category === 'reviewer') {
|
|
135
|
+
await runReviewerBrain(brain, config, options);
|
|
136
|
+
} else if (brain.category === 'role') {
|
|
137
|
+
await runRoleBrain(brain, config, options);
|
|
138
|
+
} else if (brain.category === 'domain') {
|
|
139
|
+
await runDomainBrain(brain, config, options);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ─── Builder Brain Runner ───
|
|
144
|
+
async function runBuilderBrain(brain, config, options) {
|
|
145
|
+
showInfo(`${brain.name} will ask you a few questions, then generate your project.\n`);
|
|
146
|
+
|
|
147
|
+
const answers = {};
|
|
148
|
+
|
|
149
|
+
// Run through the brain's interview questions
|
|
150
|
+
for (const q of config.questions || brain.questions) {
|
|
151
|
+
const { answer } = await inquirer.prompt([
|
|
152
|
+
{
|
|
153
|
+
type: 'input',
|
|
154
|
+
name: 'answer',
|
|
155
|
+
message: chalk.hex('#FF3366')(q.question),
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
answers[q.key] = answer;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log('');
|
|
162
|
+
showInfo('Got it! Generating your project...\n');
|
|
163
|
+
|
|
164
|
+
// Simulate generation steps based on brain type
|
|
165
|
+
const genSteps = getBuilderSteps(brain.id);
|
|
166
|
+
for (const step of genSteps) {
|
|
167
|
+
const spinner = ora({
|
|
168
|
+
text: step.text,
|
|
169
|
+
color: 'magenta',
|
|
170
|
+
spinner: 'dots12',
|
|
171
|
+
}).start();
|
|
172
|
+
await new Promise((r) => setTimeout(r, step.time));
|
|
173
|
+
spinner.succeed(chalk.dim(step.text));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Show output
|
|
177
|
+
const dir = options.dir || `./${answers.product || answers.name || brain.id}-project`;
|
|
178
|
+
|
|
179
|
+
console.log('');
|
|
180
|
+
showSuccess('Project generated successfully!\n');
|
|
181
|
+
|
|
182
|
+
const tree = getProjectTree(brain.id, answers);
|
|
183
|
+
console.log(chalk.dim(tree));
|
|
184
|
+
|
|
185
|
+
console.log('');
|
|
186
|
+
showInfo(`Project created at: ${ACCENT(dir)}`);
|
|
187
|
+
showInfo(`Next steps:`);
|
|
188
|
+
console.log(` ${DIM('$')} ${ACCENT(`cd ${dir}`)}`);
|
|
189
|
+
console.log(` ${DIM('$')} ${ACCENT('npm install')}`);
|
|
190
|
+
console.log(` ${DIM('$')} ${ACCENT('npm run dev')}`);
|
|
191
|
+
console.log('');
|
|
192
|
+
|
|
193
|
+
// Show what the brain generated
|
|
194
|
+
const systemPromptInfo = `
|
|
195
|
+
${chalk.bold('What was generated:')}
|
|
196
|
+
|
|
197
|
+
This project was scaffolded by the ${chalk.hex('#FF3366').bold(brain.name)} Brain.
|
|
198
|
+
The brain used the following context to customize your project:
|
|
199
|
+
${Object.entries(answers)
|
|
200
|
+
.map(([k, v]) => ` ${chalk.hex('#FF3366')('▸')} ${k}: ${DIM(v)}`)
|
|
201
|
+
.join('\n')}
|
|
202
|
+
|
|
203
|
+
${chalk.bold('Brain System Prompt:')}
|
|
204
|
+
${DIM('The brain operated with a specialized system prompt that ensures')}
|
|
205
|
+
${DIM('best practices, modern patterns, and production-grade output.')}
|
|
206
|
+
${DIM(`View it at: ~/.brains/${brain.id}/BRAIN.md`)}
|
|
207
|
+
`;
|
|
208
|
+
console.log(systemPromptInfo);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ─── Reviewer Brain Runner ───
|
|
212
|
+
async function runReviewerBrain(brain, config, options) {
|
|
213
|
+
const targetDir = options.dir || process.cwd();
|
|
214
|
+
|
|
215
|
+
showInfo(`${brain.name} will analyze your codebase.\n`);
|
|
216
|
+
|
|
217
|
+
// Ask focus questions
|
|
218
|
+
const answers = {};
|
|
219
|
+
for (const q of config.questions || brain.questions) {
|
|
220
|
+
const { answer } = await inquirer.prompt([
|
|
221
|
+
{
|
|
222
|
+
type: 'input',
|
|
223
|
+
name: 'answer',
|
|
224
|
+
message: chalk.hex('#00AAFF')(q.question),
|
|
225
|
+
},
|
|
226
|
+
]);
|
|
227
|
+
answers[q.key] = answer;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
console.log('');
|
|
231
|
+
|
|
232
|
+
const scanSteps = [
|
|
233
|
+
{ text: 'Scanning project structure', time: 600 },
|
|
234
|
+
{ text: 'Analyzing source files', time: 1000 },
|
|
235
|
+
{ text: 'Checking dependencies', time: 500 },
|
|
236
|
+
{ text: 'Running pattern analysis', time: 800 },
|
|
237
|
+
{ text: 'Evaluating security posture', time: 700 },
|
|
238
|
+
{ text: 'Generating review report', time: 600 },
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
for (const step of scanSteps) {
|
|
242
|
+
const spinner = ora({
|
|
243
|
+
text: step.text,
|
|
244
|
+
color: 'cyan',
|
|
245
|
+
spinner: 'dots12',
|
|
246
|
+
}).start();
|
|
247
|
+
await new Promise((r) => setTimeout(r, step.time));
|
|
248
|
+
spinner.succeed(chalk.dim(step.text));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
console.log('');
|
|
252
|
+
showSuccess('Review complete!\n');
|
|
253
|
+
|
|
254
|
+
// Show sample review output
|
|
255
|
+
console.log(chalk.bold(' Review Summary\n'));
|
|
256
|
+
console.log(` ${chalk.red('🔴 CRITICAL')} ${chalk.dim('0 issues')}`);
|
|
257
|
+
console.log(` ${chalk.hex('#FF8800')('🟡 WARNING')} ${chalk.dim('3 issues')}`);
|
|
258
|
+
console.log(` ${chalk.hex('#00CC88')('🟢 SUGGESTION')} ${chalk.dim('7 suggestions')}`);
|
|
259
|
+
console.log(` ${chalk.blue('📝 NOTE')} ${chalk.dim('2 notes')}`);
|
|
260
|
+
|
|
261
|
+
console.log(`\n${chalk.dim('─'.repeat(56))}\n`);
|
|
262
|
+
|
|
263
|
+
console.log(
|
|
264
|
+
` ${chalk.bold('In production, this brain would:')}\n` +
|
|
265
|
+
` ${chalk.hex('#00AAFF')('▸')} Read every file in your project\n` +
|
|
266
|
+
` ${chalk.hex('#00AAFF')('▸')} Apply the review methodology from its system prompt\n` +
|
|
267
|
+
` ${chalk.hex('#00AAFF')('▸')} Use Claude to analyze patterns, bugs, and security\n` +
|
|
268
|
+
` ${chalk.hex('#00AAFF')('▸')} Output a detailed, prioritized review report\n` +
|
|
269
|
+
` ${chalk.hex('#00AAFF')('▸')} Optionally auto-fix issues with --fix flag\n`
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
showInfo(`Brain config: ${DIM(`~/.brains/${brain.id}/BRAIN.md`)}`);
|
|
273
|
+
console.log('');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ─── Role Brain Runner ───
|
|
277
|
+
async function runRoleBrain(brain, config, options) {
|
|
278
|
+
showInfo(`${brain.name} is ready. Starting conversational session.\n`);
|
|
279
|
+
|
|
280
|
+
// Ask initial context questions
|
|
281
|
+
const answers = {};
|
|
282
|
+
for (const q of config.questions || brain.questions) {
|
|
283
|
+
const { answer } = await inquirer.prompt([
|
|
284
|
+
{
|
|
285
|
+
type: 'input',
|
|
286
|
+
name: 'answer',
|
|
287
|
+
message: chalk.hex('#7B2FFF')(q.question),
|
|
288
|
+
},
|
|
289
|
+
]);
|
|
290
|
+
answers[q.key] = answer;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log('');
|
|
294
|
+
|
|
295
|
+
const spinner = ora({
|
|
296
|
+
text: 'Loading context and preparing response...',
|
|
297
|
+
color: 'magenta',
|
|
298
|
+
spinner: 'dots12',
|
|
299
|
+
}).start();
|
|
300
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
301
|
+
spinner.succeed(chalk.dim('Context loaded'));
|
|
302
|
+
|
|
303
|
+
console.log(`\n${chalk.dim('─'.repeat(56))}\n`);
|
|
304
|
+
|
|
305
|
+
console.log(
|
|
306
|
+
` ${chalk.bold('In production, this brain would now:')}\n` +
|
|
307
|
+
` ${chalk.hex('#7B2FFF')('▸')} Enter a REPL-style conversational loop\n` +
|
|
308
|
+
` ${chalk.hex('#7B2FFF')('▸')} Use the ${brain.name} system prompt to guide every response\n` +
|
|
309
|
+
` ${chalk.hex('#7B2FFF')('▸')} Generate code, review PRs, design systems interactively\n` +
|
|
310
|
+
` ${chalk.hex('#7B2FFF')('▸')} Maintain context across the conversation\n` +
|
|
311
|
+
` ${chalk.hex('#7B2FFF')('▸')} Write files directly to your project\n`
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
console.log(
|
|
315
|
+
` ${chalk.bold('The system prompt for this brain includes:')}\n` +
|
|
316
|
+
` ${DIM('Personality, methodology, tech preferences, and output format.')}\n` +
|
|
317
|
+
` ${DIM(`View it at: ~/.brains/${brain.id}/BRAIN.md`)}\n`
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
// Interactive loop demo
|
|
321
|
+
const { continueChat } = await inquirer.prompt([
|
|
322
|
+
{
|
|
323
|
+
type: 'confirm',
|
|
324
|
+
name: 'continueChat',
|
|
325
|
+
message: 'Want to see a sample interaction?',
|
|
326
|
+
default: true,
|
|
327
|
+
},
|
|
328
|
+
]);
|
|
329
|
+
|
|
330
|
+
if (continueChat) {
|
|
331
|
+
console.log(`\n ${chalk.hex('#7B2FFF').bold(`[${brain.name}]`)} ${chalk.white("I've reviewed your request. Here's my approach:")}\n`);
|
|
332
|
+
console.log(DIM(' (In production, Claude would respond here using the brain\'s system prompt'));
|
|
333
|
+
console.log(DIM(' as its personality and methodology, generating real code and advice.)\n'));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// ─── Domain Brain Runner ───
|
|
338
|
+
async function runDomainBrain(brain, config, options) {
|
|
339
|
+
showInfo(`${brain.name} expert session started.\n`);
|
|
340
|
+
|
|
341
|
+
// Ask what they need
|
|
342
|
+
for (const q of config.questions || brain.questions) {
|
|
343
|
+
const { answer } = await inquirer.prompt([
|
|
344
|
+
{
|
|
345
|
+
type: 'input',
|
|
346
|
+
name: 'answer',
|
|
347
|
+
message: chalk.hex('#00CC88')(q.question),
|
|
348
|
+
},
|
|
349
|
+
]);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
console.log('');
|
|
353
|
+
|
|
354
|
+
const spinner = ora({
|
|
355
|
+
text: `Consulting ${brain.name} knowledge base...`,
|
|
356
|
+
color: 'green',
|
|
357
|
+
spinner: 'dots12',
|
|
358
|
+
}).start();
|
|
359
|
+
await new Promise((r) => setTimeout(r, 1200));
|
|
360
|
+
spinner.succeed(chalk.dim('Ready'));
|
|
361
|
+
|
|
362
|
+
console.log(`\n${chalk.dim('─'.repeat(56))}\n`);
|
|
363
|
+
|
|
364
|
+
console.log(
|
|
365
|
+
` ${chalk.bold('In production, this brain would:')}\n` +
|
|
366
|
+
` ${chalk.hex('#00CC88')('▸')} Use deep ${brain.stack[0]} expertise from its system prompt\n` +
|
|
367
|
+
` ${chalk.hex('#00CC88')('▸')} Generate best-practice code specific to your question\n` +
|
|
368
|
+
` ${chalk.hex('#00CC88')('▸')} Include explanations, trade-offs, and gotchas\n` +
|
|
369
|
+
` ${chalk.hex('#00CC88')('▸')} Reference latest patterns and APIs\n` +
|
|
370
|
+
` ${chalk.hex('#00CC88')('▸')} Work interactively in a conversational loop\n`
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
showInfo(`Brain config: ${DIM(`~/.brains/${brain.id}/BRAIN.md`)}`);
|
|
374
|
+
console.log('');
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// ─── Helper: Builder generation steps ───
|
|
378
|
+
function getBuilderSteps(brainId) {
|
|
379
|
+
const common = [
|
|
380
|
+
{ text: 'Analyzing requirements', time: 500 },
|
|
381
|
+
{ text: 'Selecting architecture', time: 400 },
|
|
382
|
+
];
|
|
383
|
+
|
|
384
|
+
const specific = {
|
|
385
|
+
resume: [
|
|
386
|
+
{ text: 'Generating Next.js project', time: 700 },
|
|
387
|
+
{ text: 'Creating resume components', time: 600 },
|
|
388
|
+
{ text: 'Applying theme and typography', time: 500 },
|
|
389
|
+
{ text: 'Adding responsive styles', time: 400 },
|
|
390
|
+
{ text: 'Configuring SEO metadata', time: 300 },
|
|
391
|
+
{ text: 'Setting up Vercel deployment', time: 300 },
|
|
392
|
+
],
|
|
393
|
+
mvp: [
|
|
394
|
+
{ text: 'Generating Next.js + Prisma project', time: 800 },
|
|
395
|
+
{ text: 'Creating database schema', time: 600 },
|
|
396
|
+
{ text: 'Building API routes', time: 700 },
|
|
397
|
+
{ text: 'Setting up authentication', time: 500 },
|
|
398
|
+
{ text: 'Generating dashboard pages', time: 600 },
|
|
399
|
+
{ text: 'Creating landing page', time: 500 },
|
|
400
|
+
{ text: 'Configuring Docker', time: 400 },
|
|
401
|
+
],
|
|
402
|
+
landing: [
|
|
403
|
+
{ text: 'Generating page structure', time: 500 },
|
|
404
|
+
{ text: 'Writing conversion copy', time: 700 },
|
|
405
|
+
{ text: 'Building hero section', time: 500 },
|
|
406
|
+
{ text: 'Creating feature sections', time: 400 },
|
|
407
|
+
{ text: 'Adding social proof', time: 400 },
|
|
408
|
+
{ text: 'Setting up email capture', time: 300 },
|
|
409
|
+
{ text: 'Adding animations', time: 500 },
|
|
410
|
+
],
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
return [...common, ...(specific[brainId] || specific.mvp)];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ─── Helper: Project tree output ───
|
|
417
|
+
function getProjectTree(brainId, answers) {
|
|
418
|
+
const name = answers.product || answers.name || brainId;
|
|
419
|
+
const trees = {
|
|
420
|
+
resume: `
|
|
421
|
+
${chalk.bold(`${name}-project/`)}
|
|
422
|
+
├── app/
|
|
423
|
+
│ ├── layout.tsx
|
|
424
|
+
│ ├── page.tsx
|
|
425
|
+
│ └── globals.css
|
|
426
|
+
├── components/
|
|
427
|
+
│ ├── Hero.tsx
|
|
428
|
+
│ ├── Experience.tsx
|
|
429
|
+
│ ├── Skills.tsx
|
|
430
|
+
│ ├── Projects.tsx
|
|
431
|
+
│ └── Contact.tsx
|
|
432
|
+
├── lib/
|
|
433
|
+
│ └── data.ts
|
|
434
|
+
├── public/
|
|
435
|
+
│ └── resume.pdf
|
|
436
|
+
├── package.json
|
|
437
|
+
├── tailwind.config.ts
|
|
438
|
+
├── tsconfig.json
|
|
439
|
+
└── next.config.js`,
|
|
440
|
+
mvp: `
|
|
441
|
+
${chalk.bold(`${name}-project/`)}
|
|
442
|
+
├── app/
|
|
443
|
+
│ ├── layout.tsx
|
|
444
|
+
│ ├── page.tsx ${DIM('← Landing page')}
|
|
445
|
+
│ ├── (auth)/
|
|
446
|
+
│ │ ├── login/page.tsx
|
|
447
|
+
│ │ └── register/page.tsx
|
|
448
|
+
│ ├── dashboard/
|
|
449
|
+
│ │ ├── layout.tsx
|
|
450
|
+
│ │ └── page.tsx
|
|
451
|
+
│ └── api/
|
|
452
|
+
│ └── [...routes].ts
|
|
453
|
+
├── components/
|
|
454
|
+
│ ├── ui/
|
|
455
|
+
│ └── features/
|
|
456
|
+
├── lib/
|
|
457
|
+
│ ├── db.ts
|
|
458
|
+
│ └── auth.ts
|
|
459
|
+
├── prisma/
|
|
460
|
+
│ ├── schema.prisma
|
|
461
|
+
│ └── migrations/
|
|
462
|
+
├── package.json
|
|
463
|
+
├── docker-compose.yml
|
|
464
|
+
└── .env.example`,
|
|
465
|
+
landing: `
|
|
466
|
+
${chalk.bold(`${name}-project/`)}
|
|
467
|
+
├── app/
|
|
468
|
+
│ ├── layout.tsx
|
|
469
|
+
│ ├── page.tsx
|
|
470
|
+
│ └── globals.css
|
|
471
|
+
├── components/
|
|
472
|
+
│ ├── Hero.tsx
|
|
473
|
+
│ ├── Features.tsx
|
|
474
|
+
│ ├── HowItWorks.tsx
|
|
475
|
+
│ ├── Testimonials.tsx
|
|
476
|
+
│ ├── Pricing.tsx
|
|
477
|
+
│ ├── FAQ.tsx
|
|
478
|
+
│ └── CTA.tsx
|
|
479
|
+
├── package.json
|
|
480
|
+
├── tailwind.config.ts
|
|
481
|
+
└── next.config.js`,
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
return trees[brainId] || trees.mvp;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
module.exports = { run };
|