@nimbuslab/cli 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +176 -57
  2. package/dist/index.js +1388 -312
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -147,7 +147,7 @@ var require_src = __commonJS((exports, module) => {
147
147
  });
148
148
 
149
149
  // src/index.ts
150
- var import_picocolors8 = __toESM(require_picocolors(), 1);
150
+ var import_picocolors9 = __toESM(require_picocolors(), 1);
151
151
 
152
152
  // node_modules/@clack/core/dist/index.mjs
153
153
  var import_sisteransi = __toESM(require_src(), 1);
@@ -865,10 +865,1041 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
865
865
  };
866
866
 
867
867
  // src/commands/create.ts
868
- var import_picocolors3 = __toESM(require_picocolors(), 1);
868
+ var import_picocolors4 = __toESM(require_picocolors(), 1);
869
869
  var {$: $2 } = globalThis.Bun;
870
870
  import { rm, mkdir } from "fs/promises";
871
+ import { join as join2 } from "path";
872
+
873
+ // src/lib/generators/ai-docs.ts
871
874
  import { join } from "path";
875
+ async function generateAIFriendlyDocs(projectPath, config) {
876
+ await generateAgentsFile(projectPath, config);
877
+ await generateLLMsFile(projectPath, config);
878
+ await generateArchitectureDoc(projectPath, config);
879
+ await generateExamplesDoc(projectPath, config);
880
+ await generateModificationsDoc(projectPath, config);
881
+ await createCompatibilitySymlinks(projectPath);
882
+ }
883
+ async function generateAgentsFile(projectPath, config) {
884
+ const content = `# Project Context for AI Assistants
885
+
886
+ > This file is automatically loaded by Claude Code, Cursor, GitHub Copilot, and other AI coding assistants.
887
+
888
+ ## Project Overview
889
+
890
+ **Name:** ${config.name}
891
+ **Type:** ${config.type}
892
+ **Description:** ${config.description}
893
+
894
+ ## Quick Start
895
+
896
+ \`\`\`bash
897
+ bun install
898
+ bun dev # http://localhost:3000
899
+ bun build # Production build
900
+ bun lint # ESLint
901
+ bun typecheck # TypeScript check
902
+ \`\`\`
903
+
904
+ ## Tech Stack
905
+
906
+ | Category | Technology | Why? |
907
+ |----------|-----------|------|
908
+ | Framework | ${config.stack.framework} | App Router, Turbopack, best DX |
909
+ | Styling | ${config.stack.styling} | Fast, composable, CSS-first |
910
+ | Components | ${config.stack.components} | Copy-paste, zero lock-in |
911
+ ${config.stack.forms ? `| Forms | ${config.stack.forms} | Type-safe validation |
912
+ ` : ""}${config.stack.email ? `| Email | ${config.stack.email} | Transactional emails |
913
+ ` : ""}${config.stack.auth ? `| Auth | ${config.stack.auth} | Secure authentication |
914
+ ` : ""}
915
+ ## Architecture Decisions
916
+
917
+ ### Server vs Client Components
918
+
919
+ **Default: Server Components**
920
+ - Better performance (less JS shipped)
921
+ - SEO-friendly
922
+ - Direct data access
923
+
924
+ **Use Client Components when:**
925
+ - Need \`useState\`/\`useEffect\`
926
+ - Browser APIs (\`localStorage\`, \`window\`)
927
+ - Event handlers (\`onClick\`, \`onChange\`)
928
+ - Third-party libraries that require \`'use client'\`
929
+
930
+ ### File Structure
931
+
932
+ \`\`\`
933
+ app/
934
+ \u251C\u2500\u2500 layout.tsx # Root layout
935
+ \u251C\u2500\u2500 page.tsx # Home page
936
+ ${config.features.contactForm ? `\u251C\u2500\u2500 api/
937
+ \u2502 \u2514\u2500\u2500 contact/ # Form API
938
+ ` : ""}\u2514\u2500\u2500 ...
939
+
940
+ components/
941
+ \u251C\u2500\u2500 ui/ # shadcn/ui components (DON'T EDIT)
942
+ ${config.type === "landing" ? `\u251C\u2500\u2500 sections/ # Landing sections
943
+ ` : ""}${config.type === "app" ? `\u251C\u2500\u2500 dashboard/ # Dashboard components
944
+ ` : ""}\u2514\u2500\u2500 forms/ # Form components
945
+
946
+ lib/
947
+ \u251C\u2500\u2500 utils.ts # Helpers (cn, etc)
948
+ ${config.features.contactForm ? `\u251C\u2500\u2500 validations.ts # Zod schemas
949
+ ` : ""}${config.stack.email ? `\u251C\u2500\u2500 email.ts # Email client
950
+ ` : ""}${config.stack.auth ? `\u251C\u2500\u2500 auth.ts # Auth config
951
+ ` : ""}\u2514\u2500\u2500 ...
952
+ \`\`\`
953
+
954
+ ## Coding Conventions
955
+
956
+ ### Naming
957
+ - Components: \`PascalCase\` (UserProfile.tsx)
958
+ - Files: \`kebab-case\` (user-profile.tsx)
959
+ - Hooks: \`useCamelCase\` (useAuth.ts)
960
+ - Utils: \`camelCase\` (formatDate)
961
+ - Constants: \`SCREAMING_SNAKE_CASE\`
962
+
963
+ ### Imports Order
964
+ \`\`\`typescript
965
+ // 1. External
966
+ import { useState } from 'react'
967
+ import { cn } from '@/lib/utils'
968
+
969
+ // 2. Internal components
970
+ import { Button } from '@/components/ui/button'
971
+
972
+ // 3. Local
973
+ import { schema } from './validations'
974
+
975
+ // 4. Types
976
+ import type { User } from '@/types'
977
+ \`\`\`
978
+
979
+ ### TypeScript
980
+ - Always use \`type\` for objects
981
+ - Use \`interface\` only for extendable contracts
982
+ - Prefer \`const\` over \`let\`
983
+ - Use arrow functions for components
984
+ - Explicit return types for exported functions
985
+
986
+ ## Project Inventory
987
+
988
+ ${generateProjectInventory(config)}
989
+
990
+ ## Feature Dependencies
991
+
992
+ ${generateFeatureDependencies(config)}
993
+
994
+ ## Common Tasks
995
+
996
+ ### Add a new section
997
+ \`\`\`bash
998
+ # 1. Create component
999
+ touch components/sections/pricing.tsx
1000
+
1001
+ # 2. Add to page
1002
+ # app/page.tsx
1003
+ import { Pricing } from '@/components/sections/pricing'
1004
+ \`\`\`
1005
+
1006
+ ${config.features.contactForm ? `### Add form validation
1007
+ \`\`\`typescript
1008
+ // lib/validations.ts
1009
+ export const contactSchema = z.object({
1010
+ email: z.string().email('Email inv\xE1lido'),
1011
+ message: z.string().min(10, 'M\xEDnimo 10 caracteres'),
1012
+ })
1013
+
1014
+ // components/forms/contact-form.tsx
1015
+ const form = useForm<z.infer<typeof contactSchema>>({
1016
+ resolver: zodResolver(contactSchema),
1017
+ })
1018
+ \`\`\`
1019
+
1020
+ ` : ""}${config.stack.email ? `### Send email
1021
+ \`\`\`typescript
1022
+ // app/api/contact/route.ts
1023
+ import { resend } from '@/lib/email'
1024
+
1025
+ await resend.emails.send({
1026
+ from: 'noreply@example.com',
1027
+ to: 'contact@example.com',
1028
+ subject: 'Novo contato',
1029
+ react: ContactEmail({ name, email, message }),
1030
+ })
1031
+ \`\`\`
1032
+
1033
+ ` : ""}## Performance Targets
1034
+
1035
+ | Metric | Target |
1036
+ |--------|--------|
1037
+ | Lighthouse Performance | 95+ |
1038
+ | LCP | < 2.0s |
1039
+ | CLS | < 0.05 |
1040
+ | Bundle Size | < 100KB |
1041
+
1042
+ ## Environment Variables
1043
+
1044
+ \`\`\`env
1045
+ # Required
1046
+ ${config.stack.email ? `RESEND_API_KEY=re_*** # Get: https://resend.com/api-keys
1047
+ ` : ""}${config.stack.auth ? `NEXTAUTH_SECRET=*** # Generate: openssl rand -base64 32
1048
+ ` : ""}
1049
+ # Optional
1050
+ NEXT_PUBLIC_GA_ID=G-*** # Google Analytics
1051
+ \`\`\`
1052
+
1053
+ ## Testing
1054
+
1055
+ \`\`\`bash
1056
+ bun test # Unit tests
1057
+ bun test:e2e # E2E tests
1058
+ bun lint # ESLint
1059
+ bun typecheck # TypeScript
1060
+ \`\`\`
1061
+
1062
+ ## Deployment
1063
+
1064
+ Auto-deploys to Vercel on push to \`main\`.
1065
+
1066
+ **Manual:**
1067
+ \`\`\`bash
1068
+ vercel --prod
1069
+ \`\`\`
1070
+
1071
+ ## Troubleshooting
1072
+
1073
+ ### Build errors
1074
+ - Clear \`.next\`: \`rm -rf .next\`
1075
+ - Clear cache: \`bun install --force\`
1076
+
1077
+ ### Type errors
1078
+ - Restart TS server in IDE
1079
+ - Check \`tsconfig.json\` paths
1080
+
1081
+ ## Resources
1082
+
1083
+ - [Next.js Docs](https://nextjs.org/docs)
1084
+ - [Tailwind Docs](https://tailwindcss.com/docs)
1085
+ - [shadcn/ui](https://ui.shadcn.com)
1086
+ ${config.stack.email ? `- [Resend Docs](https://resend.com/docs)
1087
+ ` : ""}${config.stack.auth ? `- [NextAuth Docs](https://authjs.dev)
1088
+ ` : ""}
1089
+ ---
1090
+
1091
+ *Generated by @nimbuslab/cli*
1092
+ *Last updated: ${new Date().toISOString().split("T")[0]}*
1093
+ `;
1094
+ await Bun.write(join(projectPath, "AGENTS.md"), content);
1095
+ }
1096
+ async function generateLLMsFile(projectPath, config) {
1097
+ const content = `# ${config.name}
1098
+
1099
+ > AI-friendly documentation index
1100
+
1101
+ ## Navigation
1102
+
1103
+ - [Project Overview](./AGENTS.md)
1104
+ - [Architecture](./ARCHITECTURE.md)
1105
+ - [Examples](./EXAMPLES.md)
1106
+ - [How to Modify](./MODIFICATIONS.md)
1107
+ - [Contributing](./CONTRIBUTING.md)
1108
+
1109
+ ## Quick Context
1110
+
1111
+ ${config.description}
1112
+
1113
+ **Stack:** ${config.stack.framework}, ${config.stack.styling}, ${config.stack.components}
1114
+
1115
+ ## Common Questions
1116
+
1117
+ ### How do I start development?
1118
+ \`\`\`bash
1119
+ bun install && bun dev
1120
+ \`\`\`
1121
+
1122
+ ${config.features.contactForm ? `### How do I configure email?
1123
+ See [AGENTS.md#send-email](./AGENTS.md#send-email)
1124
+
1125
+ ` : ""}${config.features.auth ? `### How do I set up authentication?
1126
+ See [AGENTS.md#environment-variables](./AGENTS.md#environment-variables)
1127
+
1128
+ ` : ""}### How do I deploy?
1129
+ Push to \`main\` branch - auto-deploys to Vercel.
1130
+
1131
+ ## File Structure
1132
+
1133
+ \`\`\`
1134
+ app/ # Next.js app router
1135
+ components/ # React components
1136
+ ui/ # shadcn/ui (auto-generated)
1137
+ lib/ # Utilities
1138
+ public/ # Static assets
1139
+ \`\`\`
1140
+
1141
+ ---
1142
+
1143
+ *Auto-generated for LLM consumption*
1144
+ *Learn more: https://mintlify.com/blog/simplifying-docs-with-llms-txt*
1145
+ `;
1146
+ await Bun.write(join(projectPath, "llms.txt"), content);
1147
+ }
1148
+ async function generateArchitectureDoc(projectPath, config) {
1149
+ const content = `# Architecture
1150
+
1151
+ ## Design Decisions
1152
+
1153
+ ### 1. Next.js App Router
1154
+
1155
+ **Why:**
1156
+ - React Server Components by default
1157
+ - Better performance (less client JS)
1158
+ - Simplified data fetching
1159
+ - Native TypeScript support
1160
+
1161
+ **Trade-offs:**
1162
+ - Learning curve vs Pages Router
1163
+ - Some libraries require \`'use client'\`
1164
+
1165
+ ### 2. ${config.stack.styling}
1166
+
1167
+ **Why:**
1168
+ - Zero runtime (pure CSS)
1169
+ - Better performance
1170
+ - Smaller bundle size
1171
+ - Familiar DX
1172
+
1173
+ ### 3. ${config.stack.components}
1174
+
1175
+ **Why:**
1176
+ - Copy-paste workflow (no lock-in)
1177
+ - Full control over components
1178
+ - Customizable without ejecting
1179
+ - Built on Radix UI (accessibility)
1180
+
1181
+ **Trade-offs:**
1182
+ - Manual updates (not auto-updated via npm)
1183
+ - More files in your repo
1184
+ - Worth it for flexibility
1185
+
1186
+ ${config.type === "landing" ? `### 4. Landing Page Structure
1187
+
1188
+ \`\`\`
1189
+ Hero
1190
+ \u2193
1191
+ Social Proof / Features
1192
+ \u2193
1193
+ How It Works
1194
+ \u2193
1195
+ Testimonials
1196
+ \u2193
1197
+ FAQ
1198
+ \u2193
1199
+ CTA
1200
+ \u2193
1201
+ Footer
1202
+ \`\`\`
1203
+
1204
+ **Why this order:**
1205
+ - Hero grabs attention first
1206
+ - Features build interest
1207
+ - FAQ reduces friction
1208
+ - CTA when ready to convert
1209
+
1210
+ ` : ""}## This Project's Specific Decisions
1211
+
1212
+ ${generateProjectDecisions(config)}
1213
+
1214
+ ## Data Flow
1215
+
1216
+ \`\`\`
1217
+ User Action
1218
+ \u2193
1219
+ Client Component (onClick)
1220
+ \u2193
1221
+ ${config.features.contactForm ? `Server Action / API Route
1222
+ \u2193
1223
+ Validation (Zod)
1224
+ \u2193
1225
+ ` : ""}${config.stack.email ? `External API (Resend)
1226
+ \u2193
1227
+ ` : ""}Response to client
1228
+ \`\`\`
1229
+
1230
+ ## Performance Strategy
1231
+
1232
+ ### 1. Server Components First
1233
+ - Default to Server Components
1234
+ - Only use Client when needed
1235
+ - Less JavaScript shipped
1236
+
1237
+ ### 2. Image Optimization
1238
+ - Always use \`next/image\`
1239
+ - Lazy loading by default
1240
+ - Modern formats (WebP, AVIF)
1241
+
1242
+ ### 3. Code Splitting
1243
+ - Dynamic imports for heavy components
1244
+ - Route-based splitting (automatic)
1245
+
1246
+ ## Security
1247
+
1248
+ ### 1. Environment Variables
1249
+ - Never commit \`.env\`
1250
+ - Use \`.env.example\` for templates
1251
+ - Validate on startup
1252
+
1253
+ ${config.features.contactForm ? `### 2. Form Validation
1254
+ - Client + Server validation
1255
+ - Zod schemas shared
1256
+ - Sanitize inputs
1257
+
1258
+ ` : ""}### 3. Rate Limiting
1259
+ - API routes protected
1260
+ - Per-IP limits
1261
+
1262
+ ---
1263
+
1264
+ *This document explains WHY, not HOW.*
1265
+ *For HOW, see AGENTS.md*
1266
+ `;
1267
+ await Bun.write(join(projectPath, "ARCHITECTURE.md"), content);
1268
+ }
1269
+ async function generateExamplesDoc(projectPath, config) {
1270
+ const content = `# Examples
1271
+
1272
+ Common tasks with complete code examples.
1273
+
1274
+ ## Adding a New Component
1275
+
1276
+ \`\`\`tsx
1277
+ // components/ui/card.tsx
1278
+ export function Card({ children, className }: {
1279
+ children: React.ReactNode
1280
+ className?: string
1281
+ }) {
1282
+ return (
1283
+ <div className={cn("rounded-lg border p-6", className)}>
1284
+ {children}
1285
+ </div>
1286
+ )
1287
+ }
1288
+ \`\`\`
1289
+
1290
+ ${config.features.contactForm ? `## Form with Validation
1291
+
1292
+ \`\`\`tsx
1293
+ // lib/validations.ts
1294
+ export const contactSchema = z.object({
1295
+ name: z.string().min(2, 'Nome muito curto'),
1296
+ email: z.string().email('Email inv\xE1lido'),
1297
+ message: z.string().min(10, 'Mensagem muito curta'),
1298
+ })
1299
+
1300
+ // components/forms/contact.tsx
1301
+ 'use client'
1302
+
1303
+ import { useForm } from 'react-hook-form'
1304
+ import { zodResolver } from '@hookform/resolvers/zod'
1305
+
1306
+ export function ContactForm() {
1307
+ const form = useForm({
1308
+ resolver: zodResolver(contactSchema),
1309
+ })
1310
+
1311
+ async function onSubmit(data) {
1312
+ const res = await fetch('/api/contact', {
1313
+ method: 'POST',
1314
+ body: JSON.stringify(data),
1315
+ })
1316
+ // Handle response
1317
+ }
1318
+
1319
+ return <form onSubmit={form.handleSubmit(onSubmit)}>...</form>
1320
+ }
1321
+ \`\`\`
1322
+
1323
+ ` : ""}## Adding Animation
1324
+
1325
+ \`\`\`tsx
1326
+ 'use client'
1327
+
1328
+ import { motion } from 'framer-motion'
1329
+
1330
+ export function FadeIn({ children }: { children: React.ReactNode }) {
1331
+ return (
1332
+ <motion.div
1333
+ initial={{ opacity: 0, y: 20 }}
1334
+ animate={{ opacity: 1, y: 0 }}
1335
+ transition={{ duration: 0.5 }}
1336
+ >
1337
+ {children}
1338
+ </motion.div>
1339
+ )
1340
+ }
1341
+ \`\`\`
1342
+
1343
+ ## Environment Variables
1344
+
1345
+ \`\`\`typescript
1346
+ // lib/env.ts
1347
+ import { z } from 'zod'
1348
+
1349
+ const envSchema = z.object({
1350
+ ${config.stack.email ? `RESEND_API_KEY: z.string().min(1),
1351
+ ` : ""}NODE_ENV: z.enum(['development', 'production', 'test']),
1352
+ })
1353
+
1354
+ export const env = envSchema.parse(process.env)
1355
+ \`\`\`
1356
+
1357
+ ---
1358
+
1359
+ *For more examples, see the component files*
1360
+ `;
1361
+ await Bun.write(join(projectPath, "EXAMPLES.md"), content);
1362
+ }
1363
+ function generateProjectDecisions(config) {
1364
+ let decisions = "";
1365
+ if (config.stack.email) {
1366
+ decisions += `### Email Provider: ${config.stack.email}
1367
+
1368
+ **Why chosen:**
1369
+ - 3,000 emails/month free tier
1370
+ - React Email support (type-safe templates)
1371
+ - Simple API, great DX
1372
+
1373
+ **Alternatives considered:**
1374
+ - SendGrid: More complex, steeper pricing
1375
+ - Postmark: Great but no free tier
1376
+ - AWS SES: Requires more setup
1377
+
1378
+ **If you need to change:**
1379
+ 1. Update \`lib/email.ts\` client
1380
+ 2. Update env vars (\`.env\`)
1381
+ 3. Update API route implementation
1382
+
1383
+ `;
1384
+ }
1385
+ if (config.stack.forms) {
1386
+ decisions += `### Form Library: ${config.stack.forms}
1387
+
1388
+ **Why chosen:**
1389
+ - Better performance than Formik
1390
+ - Smaller bundle size
1391
+ - Native TypeScript support
1392
+ - Works great with Zod
1393
+
1394
+ **Trade-off:**
1395
+ - More verbose than simple useState
1396
+ - Worth it for complex forms with validation
1397
+
1398
+ **If you need simpler forms:**
1399
+ - Use plain \`<form>\` + \`useState\`
1400
+ - Good for 1-2 field forms
1401
+
1402
+ `;
1403
+ }
1404
+ if (config.features.contactForm) {
1405
+ decisions += `### Contact Form Implementation
1406
+
1407
+ **Current setup:**
1408
+ - Client-side validation (instant feedback)
1409
+ - Server-side validation (security)
1410
+ - Rate limiting (spam prevention)
1411
+
1412
+ **Why both validations:**
1413
+ - Client: Better UX (immediate feedback)
1414
+ - Server: Security (never trust client)
1415
+
1416
+ `;
1417
+ }
1418
+ if (!decisions) {
1419
+ decisions = `No specific architectural decisions documented yet. As you make choices, document them here.
1420
+ `;
1421
+ }
1422
+ return decisions;
1423
+ }
1424
+ function generateProjectInventory(config) {
1425
+ let inventory = `**Implemented Components:**
1426
+ `;
1427
+ if (config.type === "landing") {
1428
+ inventory += `- Hero (\`components/sections/hero.tsx\`) - Main value proposition and CTA
1429
+ - Features (\`components/sections/features.tsx\`) - Product features grid
1430
+ - FAQ (\`components/sections/faq.tsx\`) - Frequently asked questions
1431
+ `;
1432
+ if (config.features.contactForm) {
1433
+ inventory += `- Contact Form (\`components/forms/contact-form.tsx\`) - Email contact with validation
1434
+ `;
1435
+ }
1436
+ }
1437
+ if (config.type === "app") {
1438
+ inventory += `- Dashboard Layout (\`components/dashboard/layout.tsx\`) - Main app layout
1439
+ - Auth Forms (\`components/auth/\`) - Login/signup components
1440
+ `;
1441
+ }
1442
+ inventory += `
1443
+ **API Routes:**
1444
+ `;
1445
+ if (config.features.contactForm) {
1446
+ inventory += `- \`/api/contact\` - Form submission handler (rate-limited, ${config.stack.email || "email"} integration)
1447
+ `;
1448
+ }
1449
+ if (config.features.auth) {
1450
+ inventory += `- \`/api/auth/[...nextauth]\` - Authentication endpoints
1451
+ `;
1452
+ }
1453
+ if (!config.features.contactForm && !config.features.auth) {
1454
+ inventory += `- None yet (add API routes in \`app/api/\`)
1455
+ `;
1456
+ }
1457
+ inventory += `
1458
+ **Utilities:**
1459
+ `;
1460
+ if (config.stack.email) {
1461
+ inventory += `- \`lib/email.ts\` - ${config.stack.email} client configuration
1462
+ `;
1463
+ }
1464
+ if (config.features.contactForm) {
1465
+ inventory += `- \`lib/validations.ts\` - Zod schemas (contactSchema: name, email, message)
1466
+ `;
1467
+ }
1468
+ inventory += `- \`lib/utils.ts\` - Helper functions (cn, formatters)
1469
+ `;
1470
+ return inventory;
1471
+ }
1472
+ function generateFeatureDependencies(config) {
1473
+ let deps = "";
1474
+ if (config.features.contactForm) {
1475
+ deps += `**Contact Form** depends on:
1476
+ \`\`\`
1477
+ \u251C\u2500 React Hook Form (form state management)
1478
+ \u251C\u2500 Zod (validation schemas)
1479
+ ${config.stack.email ? `\u251C\u2500 ${config.stack.email} (email sending)
1480
+ ` : ""}\u2514\u2500 /api/contact (server endpoint)
1481
+ \`\`\`
1482
+
1483
+ **To modify contact form:**
1484
+ 1. Update validation: \`lib/validations.ts\` (contactSchema)
1485
+ 2. Update UI: \`components/forms/contact-form.tsx\`
1486
+ 3. Update API: \`app/api/contact/route.ts\`
1487
+ 4. Update email template: \`emails/contact-email.tsx\` (if exists)
1488
+
1489
+ `;
1490
+ }
1491
+ if (config.features.auth) {
1492
+ deps += `**Authentication** depends on:
1493
+ \`\`\`
1494
+ \u251C\u2500 ${config.stack.auth} (auth provider)
1495
+ \u251C\u2500 Database (user storage)
1496
+ \u2514\u2500 /api/auth/[...nextauth] (auth endpoints)
1497
+ \`\`\`
1498
+
1499
+ **To modify auth:**
1500
+ 1. Update config: \`lib/auth.ts\`
1501
+ 2. Update providers: Add/remove in auth config
1502
+ 3. Update callbacks: Customize JWT/session
1503
+
1504
+ `;
1505
+ }
1506
+ if (!deps) {
1507
+ deps = `No complex feature dependencies yet. Add features and their dependency maps will appear here.
1508
+ `;
1509
+ }
1510
+ return deps;
1511
+ }
1512
+ async function generateModificationsDoc(projectPath, config) {
1513
+ let content = `# Modification Guide
1514
+
1515
+ This file shows you exactly how to modify existing features in this project.
1516
+
1517
+ > **Context-aware:** These are the actual files in YOUR project, not generic examples.
1518
+
1519
+ `;
1520
+ if (config.type === "landing") {
1521
+ content += `## Landing Page Sections
1522
+
1523
+ ### Change Hero Text
1524
+
1525
+ **File:** \`components/sections/hero.tsx\`
1526
+ **What to edit:** Lines with \`<h1>\` and \`<p>\` tags
1527
+ **Current pattern:** Value proposition + subheading + CTA
1528
+ **Example change:**
1529
+ \`\`\`tsx
1530
+ <h1 className="text-4xl font-bold">
1531
+ Your New Headline Here
1532
+ </h1>
1533
+ <p className="text-xl text-muted-foreground">
1534
+ Your new subheading
1535
+ </p>
1536
+ \`\`\`
1537
+
1538
+ ### Add/Remove Feature Cards
1539
+
1540
+ **File:** \`components/sections/features.tsx\`
1541
+ **What to edit:** \`features\` array (usually lines 10-25)
1542
+ **Current:** 3 feature cards
1543
+ **To add:** Push new object to array: \`{ icon: Icon, title: "", description: "" }\`
1544
+ **To remove:** Delete object from array or filter it out
1545
+
1546
+ ### Modify FAQ Questions
1547
+
1548
+ **File:** \`components/sections/faq.tsx\`
1549
+ **What to edit:** \`questions\` array
1550
+ **Current:** Pre-populated with common questions
1551
+ **Pattern:** Keep answers concise (< 100 chars) for better UX
1552
+ **To add:** \`{ question: "...", answer: "..." }\`
1553
+
1554
+ `;
1555
+ }
1556
+ if (config.features.contactForm) {
1557
+ content += `## Contact Form
1558
+
1559
+ ### Change Form Fields
1560
+
1561
+ **Files to modify:**
1562
+ 1. \`lib/validations.ts\` - Add field to schema
1563
+ 2. \`components/forms/contact-form.tsx\` - Add UI input
1564
+ 3. \`app/api/contact/route.ts\` - Handle new field
1565
+
1566
+ **Example: Add phone field**
1567
+ \`\`\`typescript
1568
+ // 1. lib/validations.ts
1569
+ export const contactSchema = z.object({
1570
+ name: z.string().min(2),
1571
+ email: z.string().email(),
1572
+ phone: z.string().min(10), // NEW
1573
+ message: z.string().min(10),
1574
+ })
1575
+
1576
+ // 2. components/forms/contact-form.tsx
1577
+ <FormField
1578
+ name="phone"
1579
+ control={form.control}
1580
+ render={({ field }) => (
1581
+ <Input placeholder="Phone" {...field} />
1582
+ )}
1583
+ />
1584
+
1585
+ // 3. app/api/contact/route.ts
1586
+ // Phone is now available in validated data
1587
+ const { name, email, phone, message } = validated.data
1588
+ \`\`\`
1589
+
1590
+ ### Change Email Template
1591
+
1592
+ **File:** \`emails/contact-email.tsx\` (if using React Email)
1593
+ **Alternative:** Inline in \`app/api/contact/route.ts\`
1594
+ **What to edit:** Subject, body content, styling
1595
+ **Test locally:** \`bun run email:dev\` (if available)
1596
+
1597
+ ### Change Email Recipient
1598
+
1599
+ **File:** \`app/api/contact/route.ts\`
1600
+ **What to edit:** The \`to:\` field in email send
1601
+ \`\`\`typescript
1602
+ await resend.emails.send({
1603
+ to: 'your-new-email@example.com', // CHANGE THIS
1604
+ // ...
1605
+ })
1606
+ \`\`\`
1607
+
1608
+ `;
1609
+ }
1610
+ content += `## Styling Changes
1611
+
1612
+ ### Update Colors
1613
+
1614
+ **File:** \`app/globals.css\`
1615
+ **What to edit:** CSS variables in \`:root\` and \`.dark\`
1616
+ \`\`\`css
1617
+ :root {
1618
+ --primary: 220 90% 56%; /* Change this */
1619
+ }
1620
+ \`\`\`
1621
+ **Tip:** Use [shadcn theme editor](https://ui.shadcn.com/themes) to generate new colors
1622
+
1623
+ ### Change Fonts
1624
+
1625
+ **File:** \`app/layout.tsx\`
1626
+ **What to edit:** Font imports and \`className\` on \`<body>\`
1627
+ \`\`\`tsx
1628
+ import { Inter } from 'next/font/google'
1629
+
1630
+ const font = Inter({ subsets: ['latin'] })
1631
+
1632
+ <body className={font.className}>
1633
+ \`\`\`
1634
+
1635
+ ## Adding New Features
1636
+
1637
+ ### Add a New Page
1638
+
1639
+ \`\`\`bash
1640
+ # 1. Create route
1641
+ touch app/about/page.tsx
1642
+
1643
+ # 2. Add navigation link
1644
+ # Edit: components/layout/header.tsx or footer.tsx
1645
+ \`\`\`
1646
+
1647
+ ### Add shadcn/ui Component
1648
+
1649
+ \`\`\`bash
1650
+ bunx --bun shadcn@latest add [component-name]
1651
+ # Example: bunx --bun shadcn@latest add dialog
1652
+ \`\`\`
1653
+
1654
+ ## Environment Variables
1655
+
1656
+ **File:** \`.env\` (create from \`.env.example\`)
1657
+
1658
+ ${config.stack.email ? `### ${config.stack.email} API Key
1659
+ \`\`\`env
1660
+ RESEND_API_KEY=re_xxxxxxxxxxxx
1661
+ \`\`\`
1662
+ **Get key:** [${config.stack.email} Dashboard](https://resend.com/api-keys)
1663
+
1664
+ ` : ""}${config.features.analytics ? `### Google Analytics
1665
+ \`\`\`env
1666
+ NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
1667
+ \`\`\`
1668
+ **Get ID:** [Google Analytics](https://analytics.google.com)
1669
+
1670
+ ` : ""}## Common Modifications
1671
+
1672
+ ### Change Site Metadata (SEO)
1673
+
1674
+ **File:** \`app/layout.tsx\`
1675
+ **What to edit:** \`metadata\` export
1676
+ \`\`\`tsx
1677
+ export const metadata = {
1678
+ title: 'Your New Title',
1679
+ description: 'Your new description',
1680
+ // ...
1681
+ }
1682
+ \`\`\`
1683
+
1684
+ ### Add Custom Font from File
1685
+
1686
+ \`\`\`tsx
1687
+ // app/layout.tsx
1688
+ import localFont from 'next/font/local'
1689
+
1690
+ const customFont = localFont({
1691
+ src: './fonts/CustomFont.woff2',
1692
+ variable: '--font-custom',
1693
+ })
1694
+ \`\`\`
1695
+
1696
+ ---
1697
+
1698
+ **Pro tip:** Before modifying, search the codebase for the text/component you want to change:
1699
+ \`\`\`bash
1700
+ grep -r "text to find" .
1701
+ \`\`\`
1702
+ `;
1703
+ await Bun.write(join(projectPath, "MODIFICATIONS.md"), content);
1704
+ }
1705
+ async function createCompatibilitySymlinks(projectPath) {
1706
+ const agentsContent = await Bun.file(join(projectPath, "AGENTS.md")).text();
1707
+ await Bun.write(join(projectPath, ".cursorrules"), agentsContent);
1708
+ const githubDir = join(projectPath, ".github");
1709
+ await Bun.$`mkdir -p ${githubDir}`.quiet();
1710
+ await Bun.write(join(githubDir, "copilot-instructions.md"), agentsContent);
1711
+ }
1712
+ // src/lib/generators/interactive-setup.ts
1713
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
1714
+ var SERVICE_INFO = {
1715
+ resend: {
1716
+ name: "Resend",
1717
+ description: "Servi\xE7o de email transacional",
1718
+ pricing: "Gr\xE1tis: 3,000 emails/m\xEAs",
1719
+ signupUrl: "https://resend.com/signup",
1720
+ apiKeyUrl: "https://resend.com/api-keys",
1721
+ keyPrefix: "re_"
1722
+ },
1723
+ googleAnalytics: {
1724
+ name: "Google Analytics",
1725
+ description: "Analytics e m\xE9tricas do site",
1726
+ pricing: "Gr\xE1tis",
1727
+ setupUrl: "https://analytics.google.com",
1728
+ keyFormat: "G-XXXXXXXXXX"
1729
+ }
1730
+ };
1731
+ async function interactiveSetup(templateType) {
1732
+ console.log();
1733
+ console.log(import_picocolors3.default.cyan(" Configura\xE7\xE3o Interativa"));
1734
+ console.log(import_picocolors3.default.dim(" ======================="));
1735
+ console.log();
1736
+ const skipSetup = await ye({
1737
+ message: "Deseja configurar integra\xE7\xF5es agora?",
1738
+ initialValue: true
1739
+ });
1740
+ if (pD(skipSetup) || !skipSetup) {
1741
+ return {
1742
+ features: {
1743
+ contactForm: false,
1744
+ newsletter: false,
1745
+ analytics: false
1746
+ },
1747
+ apiKeys: {},
1748
+ skipSetup: true
1749
+ };
1750
+ }
1751
+ const result = {
1752
+ features: {
1753
+ contactForm: false,
1754
+ newsletter: false,
1755
+ analytics: false
1756
+ },
1757
+ apiKeys: {},
1758
+ skipSetup: false
1759
+ };
1760
+ if (templateType === "landing" || templateType === "app") {
1761
+ const contactFormSetup = await setupContactForm();
1762
+ if (!pD(contactFormSetup)) {
1763
+ result.features.contactForm = contactFormSetup.enabled;
1764
+ if (contactFormSetup.apiKey) {
1765
+ result.apiKeys.resend = contactFormSetup.apiKey;
1766
+ }
1767
+ }
1768
+ }
1769
+ const analyticsSetup = await setupAnalytics();
1770
+ if (!pD(analyticsSetup)) {
1771
+ result.features.analytics = analyticsSetup.enabled;
1772
+ if (analyticsSetup.trackingId) {
1773
+ result.apiKeys.ga = analyticsSetup.trackingId;
1774
+ }
1775
+ }
1776
+ return result;
1777
+ }
1778
+ async function setupContactForm() {
1779
+ console.log();
1780
+ console.log(import_picocolors3.default.cyan(" \uD83D\uDCE7 Formul\xE1rio de Contato"));
1781
+ console.log();
1782
+ const needsForm = await ve({
1783
+ message: "Incluir formul\xE1rio de contato?",
1784
+ options: [
1785
+ { value: "now", label: "Sim, configurar agora" },
1786
+ { value: "later", label: "Sim, mas configurar depois" },
1787
+ { value: "no", label: "N\xE3o incluir" }
1788
+ ]
1789
+ });
1790
+ if (pD(needsForm) || needsForm === "no") {
1791
+ return { enabled: false };
1792
+ }
1793
+ if (needsForm === "later") {
1794
+ return { enabled: true };
1795
+ }
1796
+ showServiceInfo("resend");
1797
+ const apiKey = await he({
1798
+ message: "Resend API Key (deixe vazio para configurar depois):",
1799
+ placeholder: "re_...",
1800
+ validate: (v2) => {
1801
+ if (!v2)
1802
+ return;
1803
+ if (!v2.startsWith(SERVICE_INFO.resend.keyPrefix)) {
1804
+ return `Key inv\xE1lida (deve come\xE7ar com ${SERVICE_INFO.resend.keyPrefix})`;
1805
+ }
1806
+ return;
1807
+ }
1808
+ });
1809
+ if (pD(apiKey)) {
1810
+ return { enabled: true };
1811
+ }
1812
+ return {
1813
+ enabled: true,
1814
+ apiKey: apiKey || undefined
1815
+ };
1816
+ }
1817
+ async function setupAnalytics() {
1818
+ console.log();
1819
+ console.log(import_picocolors3.default.cyan(" \uD83D\uDCCA Analytics"));
1820
+ console.log();
1821
+ const needsAnalytics = await ye({
1822
+ message: "Incluir Google Analytics?",
1823
+ initialValue: false
1824
+ });
1825
+ if (pD(needsAnalytics) || !needsAnalytics) {
1826
+ return { enabled: false };
1827
+ }
1828
+ showServiceInfo("googleAnalytics");
1829
+ const trackingId = await he({
1830
+ message: "Google Analytics Tracking ID (deixe vazio para configurar depois):",
1831
+ placeholder: "G-XXXXXXXXXX",
1832
+ validate: (v2) => {
1833
+ if (!v2)
1834
+ return;
1835
+ if (!v2.startsWith("G-")) {
1836
+ return "ID inv\xE1lido (deve come\xE7ar com G-)";
1837
+ }
1838
+ return;
1839
+ }
1840
+ });
1841
+ if (pD(trackingId)) {
1842
+ return { enabled: false };
1843
+ }
1844
+ return {
1845
+ enabled: true,
1846
+ trackingId: trackingId || undefined
1847
+ };
1848
+ }
1849
+ function showServiceInfo(service) {
1850
+ const info = SERVICE_INFO[service];
1851
+ console.log();
1852
+ console.log(import_picocolors3.default.bold(` ${info.name}`));
1853
+ console.log(import_picocolors3.default.dim(` ${info.description}`));
1854
+ console.log(import_picocolors3.default.dim(` ${info.pricing}`));
1855
+ if ("apiKeyUrl" in info) {
1856
+ console.log(import_picocolors3.default.cyan(` ${info.apiKeyUrl}`));
1857
+ } else if ("setupUrl" in info) {
1858
+ console.log(import_picocolors3.default.cyan(` ${info.setupUrl}`));
1859
+ }
1860
+ console.log();
1861
+ }
1862
+ async function generateEnvFile(projectPath, apiKeys, features) {
1863
+ const lines = [
1864
+ "# ====================================",
1865
+ "# Environment Variables",
1866
+ "# ====================================",
1867
+ "",
1868
+ "# IMPORTANT: Add this file to .gitignore",
1869
+ "# Never commit API keys to version control!",
1870
+ ""
1871
+ ];
1872
+ if (features.contactForm) {
1873
+ lines.push("# Email (Resend)");
1874
+ lines.push("# Get your key: https://resend.com/api-keys");
1875
+ lines.push(`RESEND_API_KEY=${apiKeys.resend || "your_api_key_here"}`);
1876
+ lines.push("");
1877
+ }
1878
+ if (features.analytics) {
1879
+ lines.push("# Analytics (Google Analytics)");
1880
+ lines.push("# Get your ID: https://analytics.google.com");
1881
+ lines.push(`NEXT_PUBLIC_GA_ID=${apiKeys.ga || "G-XXXXXXXXXX"}`);
1882
+ lines.push("");
1883
+ }
1884
+ lines.push("# ====================================");
1885
+ lines.push("# Docs completa em README.md");
1886
+ lines.push("# ====================================");
1887
+ const content = lines.join(`
1888
+ `);
1889
+ await Bun.write(`${projectPath}/.env`, content);
1890
+ const exampleLines = lines.map((line) => {
1891
+ if (line.includes("RESEND_API_KEY=") && !line.startsWith("#")) {
1892
+ return "RESEND_API_KEY=re_your_key_here";
1893
+ }
1894
+ if (line.includes("NEXT_PUBLIC_GA_ID=") && !line.startsWith("#")) {
1895
+ return "NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX";
1896
+ }
1897
+ return line;
1898
+ });
1899
+ await Bun.write(`${projectPath}/.env.example`, exampleLines.join(`
1900
+ `));
1901
+ }
1902
+ // src/commands/create.ts
872
1903
  var AI_CONFIGS = {
873
1904
  claude: {
874
1905
  filename: "CLAUDE.md",
@@ -1068,7 +2099,7 @@ async function ensureRailwayCli() {
1068
2099
  const hasRailway = await $2`${checkCmd} railway`.quiet().then(() => true).catch(() => false);
1069
2100
  if (hasRailway)
1070
2101
  return true;
1071
- console.log(import_picocolors3.default.yellow("Railway CLI not found. Installing..."));
2102
+ console.log(import_picocolors4.default.yellow("Railway CLI not found. Installing..."));
1072
2103
  console.log();
1073
2104
  try {
1074
2105
  if (process.platform === "win32") {
@@ -1076,11 +2107,11 @@ async function ensureRailwayCli() {
1076
2107
  } else {
1077
2108
  await $2`curl -fsSL https://railway.app/install.sh | sh`.quiet();
1078
2109
  }
1079
- console.log(import_picocolors3.default.green("Railway CLI installed successfully!"));
2110
+ console.log(import_picocolors4.default.green("Railway CLI installed successfully!"));
1080
2111
  return true;
1081
2112
  } catch (error) {
1082
- console.log(import_picocolors3.default.red("Error installing Railway CLI."));
1083
- console.log(import_picocolors3.default.dim("Install manually: https://docs.railway.app/guides/cli"));
2113
+ console.log(import_picocolors4.default.red("Error installing Railway CLI."));
2114
+ console.log(import_picocolors4.default.dim("Install manually: https://docs.railway.app/guides/cli"));
1084
2115
  return false;
1085
2116
  }
1086
2117
  }
@@ -1108,38 +2139,38 @@ async function create(args) {
1108
2139
  const hasGit = await $2`${checkCmd} git`.quiet().then(() => true).catch(() => false);
1109
2140
  const hasGh = await $2`${checkCmd} gh`.quiet().then(() => true).catch(() => false);
1110
2141
  if (!hasBun) {
1111
- console.log(import_picocolors3.default.red("Error: Bun not found."));
1112
- console.log(import_picocolors3.default.dim("Install from: https://bun.sh"));
2142
+ console.log(import_picocolors4.default.red("Error: Bun not found."));
2143
+ console.log(import_picocolors4.default.dim("Install from: https://bun.sh"));
1113
2144
  console.log();
1114
2145
  if (process.platform === "win32") {
1115
- console.log(import_picocolors3.default.cyan('powershell -c "irm bun.sh/install.ps1 | iex"'));
2146
+ console.log(import_picocolors4.default.cyan('powershell -c "irm bun.sh/install.ps1 | iex"'));
1116
2147
  } else {
1117
- console.log(import_picocolors3.default.cyan("curl -fsSL https://bun.sh/install | bash"));
2148
+ console.log(import_picocolors4.default.cyan("curl -fsSL https://bun.sh/install | bash"));
1118
2149
  }
1119
2150
  console.log();
1120
2151
  process.exit(1);
1121
2152
  }
1122
2153
  if (!hasGit) {
1123
- console.log(import_picocolors3.default.red("Error: Git not found."));
1124
- console.log(import_picocolors3.default.dim("Install git to continue."));
2154
+ console.log(import_picocolors4.default.red("Error: Git not found."));
2155
+ console.log(import_picocolors4.default.dim("Install git to continue."));
1125
2156
  process.exit(1);
1126
2157
  }
1127
2158
  if (!hasGh) {
1128
- console.log(import_picocolors3.default.dim(" GitHub CLI not found (repo creation will be skipped)"));
1129
- console.log(import_picocolors3.default.dim(" Install from: https://cli.github.com"));
2159
+ console.log(import_picocolors4.default.dim(" GitHub CLI not found (repo creation will be skipped)"));
2160
+ console.log(import_picocolors4.default.dim(" Install from: https://cli.github.com"));
1130
2161
  console.log();
1131
2162
  }
1132
2163
  const hasRailway = await ensureRailwayCli();
1133
2164
  if (hasRailway) {
1134
2165
  const railwayAuth = await isRailwayAuthenticated();
1135
2166
  if (!railwayAuth) {
1136
- console.log(import_picocolors3.default.yellow("Railway CLI not authenticated."));
1137
- console.log(import_picocolors3.default.dim("Run: railway login"));
2167
+ console.log(import_picocolors4.default.yellow("Railway CLI not authenticated."));
2168
+ console.log(import_picocolors4.default.dim("Run: railway login"));
1138
2169
  console.log();
1139
2170
  }
1140
2171
  }
1141
2172
  const { flags, projectName } = parseFlags(args);
1142
- Ie(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" New nimbuslab Project ")));
2173
+ Ie(import_picocolors4.default.bgCyan(import_picocolors4.default.black(" New nimbuslab Project ")));
1143
2174
  let config;
1144
2175
  const hasTypeFlag = flags.landing || flags.app || flags.turborepo || flags.fast || flags.fastPlus || flags.fastTurborepo || flags.core;
1145
2176
  const typeFromFlag = flags.landing ? "landing" : flags.app ? "app" : flags.turborepo ? "turborepo" : flags.fastTurborepo ? "fast+" : flags.fastPlus ? "fast+" : flags.fast ? "fast" : flags.core ? "nimbus-core" : null;
@@ -1168,14 +2199,14 @@ async function create(args) {
1168
2199
  customTemplate: flags.template
1169
2200
  };
1170
2201
  const typeLabel = flags.turborepo ? "fast+ (monorepo)" : config.type;
1171
- console.log(import_picocolors3.default.dim(` Project: ${projectName}`));
1172
- console.log(import_picocolors3.default.dim(` Type: ${typeLabel}`));
1173
- console.log(import_picocolors3.default.dim(` Git: ${config.git ? "yes" : "no"}`));
1174
- console.log(import_picocolors3.default.dim(` Install: ${config.install ? "yes" : "no"}`));
2202
+ console.log(import_picocolors4.default.dim(` Project: ${projectName}`));
2203
+ console.log(import_picocolors4.default.dim(` Type: ${typeLabel}`));
2204
+ console.log(import_picocolors4.default.dim(` Git: ${config.git ? "yes" : "no"}`));
2205
+ console.log(import_picocolors4.default.dim(` Install: ${config.install ? "yes" : "no"}`));
1175
2206
  if (flags.railway)
1176
- console.log(import_picocolors3.default.dim(` Railway: configurar`));
2207
+ console.log(import_picocolors4.default.dim(` Railway: configurar`));
1177
2208
  if (flags.template)
1178
- console.log(import_picocolors3.default.dim(` Template: ${flags.template}`));
2209
+ console.log(import_picocolors4.default.dim(` Template: ${flags.template}`));
1179
2210
  console.log();
1180
2211
  if (flags.railway) {
1181
2212
  const railwayAuthenticated = await isRailwayAuthenticated();
@@ -1185,21 +2216,21 @@ async function create(args) {
1185
2216
  const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
1186
2217
  if (fastProject) {
1187
2218
  config.railwayProject = fastProject;
1188
- console.log(import_picocolors3.default.green(` Railway: ${fastProject}`));
2219
+ console.log(import_picocolors4.default.green(` Railway: ${fastProject}`));
1189
2220
  }
1190
2221
  } else {
1191
- console.log(import_picocolors3.default.dim(` Creating project Railway: ${projectName}...`));
2222
+ console.log(import_picocolors4.default.dim(` Creating project Railway: ${projectName}...`));
1192
2223
  try {
1193
2224
  const result = await $2`echo "" | railway init -n ${projectName} -w nimbuslab --json`.text();
1194
2225
  const newProject = JSON.parse(result);
1195
2226
  config.railwayProject = newProject.name || projectName;
1196
- console.log(import_picocolors3.default.green(` Railway: ${config.railwayProject} criado`));
2227
+ console.log(import_picocolors4.default.green(` Railway: ${config.railwayProject} criado`));
1197
2228
  } catch {
1198
- console.log(import_picocolors3.default.yellow(` Railway: erro ao criar projeto`));
2229
+ console.log(import_picocolors4.default.yellow(` Railway: erro ao criar projeto`));
1199
2230
  }
1200
2231
  }
1201
2232
  } else {
1202
- console.log(import_picocolors3.default.yellow(` Railway: not authenticated (railway login)`));
2233
+ console.log(import_picocolors4.default.yellow(` Railway: not authenticated (railway login)`));
1203
2234
  }
1204
2235
  console.log();
1205
2236
  }
@@ -1211,13 +2242,58 @@ async function create(args) {
1211
2242
  process.exit(0);
1212
2243
  }
1213
2244
  await createProject(config);
1214
- Se(import_picocolors3.default.green("Project created successfully!"));
2245
+ const finalConfig = config;
2246
+ const isPublicTemplate = ["landing", "app", "turborepo"].includes(finalConfig.type);
2247
+ if (isPublicTemplate) {
2248
+ const s = Y2();
2249
+ s.start("Configura\xE7\xE3o de servi\xE7os...");
2250
+ const setupResult = await interactiveSetup(finalConfig.type);
2251
+ s.stop("Configura\xE7\xE3o conclu\xEDda");
2252
+ s.start("Gerando documenta\xE7\xE3o AI-friendly...");
2253
+ try {
2254
+ const generatorConfig = {
2255
+ name: finalConfig.name,
2256
+ type: finalConfig.type,
2257
+ description: finalConfig.githubDescription || `${finalConfig.type} criado com nimbus-cli`,
2258
+ stack: {
2259
+ framework: "Next.js 16 (App Router)",
2260
+ styling: "Tailwind CSS 4",
2261
+ components: "shadcn/ui (default)",
2262
+ forms: setupResult.features.contactForm ? "React Hook Form + Zod" : undefined,
2263
+ email: setupResult.features.contactForm ? "Resend" : undefined,
2264
+ auth: finalConfig.type === "app" ? "Better Auth" : undefined
2265
+ },
2266
+ features: {
2267
+ contactForm: setupResult.features.contactForm,
2268
+ newsletter: setupResult.features.newsletter,
2269
+ analytics: setupResult.features.analytics,
2270
+ auth: finalConfig.type === "app"
2271
+ }
2272
+ };
2273
+ await generateAIFriendlyDocs(finalConfig.name, generatorConfig);
2274
+ s.stop("Documenta\xE7\xE3o AI-friendly gerada");
2275
+ } catch (error) {
2276
+ s.stop("Erro ao gerar documenta\xE7\xE3o AI-friendly");
2277
+ console.log(import_picocolors4.default.dim(" Voc\xEA pode gerar manualmente depois"));
2278
+ }
2279
+ if (!setupResult.skipSetup && (setupResult.apiKeys.resend || setupResult.apiKeys.ga)) {
2280
+ s.start("Gerando arquivos .env...");
2281
+ try {
2282
+ await generateEnvFile(finalConfig.name, setupResult.apiKeys, setupResult.features);
2283
+ s.stop("Arquivos .env gerados (.env e .env.example)");
2284
+ } catch (error) {
2285
+ s.stop("Erro ao gerar .env");
2286
+ console.log(import_picocolors4.default.dim(" Voc\xEA pode criar manualmente depois"));
2287
+ }
2288
+ }
2289
+ }
2290
+ Se(import_picocolors4.default.green("Project created successfully!"));
1215
2291
  showNextSteps(config);
1216
2292
  }
1217
2293
  async function promptConfig(initialName, flags) {
1218
2294
  const { isMember, user } = await isNimbuslabMember();
1219
2295
  const greeting = user ? `Hello, ${user}!` : "Hello!";
1220
- console.log(import_picocolors3.default.dim(` ${greeting}`));
2296
+ console.log(import_picocolors4.default.dim(` ${greeting}`));
1221
2297
  console.log();
1222
2298
  const name = await he({
1223
2299
  message: "Project name:",
@@ -1276,12 +2352,12 @@ async function promptConfig(initialName, flags) {
1276
2352
  return type;
1277
2353
  const isPublicTemplate = ["landing", "app", "turborepo"].includes(type);
1278
2354
  if (!isMember && !isPublicTemplate) {
1279
- console.log(import_picocolors3.default.red("Error: Template available only for nimbuslab members"));
2355
+ console.log(import_picocolors4.default.red("Error: Template available only for nimbuslab members"));
1280
2356
  process.exit(1);
1281
2357
  }
1282
2358
  if (type === "nimbus-core") {
1283
2359
  console.log();
1284
- console.log(import_picocolors3.default.dim(" nimbus-core: Motor para projetos externos (stealth mode)"));
2360
+ console.log(import_picocolors4.default.dim(" nimbus-core: Motor para projetos externos (stealth mode)"));
1285
2361
  console.log();
1286
2362
  const repoOption = await ve({
1287
2363
  message: "Create repository for this project?",
@@ -1496,7 +2572,7 @@ async function promptConfig(initialName, flags) {
1496
2572
  const configItems = infraOptions;
1497
2573
  if (configItems.includes("urls")) {
1498
2574
  console.log();
1499
- console.log(import_picocolors3.default.dim(" Project URLs"));
2575
+ console.log(import_picocolors4.default.dim(" Project URLs"));
1500
2576
  const staging = await he({
1501
2577
  message: "Staging URL:",
1502
2578
  placeholder: defaultStagingUrl,
@@ -1516,7 +2592,7 @@ async function promptConfig(initialName, flags) {
1516
2592
  }
1517
2593
  if (configItems.includes("resend")) {
1518
2594
  console.log();
1519
- console.log(import_picocolors3.default.dim(" Resend (Email)"));
2595
+ console.log(import_picocolors4.default.dim(" Resend (Email)"));
1520
2596
  const resendKey = await he({
1521
2597
  message: "RESEND_API_KEY:",
1522
2598
  placeholder: "re_xxxxxxxxxxxx"
@@ -1545,16 +2621,16 @@ async function promptConfig(initialName, flags) {
1545
2621
  const railwayAuthenticated = await isRailwayAuthenticated();
1546
2622
  if (railwayAuthenticated) {
1547
2623
  console.log();
1548
- console.log(import_picocolors3.default.dim(" Railway"));
2624
+ console.log(import_picocolors4.default.dim(" Railway"));
1549
2625
  const projects = await listRailwayProjects();
1550
2626
  if (type === "fast") {
1551
2627
  const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
1552
2628
  if (fastProject) {
1553
2629
  railwayProject = fastProject;
1554
- console.log(import_picocolors3.default.green(` Project: ${fastProject} (automatico)`));
2630
+ console.log(import_picocolors4.default.green(` Project: ${fastProject} (automatico)`));
1555
2631
  } else {
1556
- console.log(import_picocolors3.default.yellow(" Project 'Fast by nimbuslab' not found."));
1557
- console.log(import_picocolors3.default.dim(" Configure manually in .env"));
2632
+ console.log(import_picocolors4.default.yellow(" Project 'Fast by nimbuslab' not found."));
2633
+ console.log(import_picocolors4.default.dim(" Configure manually in .env"));
1558
2634
  }
1559
2635
  } else {
1560
2636
  const projectOptions = [
@@ -1570,26 +2646,26 @@ async function promptConfig(initialName, flags) {
1570
2646
  return selectedProject;
1571
2647
  if (selectedProject === "__new__") {
1572
2648
  const projectNameForRailway = name;
1573
- console.log(import_picocolors3.default.dim(` Creating project "${projectNameForRailway}" on Railway...`));
2649
+ console.log(import_picocolors4.default.dim(` Creating project "${projectNameForRailway}" on Railway...`));
1574
2650
  try {
1575
2651
  const result = await $2`echo "" | railway init -n ${projectNameForRailway} -w nimbuslab --json`.text();
1576
2652
  const newProject = JSON.parse(result);
1577
2653
  railwayProject = newProject.name || projectNameForRailway;
1578
- console.log(import_picocolors3.default.green(` Projeto "${railwayProject}" created successfully!`));
1579
- console.log(import_picocolors3.default.dim(` ID: ${newProject.id || "N/A"}`));
2654
+ console.log(import_picocolors4.default.green(` Projeto "${railwayProject}" created successfully!`));
2655
+ console.log(import_picocolors4.default.dim(` ID: ${newProject.id || "N/A"}`));
1580
2656
  } catch (error) {
1581
- console.log(import_picocolors3.default.yellow(" Error creating project via CLI."));
1582
- console.log(import_picocolors3.default.dim(" Create manually at: https://railway.app/new"));
2657
+ console.log(import_picocolors4.default.yellow(" Error creating project via CLI."));
2658
+ console.log(import_picocolors4.default.dim(" Create manually at: https://railway.app/new"));
1583
2659
  }
1584
2660
  } else if (selectedProject !== "__skip__") {
1585
2661
  railwayProject = selectedProject;
1586
- console.log(import_picocolors3.default.green(` Project selected: ${railwayProject}`));
2662
+ console.log(import_picocolors4.default.green(` Project selected: ${railwayProject}`));
1587
2663
  }
1588
2664
  }
1589
2665
  } else {
1590
2666
  console.log();
1591
- console.log(import_picocolors3.default.yellow(" Railway: not authenticated (railway login)"));
1592
- console.log(import_picocolors3.default.dim(" Configure manually in .env"));
2667
+ console.log(import_picocolors4.default.yellow(" Railway: not authenticated (railway login)"));
2668
+ console.log(import_picocolors4.default.dim(" Configure manually in .env"));
1593
2669
  }
1594
2670
  }
1595
2671
  const install = await ye({
@@ -1641,7 +2717,7 @@ async function createProject(config) {
1641
2717
  } else {
1642
2718
  await $2`gh repo clone ${templateRepo} ${config.name} -- --depth 1`.quiet();
1643
2719
  }
1644
- await rm(join(config.name, ".git"), { recursive: true, force: true });
2720
+ await rm(join2(config.name, ".git"), { recursive: true, force: true });
1645
2721
  s.stop(`Template cloned`);
1646
2722
  } catch (error) {
1647
2723
  s.stop("Error cloning template");
@@ -1662,7 +2738,7 @@ async function createProject(config) {
1662
2738
  s.stop(`Client repo cloned: workspace/${projectName}`);
1663
2739
  } catch (error) {
1664
2740
  s.stop("Error cloning client repo");
1665
- console.log(import_picocolors3.default.dim(" You can clone manually: cd workspace && git clone <url>"));
2741
+ console.log(import_picocolors4.default.dim(" You can clone manually: cd workspace && git clone <url>"));
1666
2742
  }
1667
2743
  }
1668
2744
  if (config.type !== "nimbus-core") {
@@ -1751,7 +2827,7 @@ async function createProject(config) {
1751
2827
  s.stop(`GitHub: ${repoName}`);
1752
2828
  } catch (error) {
1753
2829
  s.stop("Error creating GitHub repository");
1754
- console.log(import_picocolors3.default.dim(" You can create manually with: gh repo create"));
2830
+ console.log(import_picocolors4.default.dim(" You can create manually with: gh repo create"));
1755
2831
  }
1756
2832
  }
1757
2833
  }
@@ -1762,13 +2838,13 @@ async function createProject(config) {
1762
2838
  s.stop(`Railway linkado: ${config.railwayProject}`);
1763
2839
  } catch (error) {
1764
2840
  s.stop("Error linking Railway");
1765
- console.log(import_picocolors3.default.dim(" Run manually: railway link"));
2841
+ console.log(import_picocolors4.default.dim(" Run manually: railway link"));
1766
2842
  }
1767
2843
  }
1768
2844
  if (config.resendApiKey || config.stagingUrl) {
1769
2845
  s.start("Gerando arquivo .env...");
1770
2846
  try {
1771
- const envContent = generateEnvFile(config);
2847
+ const envContent = generateEnvFile2(config);
1772
2848
  await Bun.write(`${config.name}/.env`, envContent);
1773
2849
  s.stop("Arquivo .env criado");
1774
2850
  } catch (error) {
@@ -1785,7 +2861,7 @@ async function createProject(config) {
1785
2861
  }
1786
2862
  }
1787
2863
  }
1788
- function generateEnvFile(config) {
2864
+ function generateEnvFile2(config) {
1789
2865
  const lines = [
1790
2866
  "# Gerado automaticamente pelo nimbus-cli",
1791
2867
  "# Nao commitar este arquivo!",
@@ -1828,58 +2904,58 @@ function showNextSteps(config) {
1828
2904
  const isPublicTemplate = ["landing", "app", "turborepo"].includes(config.type);
1829
2905
  const needsSetup = config.type === "app";
1830
2906
  console.log();
1831
- console.log(import_picocolors3.default.bold("Next steps:"));
2907
+ console.log(import_picocolors4.default.bold("Next steps:"));
1832
2908
  console.log();
1833
- console.log(` ${import_picocolors3.default.cyan("cd")} ${config.name}`);
2909
+ console.log(` ${import_picocolors4.default.cyan("cd")} ${config.name}`);
1834
2910
  if (config.type === "nimbus-core") {
1835
2911
  console.log();
1836
- console.log(import_picocolors3.default.dim(" nimbus-core: Motor para projetos externos"));
2912
+ console.log(import_picocolors4.default.dim(" nimbus-core: Motor para projetos externos"));
1837
2913
  console.log();
1838
- console.log(import_picocolors3.default.dim(" Para usar a Lola:"));
1839
- console.log(` ${import_picocolors3.default.cyan("lola")}`);
2914
+ console.log(import_picocolors4.default.dim(" Para usar a Lola:"));
2915
+ console.log(` ${import_picocolors4.default.cyan("lola")}`);
1840
2916
  console.log();
1841
- console.log(import_picocolors3.default.yellow(" STEALTH MODE: Commits sem mencao a nimbuslab/Lola/IA"));
2917
+ console.log(import_picocolors4.default.yellow(" STEALTH MODE: Commits sem mencao a nimbuslab/Lola/IA"));
1842
2918
  console.log();
1843
2919
  if (config.github) {
1844
2920
  const repoUrl = `https://github.com/nimbuslab/${config.name}`;
1845
- console.log(import_picocolors3.default.green(` GitHub (private): ${repoUrl}`));
2921
+ console.log(import_picocolors4.default.green(` GitHub (private): ${repoUrl}`));
1846
2922
  console.log();
1847
2923
  }
1848
- console.log(import_picocolors3.default.dim(" Docs: See README.md for full instructions"));
2924
+ console.log(import_picocolors4.default.dim(" Docs: See README.md for full instructions"));
1849
2925
  console.log();
1850
2926
  return;
1851
2927
  }
1852
2928
  if (!config.install) {
1853
- console.log(` ${import_picocolors3.default.cyan("bun")} install`);
2929
+ console.log(` ${import_picocolors4.default.cyan("bun")} install`);
1854
2930
  }
1855
2931
  if (!isPublicTemplate || needsSetup) {
1856
- console.log(` ${import_picocolors3.default.cyan("bun")} setup`);
2932
+ console.log(` ${import_picocolors4.default.cyan("bun")} setup`);
1857
2933
  }
1858
- console.log(` ${import_picocolors3.default.cyan("bun")} dev`);
2934
+ console.log(` ${import_picocolors4.default.cyan("bun")} dev`);
1859
2935
  console.log();
1860
2936
  if (needsSetup && isPublicTemplate) {
1861
- console.log(import_picocolors3.default.dim(" bun setup will:"));
1862
- console.log(import_picocolors3.default.dim(" - Start PostgreSQL with Docker"));
1863
- console.log(import_picocolors3.default.dim(" - Run database migrations"));
1864
- console.log(import_picocolors3.default.dim(" - Create demo user (demo@example.com / demo1234)"));
2937
+ console.log(import_picocolors4.default.dim(" bun setup will:"));
2938
+ console.log(import_picocolors4.default.dim(" - Start PostgreSQL with Docker"));
2939
+ console.log(import_picocolors4.default.dim(" - Run database migrations"));
2940
+ console.log(import_picocolors4.default.dim(" - Create demo user (demo@example.com / demo1234)"));
1865
2941
  console.log();
1866
2942
  }
1867
2943
  if (config.git) {
1868
- console.log(import_picocolors3.default.dim(" Git: main -> staging -> develop (current branch)"));
2944
+ console.log(import_picocolors4.default.dim(" Git: main -> staging -> develop (current branch)"));
1869
2945
  if (config.github) {
1870
2946
  const repoUrl = config.githubOrg ? `https://github.com/${config.githubOrg}/${config.name}` : `https://github.com/${config.name}`;
1871
- console.log(import_picocolors3.default.green(` GitHub: ${repoUrl}`));
2947
+ console.log(import_picocolors4.default.green(` GitHub: ${repoUrl}`));
1872
2948
  }
1873
2949
  console.log();
1874
2950
  }
1875
2951
  if (isPublicTemplate) {
1876
2952
  if (config.theme !== "dark") {
1877
- console.log(import_picocolors3.default.dim(` Theme: ${config.theme}`));
2953
+ console.log(import_picocolors4.default.dim(` Theme: ${config.theme}`));
1878
2954
  }
1879
2955
  if (config.aiAssistant) {
1880
2956
  const aiConfig = AI_CONFIGS[config.aiAssistant];
1881
2957
  if (aiConfig) {
1882
- console.log(import_picocolors3.default.dim(` AI config: ${aiConfig.filename}`));
2958
+ console.log(import_picocolors4.default.dim(` AI config: ${aiConfig.filename}`));
1883
2959
  }
1884
2960
  }
1885
2961
  if (config.theme !== "dark" || config.aiAssistant) {
@@ -1887,56 +2963,56 @@ function showNextSteps(config) {
1887
2963
  }
1888
2964
  }
1889
2965
  if (config.type === "fast+") {
1890
- console.log(import_picocolors3.default.dim(" bun setup will:"));
1891
- console.log(import_picocolors3.default.dim(" - Start PostgreSQL with Docker"));
1892
- console.log(import_picocolors3.default.dim(" - Run database migrations"));
1893
- console.log(import_picocolors3.default.dim(" - Create demo user (demo@example.com / demo1234)"));
2966
+ console.log(import_picocolors4.default.dim(" bun setup will:"));
2967
+ console.log(import_picocolors4.default.dim(" - Start PostgreSQL with Docker"));
2968
+ console.log(import_picocolors4.default.dim(" - Run database migrations"));
2969
+ console.log(import_picocolors4.default.dim(" - Create demo user (demo@example.com / demo1234)"));
1894
2970
  console.log();
1895
- console.log(import_picocolors3.default.dim(" Tip: Configure DATABASE_URL and BETTER_AUTH_SECRET in .env"));
2971
+ console.log(import_picocolors4.default.dim(" Tip: Configure DATABASE_URL and BETTER_AUTH_SECRET in .env"));
1896
2972
  if (!config.railwayToken) {
1897
- console.log(import_picocolors3.default.dim(" Railway: Create a project at https://railway.app/new"));
2973
+ console.log(import_picocolors4.default.dim(" Railway: Create a project at https://railway.app/new"));
1898
2974
  }
1899
2975
  console.log();
1900
2976
  }
1901
2977
  if (!isPublicTemplate) {
1902
2978
  if (config.resendApiKey || config.stagingUrl) {
1903
- console.log(import_picocolors3.default.green(" .env configured!"));
2979
+ console.log(import_picocolors4.default.green(" .env configured!"));
1904
2980
  console.log();
1905
2981
  } else {
1906
- console.log(import_picocolors3.default.yellow(" Tip: Configure .env manually or use 'bun setup'."));
2982
+ console.log(import_picocolors4.default.yellow(" Tip: Configure .env manually or use 'bun setup'."));
1907
2983
  console.log();
1908
2984
  }
1909
2985
  }
1910
2986
  if (isPublicTemplate) {
1911
- console.log(import_picocolors3.default.dim(" Open source template (MIT) by nimbuslab"));
1912
- console.log(import_picocolors3.default.dim(` https://github.com/nimbuslab/create-next-${config.type === "turborepo" ? "turborepo" : config.type}`));
2987
+ console.log(import_picocolors4.default.dim(" Open source template (MIT) by nimbuslab"));
2988
+ console.log(import_picocolors4.default.dim(` https://github.com/nimbuslab/create-next-${config.type === "turborepo" ? "turborepo" : config.type}`));
1913
2989
  } else {
1914
- console.log(import_picocolors3.default.dim(" https://github.com/nimbuslab-templates"));
2990
+ console.log(import_picocolors4.default.dim(" https://github.com/nimbuslab-templates"));
1915
2991
  }
1916
2992
  console.log();
1917
2993
  }
1918
2994
 
1919
2995
  // src/commands/analyze.ts
1920
- var import_picocolors4 = __toESM(require_picocolors(), 1);
2996
+ var import_picocolors5 = __toESM(require_picocolors(), 1);
1921
2997
  import { existsSync, readFileSync } from "fs";
1922
- import { join as join2 } from "path";
2998
+ import { join as join3 } from "path";
1923
2999
  function detectPackageManager(dir) {
1924
- if (existsSync(join2(dir, "bun.lockb")))
3000
+ if (existsSync(join3(dir, "bun.lockb")))
1925
3001
  return "bun";
1926
- if (existsSync(join2(dir, "pnpm-lock.yaml")))
3002
+ if (existsSync(join3(dir, "pnpm-lock.yaml")))
1927
3003
  return "pnpm";
1928
- if (existsSync(join2(dir, "yarn.lock")))
3004
+ if (existsSync(join3(dir, "yarn.lock")))
1929
3005
  return "yarn";
1930
- if (existsSync(join2(dir, "package-lock.json")))
3006
+ if (existsSync(join3(dir, "package-lock.json")))
1931
3007
  return "npm";
1932
3008
  return "unknown";
1933
3009
  }
1934
3010
  function detectMonorepo(dir, pkg) {
1935
- if (existsSync(join2(dir, "turbo.json")))
3011
+ if (existsSync(join3(dir, "turbo.json")))
1936
3012
  return "turborepo";
1937
- if (existsSync(join2(dir, "nx.json")))
3013
+ if (existsSync(join3(dir, "nx.json")))
1938
3014
  return "nx";
1939
- if (existsSync(join2(dir, "lerna.json")))
3015
+ if (existsSync(join3(dir, "lerna.json")))
1940
3016
  return "lerna";
1941
3017
  if (pkg.workspaces)
1942
3018
  return "workspaces";
@@ -2041,14 +3117,14 @@ function generateRecommendations(result) {
2041
3117
  }
2042
3118
  async function analyze(args) {
2043
3119
  const targetDir = args[0] || ".";
2044
- const absoluteDir = targetDir.startsWith("/") ? targetDir : join2(process.cwd(), targetDir);
3120
+ const absoluteDir = targetDir.startsWith("/") ? targetDir : join3(process.cwd(), targetDir);
2045
3121
  console.log();
2046
- console.log(import_picocolors4.default.cyan(" Analisando projeto..."));
3122
+ console.log(import_picocolors5.default.cyan(" Analisando projeto..."));
2047
3123
  console.log();
2048
- const pkgPath = join2(absoluteDir, "package.json");
3124
+ const pkgPath = join3(absoluteDir, "package.json");
2049
3125
  if (!existsSync(pkgPath)) {
2050
- console.log(import_picocolors4.default.red(" Erro: package.json nao encontrado"));
2051
- console.log(import_picocolors4.default.dim(` Diretorio: ${absoluteDir}`));
3126
+ console.log(import_picocolors5.default.red(" Erro: package.json nao encontrado"));
3127
+ console.log(import_picocolors5.default.dim(` Diretorio: ${absoluteDir}`));
2052
3128
  process.exit(1);
2053
3129
  }
2054
3130
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
@@ -2065,42 +3141,42 @@ async function analyze(args) {
2065
3141
  monorepo: detectMonorepo(absoluteDir, pkg),
2066
3142
  auth: detectAuth(deps),
2067
3143
  database: detectDatabase(deps),
2068
- typescript: existsSync(join2(absoluteDir, "tsconfig.json")),
3144
+ typescript: existsSync(join3(absoluteDir, "tsconfig.json")),
2069
3145
  dependencies: deps,
2070
3146
  devDependencies: devDeps,
2071
3147
  recommendations: []
2072
3148
  };
2073
3149
  result.recommendations = generateRecommendations(result);
2074
- console.log(import_picocolors4.default.bold(" Projeto: ") + import_picocolors4.default.cyan(result.name) + import_picocolors4.default.dim(` v${result.version}`));
3150
+ console.log(import_picocolors5.default.bold(" Projeto: ") + import_picocolors5.default.cyan(result.name) + import_picocolors5.default.dim(` v${result.version}`));
2075
3151
  console.log();
2076
- console.log(import_picocolors4.default.bold(" Stack Detectada:"));
2077
- console.log(` Framework: ${result.framework ? import_picocolors4.default.green(result.framework + "@" + result.frameworkVersion) : import_picocolors4.default.dim("nenhum")}`);
2078
- console.log(` Styling: ${result.styling.map((s) => import_picocolors4.default.green(s)).join(", ")}`);
2079
- console.log(` Package Manager: ${result.packageManager === "bun" ? import_picocolors4.default.green(result.packageManager) : import_picocolors4.default.yellow(result.packageManager)}`);
2080
- console.log(` TypeScript: ${result.typescript ? import_picocolors4.default.green("sim") : import_picocolors4.default.dim("nao")}`);
2081
- console.log(` Monorepo: ${result.monorepo ? import_picocolors4.default.green(result.monorepo) : import_picocolors4.default.dim("nao")}`);
2082
- console.log(` Auth: ${result.auth ? import_picocolors4.default.green(result.auth) : import_picocolors4.default.dim("nenhum")}`);
2083
- console.log(` Database: ${result.database ? import_picocolors4.default.green(result.database) : import_picocolors4.default.dim("nenhum")}`);
3152
+ console.log(import_picocolors5.default.bold(" Stack Detectada:"));
3153
+ console.log(` Framework: ${result.framework ? import_picocolors5.default.green(result.framework + "@" + result.frameworkVersion) : import_picocolors5.default.dim("nenhum")}`);
3154
+ console.log(` Styling: ${result.styling.map((s) => import_picocolors5.default.green(s)).join(", ")}`);
3155
+ console.log(` Package Manager: ${result.packageManager === "bun" ? import_picocolors5.default.green(result.packageManager) : import_picocolors5.default.yellow(result.packageManager)}`);
3156
+ console.log(` TypeScript: ${result.typescript ? import_picocolors5.default.green("sim") : import_picocolors5.default.dim("nao")}`);
3157
+ console.log(` Monorepo: ${result.monorepo ? import_picocolors5.default.green(result.monorepo) : import_picocolors5.default.dim("nao")}`);
3158
+ console.log(` Auth: ${result.auth ? import_picocolors5.default.green(result.auth) : import_picocolors5.default.dim("nenhum")}`);
3159
+ console.log(` Database: ${result.database ? import_picocolors5.default.green(result.database) : import_picocolors5.default.dim("nenhum")}`);
2084
3160
  console.log();
2085
3161
  if (result.recommendations.length > 0) {
2086
- console.log(import_picocolors4.default.bold(" Recomendacoes:"));
3162
+ console.log(import_picocolors5.default.bold(" Recomendacoes:"));
2087
3163
  result.recommendations.forEach((rec, i) => {
2088
- console.log(import_picocolors4.default.yellow(` ${i + 1}. ${rec}`));
3164
+ console.log(import_picocolors5.default.yellow(` ${i + 1}. ${rec}`));
2089
3165
  });
2090
3166
  console.log();
2091
3167
  } else {
2092
- console.log(import_picocolors4.default.green(" Projeto ja esta na stack recomendada!"));
3168
+ console.log(import_picocolors5.default.green(" Projeto ja esta na stack recomendada!"));
2093
3169
  console.log();
2094
3170
  }
2095
3171
  if (args.includes("--json")) {
2096
- console.log(import_picocolors4.default.dim(" JSON:"));
3172
+ console.log(import_picocolors5.default.dim(" JSON:"));
2097
3173
  console.log(JSON.stringify(result, null, 2));
2098
3174
  }
2099
3175
  return result;
2100
3176
  }
2101
3177
 
2102
3178
  // src/commands/upgrade.ts
2103
- var import_picocolors5 = __toESM(require_picocolors(), 1);
3179
+ var import_picocolors6 = __toESM(require_picocolors(), 1);
2104
3180
  var UPGRADE_PLANS = {
2105
3181
  next: (current) => {
2106
3182
  const major = parseInt(current.replace(/[^0-9]/g, "").slice(0, 2));
@@ -2217,10 +3293,10 @@ async function upgrade(args) {
2217
3293
  const target = args.find((a) => !a.startsWith("-"));
2218
3294
  console.log();
2219
3295
  if (showPlan || !target) {
2220
- console.log(import_picocolors5.default.cyan(" Analisando projeto para plano de upgrade..."));
3296
+ console.log(import_picocolors6.default.cyan(" Analisando projeto para plano de upgrade..."));
2221
3297
  console.log();
2222
3298
  const analysis = await analyze([".", "--quiet"]);
2223
- console.log(import_picocolors5.default.bold(" Upgrades Disponiveis:"));
3299
+ console.log(import_picocolors6.default.bold(" Upgrades Disponiveis:"));
2224
3300
  console.log();
2225
3301
  let hasUpgrades = false;
2226
3302
  if (analysis.frameworkVersion && analysis.framework === "nextjs") {
@@ -2275,44 +3351,44 @@ async function upgrade(args) {
2275
3351
  }
2276
3352
  }
2277
3353
  if (!hasUpgrades) {
2278
- console.log(import_picocolors5.default.green(" Projeto ja esta atualizado!"));
3354
+ console.log(import_picocolors6.default.green(" Projeto ja esta atualizado!"));
2279
3355
  }
2280
3356
  console.log();
2281
- console.log(import_picocolors5.default.dim(" Para executar um upgrade especifico:"));
2282
- console.log(import_picocolors5.default.dim(" nimbus upgrade next"));
2283
- console.log(import_picocolors5.default.dim(" nimbus upgrade tailwind"));
2284
- console.log(import_picocolors5.default.dim(" nimbus upgrade bun"));
3357
+ console.log(import_picocolors6.default.dim(" Para executar um upgrade especifico:"));
3358
+ console.log(import_picocolors6.default.dim(" nimbus upgrade next"));
3359
+ console.log(import_picocolors6.default.dim(" nimbus upgrade tailwind"));
3360
+ console.log(import_picocolors6.default.dim(" nimbus upgrade bun"));
2285
3361
  console.log();
2286
3362
  return;
2287
3363
  }
2288
- console.log(import_picocolors5.default.yellow(` Upgrade ${target} ainda nao implementado.`));
2289
- console.log(import_picocolors5.default.dim(" Por enquanto, siga os passos do --plan manualmente."));
3364
+ console.log(import_picocolors6.default.yellow(` Upgrade ${target} ainda nao implementado.`));
3365
+ console.log(import_picocolors6.default.dim(" Por enquanto, siga os passos do --plan manualmente."));
2290
3366
  console.log();
2291
3367
  }
2292
3368
  function printUpgradePlan(name, plan) {
2293
3369
  const complexityColor = {
2294
- low: import_picocolors5.default.green,
2295
- medium: import_picocolors5.default.yellow,
2296
- high: import_picocolors5.default.red
3370
+ low: import_picocolors6.default.green,
3371
+ medium: import_picocolors6.default.yellow,
3372
+ high: import_picocolors6.default.red
2297
3373
  };
2298
- console.log(` ${import_picocolors5.default.bold(name)}`);
2299
- console.log(` ${import_picocolors5.default.dim("Atual:")} ${plan.current} ${import_picocolors5.default.dim("->")} ${import_picocolors5.default.cyan(plan.target)}`);
2300
- console.log(` ${import_picocolors5.default.dim("Complexidade:")} ${complexityColor[plan.complexity](plan.complexity)}`);
3374
+ console.log(` ${import_picocolors6.default.bold(name)}`);
3375
+ console.log(` ${import_picocolors6.default.dim("Atual:")} ${plan.current} ${import_picocolors6.default.dim("->")} ${import_picocolors6.default.cyan(plan.target)}`);
3376
+ console.log(` ${import_picocolors6.default.dim("Complexidade:")} ${complexityColor[plan.complexity](plan.complexity)}`);
2301
3377
  console.log();
2302
- console.log(` ${import_picocolors5.default.dim("Breaking Changes:")}`);
3378
+ console.log(` ${import_picocolors6.default.dim("Breaking Changes:")}`);
2303
3379
  plan.breakingChanges.forEach((bc) => {
2304
- console.log(` ${import_picocolors5.default.yellow("!")} ${bc}`);
3380
+ console.log(` ${import_picocolors6.default.yellow("!")} ${bc}`);
2305
3381
  });
2306
3382
  console.log();
2307
- console.log(` ${import_picocolors5.default.dim("Passos:")}`);
3383
+ console.log(` ${import_picocolors6.default.dim("Passos:")}`);
2308
3384
  plan.steps.forEach((step, i) => {
2309
- console.log(` ${import_picocolors5.default.dim(`${i + 1}.`)} ${step}`);
3385
+ console.log(` ${import_picocolors6.default.dim(`${i + 1}.`)} ${step}`);
2310
3386
  });
2311
3387
  console.log();
2312
3388
  }
2313
3389
 
2314
3390
  // src/commands/update.ts
2315
- var import_picocolors6 = __toESM(require_picocolors(), 1);
3391
+ var import_picocolors7 = __toESM(require_picocolors(), 1);
2316
3392
  import { execSync, spawnSync } from "child_process";
2317
3393
  var PACKAGE_NAME = "@nimbuslab/cli";
2318
3394
  function hasBunInstall() {
@@ -2448,7 +3524,7 @@ async function update(args) {
2448
3524
  const filteredArgs = args.filter((a) => a !== "--force" && a !== "-f");
2449
3525
  const flag = filteredArgs[0];
2450
3526
  if (flag === "--list" || flag === "-l") {
2451
- Ie(import_picocolors6.default.cyan("Versoes disponiveis"));
3527
+ Ie(import_picocolors7.default.cyan("Versoes disponiveis"));
2452
3528
  const spinner2 = Y2();
2453
3529
  spinner2.start("Buscando versoes...");
2454
3530
  const versions = await getAvailableVersions();
@@ -2460,29 +3536,29 @@ async function update(args) {
2460
3536
  const current = getCurrentVersion();
2461
3537
  const pm2 = detectPackageManager2();
2462
3538
  console.log();
2463
- console.log(import_picocolors6.default.bold("Ultimas 10 versoes:"));
3539
+ console.log(import_picocolors7.default.bold("Ultimas 10 versoes:"));
2464
3540
  versions.slice(0, 10).forEach((v2, i) => {
2465
3541
  const isCurrent = v2 === current;
2466
- const prefix = isCurrent ? import_picocolors6.default.green("-> ") : " ";
2467
- const suffix = isCurrent ? import_picocolors6.default.dim(" (instalada)") : "";
2468
- const isLatest = i === 0 ? import_picocolors6.default.yellow(" (latest)") : "";
3542
+ const prefix = isCurrent ? import_picocolors7.default.green("-> ") : " ";
3543
+ const suffix = isCurrent ? import_picocolors7.default.dim(" (instalada)") : "";
3544
+ const isLatest = i === 0 ? import_picocolors7.default.yellow(" (latest)") : "";
2469
3545
  console.log(`${prefix}${v2}${suffix}${isLatest}`);
2470
3546
  });
2471
3547
  console.log();
2472
- console.log(import_picocolors6.default.dim(`Total: ${versions.length} versoes`));
2473
- console.log(import_picocolors6.default.dim(`Package manager detectado: ${pm2 === "unknown" ? "nenhum" : pm2}`));
2474
- console.log(import_picocolors6.default.dim(`Instalar versao especifica: nimbus update <versao>`));
2475
- console.log(import_picocolors6.default.dim(`Forcar reinstalacao: nimbus update --force`));
3548
+ console.log(import_picocolors7.default.dim(`Total: ${versions.length} versoes`));
3549
+ console.log(import_picocolors7.default.dim(`Package manager detectado: ${pm2 === "unknown" ? "nenhum" : pm2}`));
3550
+ console.log(import_picocolors7.default.dim(`Instalar versao especifica: nimbus update <versao>`));
3551
+ console.log(import_picocolors7.default.dim(`Forcar reinstalacao: nimbus update --force`));
2476
3552
  return;
2477
3553
  }
2478
3554
  const targetVersion = flag || "latest";
2479
3555
  const isSpecificVersion = flag && flag !== "latest" && !flag.startsWith("-");
2480
- Ie(import_picocolors6.default.cyan(`Atualizando ${PACKAGE_NAME}`));
3556
+ Ie(import_picocolors7.default.cyan(`Atualizando ${PACKAGE_NAME}`));
2481
3557
  const spinner = Y2();
2482
3558
  spinner.start("Verificando instalacoes...");
2483
3559
  const cleanup = cleanupDuplicateInstalls();
2484
3560
  if (cleanup.cleaned) {
2485
- spinner.stop(import_picocolors6.default.yellow(cleanup.message));
3561
+ spinner.stop(import_picocolors7.default.yellow(cleanup.message));
2486
3562
  } else {
2487
3563
  spinner.stop("OK");
2488
3564
  }
@@ -2500,7 +3576,7 @@ async function update(args) {
2500
3576
  spinner.stop(`Ultima versao: ${latestVersion || "desconhecida"}`);
2501
3577
  if (!forceFlag && latestVersion && latestVersion === currentVersion) {
2502
3578
  M2.success("Voce ja esta na ultima versao!");
2503
- console.log(import_picocolors6.default.dim(" Use --force para reinstalar"));
3579
+ console.log(import_picocolors7.default.dim(" Use --force para reinstalar"));
2504
3580
  return;
2505
3581
  }
2506
3582
  }
@@ -2538,37 +3614,37 @@ async function update(args) {
2538
3614
  const isWindows = process.platform === "win32";
2539
3615
  if (isWindows) {
2540
3616
  console.log();
2541
- console.log(import_picocolors6.default.yellow(" Reinicie o terminal para aplicar a atualizacao."));
3617
+ console.log(import_picocolors7.default.yellow(" Reinicie o terminal para aplicar a atualizacao."));
2542
3618
  } else if (isUsingFnm()) {
2543
3619
  console.log();
2544
- console.log(import_picocolors6.default.yellow(" fnm detectado - execute para aplicar:"));
2545
- console.log(import_picocolors6.default.cyan(" hash -r"));
2546
- console.log(import_picocolors6.default.dim(" Ou abra um novo terminal."));
3620
+ console.log(import_picocolors7.default.yellow(" fnm detectado - execute para aplicar:"));
3621
+ console.log(import_picocolors7.default.cyan(" hash -r"));
3622
+ console.log(import_picocolors7.default.dim(" Ou abra um novo terminal."));
2547
3623
  }
2548
- Se(import_picocolors6.default.green("Pronto!"));
3624
+ Se(import_picocolors7.default.green("Pronto!"));
2549
3625
  } catch (error) {
2550
3626
  spinner.stop("Erro na atualizacao");
2551
3627
  const err = error;
2552
3628
  M2.error("Falha ao atualizar");
2553
3629
  if (err.stderr) {
2554
- console.log(import_picocolors6.default.dim(err.stderr));
3630
+ console.log(import_picocolors7.default.dim(err.stderr));
2555
3631
  }
2556
3632
  console.log();
2557
- console.log(import_picocolors6.default.yellow("Tente manualmente:"));
3633
+ console.log(import_picocolors7.default.yellow("Tente manualmente:"));
2558
3634
  if (pm === "bun") {
2559
- console.log(import_picocolors6.default.cyan(` bun add -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
3635
+ console.log(import_picocolors7.default.cyan(` bun add -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
2560
3636
  } else {
2561
- console.log(import_picocolors6.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
3637
+ console.log(import_picocolors7.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
2562
3638
  }
2563
3639
  }
2564
3640
  }
2565
3641
 
2566
3642
  // src/commands/setup-node.ts
2567
- var import_picocolors7 = __toESM(require_picocolors(), 1);
3643
+ var import_picocolors8 = __toESM(require_picocolors(), 1);
2568
3644
  import { execSync as execSync2, spawnSync as spawnSync2 } from "child_process";
2569
3645
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
2570
3646
  import { homedir } from "os";
2571
- import { join as join3 } from "path";
3647
+ import { join as join4 } from "path";
2572
3648
  var HOME = homedir();
2573
3649
  var IS_WINDOWS = process.platform === "win32";
2574
3650
  var CHECK_CMD = IS_WINDOWS ? "where" : "which";
@@ -2576,23 +3652,23 @@ function detectFnm() {
2576
3652
  const result = { name: "fnm", installed: false };
2577
3653
  const check = spawnSync2(CHECK_CMD, ["fnm"], { encoding: "utf-8", shell: true });
2578
3654
  const fnmLocations = IS_WINDOWS ? [
2579
- join3(HOME, "scoop", "shims", "fnm.exe"),
2580
- join3(HOME, "scoop", "apps", "fnm", "current", "fnm.exe"),
3655
+ join4(HOME, "scoop", "shims", "fnm.exe"),
3656
+ join4(HOME, "scoop", "apps", "fnm", "current", "fnm.exe"),
2581
3657
  "C:\\ProgramData\\chocolatey\\bin\\fnm.exe",
2582
- join3(HOME, ".cargo", "bin", "fnm.exe"),
2583
- join3(HOME, ".fnm", "fnm.exe"),
2584
- join3(HOME, "AppData", "Local", "fnm", "fnm.exe"),
2585
- join3(HOME, "AppData", "Roaming", "fnm", "fnm.exe"),
2586
- join3(HOME, "AppData", "Local", "Microsoft", "fnm", "fnm.exe"),
2587
- join3(HOME, "AppData", "Roaming", "fnm"),
2588
- join3(HOME, "AppData", "Local", "fnm_multishells")
3658
+ join4(HOME, ".cargo", "bin", "fnm.exe"),
3659
+ join4(HOME, ".fnm", "fnm.exe"),
3660
+ join4(HOME, "AppData", "Local", "fnm", "fnm.exe"),
3661
+ join4(HOME, "AppData", "Roaming", "fnm", "fnm.exe"),
3662
+ join4(HOME, "AppData", "Local", "Microsoft", "fnm", "fnm.exe"),
3663
+ join4(HOME, "AppData", "Roaming", "fnm"),
3664
+ join4(HOME, "AppData", "Local", "fnm_multishells")
2589
3665
  ] : [
2590
- join3(HOME, ".local", "share", "fnm", "fnm"),
2591
- join3(HOME, ".fnm", "fnm"),
2592
- join3(HOME, ".local", "bin", "fnm"),
3666
+ join4(HOME, ".local", "share", "fnm", "fnm"),
3667
+ join4(HOME, ".fnm", "fnm"),
3668
+ join4(HOME, ".local", "bin", "fnm"),
2593
3669
  "/opt/homebrew/bin/fnm",
2594
3670
  "/usr/local/bin/fnm",
2595
- join3(HOME, ".cargo", "bin", "fnm")
3671
+ join4(HOME, ".cargo", "bin", "fnm")
2596
3672
  ];
2597
3673
  let fnmPath = null;
2598
3674
  if (check.status === 0) {
@@ -2612,7 +3688,7 @@ function detectFnm() {
2612
3688
  }
2613
3689
  }
2614
3690
  if (!fnmPath && IS_WINDOWS) {
2615
- const fnmMultishells = join3(HOME, "AppData", "Local", "fnm_multishells");
3691
+ const fnmMultishells = join4(HOME, "AppData", "Local", "fnm_multishells");
2616
3692
  if (existsSync2(fnmMultishells)) {
2617
3693
  fnmPath = fnmMultishells;
2618
3694
  }
@@ -2628,9 +3704,9 @@ function detectFnm() {
2628
3704
  } catch {}
2629
3705
  result.configFiles = [];
2630
3706
  if (IS_WINDOWS) {
2631
- const ps5Profile = join3(HOME, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
2632
- const ps7Profile = join3(HOME, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
2633
- const psProfile = join3(HOME, "Documents", "PowerShell", "profile.ps1");
3707
+ const ps5Profile = join4(HOME, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
3708
+ const ps7Profile = join4(HOME, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
3709
+ const psProfile = join4(HOME, "Documents", "PowerShell", "profile.ps1");
2634
3710
  if (existsSync2(ps5Profile))
2635
3711
  result.configFiles.push(ps5Profile);
2636
3712
  if (existsSync2(ps7Profile))
@@ -2639,12 +3715,12 @@ function detectFnm() {
2639
3715
  result.configFiles.push(psProfile);
2640
3716
  } else {
2641
3717
  const configs = [
2642
- join3(HOME, ".bashrc"),
2643
- join3(HOME, ".bash_profile"),
2644
- join3(HOME, ".profile"),
2645
- join3(HOME, ".zshrc"),
2646
- join3(HOME, ".zprofile"),
2647
- join3(HOME, ".config", "fish", "config.fish")
3718
+ join4(HOME, ".bashrc"),
3719
+ join4(HOME, ".bash_profile"),
3720
+ join4(HOME, ".profile"),
3721
+ join4(HOME, ".zshrc"),
3722
+ join4(HOME, ".zprofile"),
3723
+ join4(HOME, ".config", "fish", "config.fish")
2648
3724
  ];
2649
3725
  for (const cfg of configs) {
2650
3726
  if (existsSync2(cfg))
@@ -2658,10 +3734,10 @@ function detectNvm() {
2658
3734
  if (IS_WINDOWS) {
2659
3735
  const check = spawnSync2(CHECK_CMD, ["nvm"], { encoding: "utf-8", shell: true });
2660
3736
  const nvmWinLocations = [
2661
- join3(HOME, "AppData", "Roaming", "nvm", "nvm.exe"),
3737
+ join4(HOME, "AppData", "Roaming", "nvm", "nvm.exe"),
2662
3738
  "C:\\Program Files\\nvm\\nvm.exe",
2663
3739
  "C:\\ProgramData\\nvm\\nvm.exe",
2664
- join3(HOME, "nvm", "nvm.exe")
3740
+ join4(HOME, "nvm", "nvm.exe")
2665
3741
  ];
2666
3742
  let nvmPath = null;
2667
3743
  if (check.status === 0) {
@@ -2685,28 +3761,28 @@ function detectNvm() {
2685
3761
  } catch {}
2686
3762
  result.configFiles = [];
2687
3763
  const configs = [
2688
- join3(HOME, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1"),
2689
- join3(HOME, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1"),
2690
- join3(HOME, "Documents", "PowerShell", "profile.ps1")
3764
+ join4(HOME, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1"),
3765
+ join4(HOME, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1"),
3766
+ join4(HOME, "Documents", "PowerShell", "profile.ps1")
2691
3767
  ];
2692
3768
  for (const cfg of configs) {
2693
3769
  if (existsSync2(cfg))
2694
3770
  result.configFiles.push(cfg);
2695
3771
  }
2696
3772
  } else {
2697
- const nvmDir = process.env.NVM_DIR || join3(HOME, ".nvm");
3773
+ const nvmDir = process.env.NVM_DIR || join4(HOME, ".nvm");
2698
3774
  if (!existsSync2(nvmDir))
2699
3775
  return result;
2700
3776
  result.installed = true;
2701
3777
  result.path = nvmDir;
2702
3778
  result.configFiles = [];
2703
3779
  const configs = [
2704
- join3(HOME, ".bashrc"),
2705
- join3(HOME, ".bash_profile"),
2706
- join3(HOME, ".profile"),
2707
- join3(HOME, ".zshrc"),
2708
- join3(HOME, ".zprofile"),
2709
- join3(HOME, ".config", "fish", "config.fish")
3780
+ join4(HOME, ".bashrc"),
3781
+ join4(HOME, ".bash_profile"),
3782
+ join4(HOME, ".profile"),
3783
+ join4(HOME, ".zshrc"),
3784
+ join4(HOME, ".zprofile"),
3785
+ join4(HOME, ".config", "fish", "config.fish")
2710
3786
  ];
2711
3787
  for (const cfg of configs) {
2712
3788
  if (existsSync2(cfg))
@@ -2833,7 +3909,7 @@ async function removeFnm(fnm) {
2833
3909
  const scoopCheck = spawnSync2("scoop", ["list"], { encoding: "utf-8", shell: true });
2834
3910
  if (scoopCheck.stdout?.includes("fnm")) {
2835
3911
  execSync2("scoop uninstall fnm", { stdio: "pipe" });
2836
- console.log(import_picocolors7.default.dim(" Removido via Scoop"));
3912
+ console.log(import_picocolors8.default.dim(" Removido via Scoop"));
2837
3913
  removed = true;
2838
3914
  }
2839
3915
  } catch {}
@@ -2842,7 +3918,7 @@ async function removeFnm(fnm) {
2842
3918
  const chocoCheck = spawnSync2("choco", ["list", "--local-only"], { encoding: "utf-8", shell: true });
2843
3919
  if (chocoCheck.stdout?.includes("fnm")) {
2844
3920
  execSync2("choco uninstall fnm -y", { stdio: "pipe" });
2845
- console.log(import_picocolors7.default.dim(" Removido via Chocolatey"));
3921
+ console.log(import_picocolors8.default.dim(" Removido via Chocolatey"));
2846
3922
  removed = true;
2847
3923
  }
2848
3924
  } catch {}
@@ -2852,28 +3928,28 @@ async function removeFnm(fnm) {
2852
3928
  const wingetCheck = spawnSync2("winget", ["list", "--name", "fnm"], { encoding: "utf-8", shell: true });
2853
3929
  if (wingetCheck.stdout?.includes("fnm")) {
2854
3930
  execSync2("winget uninstall fnm --silent", { stdio: "pipe" });
2855
- console.log(import_picocolors7.default.dim(" Removido via winget"));
3931
+ console.log(import_picocolors8.default.dim(" Removido via winget"));
2856
3932
  removed = true;
2857
3933
  }
2858
3934
  } catch {}
2859
3935
  }
2860
3936
  const winFnmDirs = [
2861
- join3(HOME, ".fnm"),
2862
- join3(HOME, "AppData", "Local", "fnm"),
2863
- join3(HOME, "AppData", "Roaming", "fnm"),
2864
- join3(HOME, "AppData", "Local", "fnm_multishells"),
2865
- join3(HOME, "AppData", "Local", "Microsoft", "fnm")
3937
+ join4(HOME, ".fnm"),
3938
+ join4(HOME, "AppData", "Local", "fnm"),
3939
+ join4(HOME, "AppData", "Roaming", "fnm"),
3940
+ join4(HOME, "AppData", "Local", "fnm_multishells"),
3941
+ join4(HOME, "AppData", "Local", "Microsoft", "fnm")
2866
3942
  ];
2867
3943
  for (const dir of winFnmDirs) {
2868
3944
  if (existsSync2(dir)) {
2869
3945
  try {
2870
3946
  execSync2(`rmdir /s /q "${dir}"`, { stdio: "pipe", shell: "cmd.exe" });
2871
- console.log(import_picocolors7.default.dim(` Removido ${dir}`));
3947
+ console.log(import_picocolors8.default.dim(` Removido ${dir}`));
2872
3948
  removed = true;
2873
3949
  } catch {
2874
3950
  try {
2875
3951
  execSync2(`powershell -Command "Remove-Item -Path '${dir}' -Recurse -Force"`, { stdio: "pipe" });
2876
- console.log(import_picocolors7.default.dim(` Removido ${dir}`));
3952
+ console.log(import_picocolors8.default.dim(` Removido ${dir}`));
2877
3953
  removed = true;
2878
3954
  } catch {}
2879
3955
  }
@@ -2882,16 +3958,16 @@ async function removeFnm(fnm) {
2882
3958
  try {
2883
3959
  execSync2(`powershell -Command "[Environment]::SetEnvironmentVariable('FNM_DIR', $null, 'User')"`, { stdio: "pipe" });
2884
3960
  execSync2(`powershell -Command "[Environment]::SetEnvironmentVariable('FNM_MULTISHELL_PATH', $null, 'User')"`, { stdio: "pipe" });
2885
- console.log(import_picocolors7.default.dim(" Variaveis de ambiente FNM removidas"));
3961
+ console.log(import_picocolors8.default.dim(" Variaveis de ambiente FNM removidas"));
2886
3962
  removed = true;
2887
3963
  } catch {}
2888
3964
  for (const configFile of fnm.configFiles || []) {
2889
3965
  if (removeFnmFromConfig(configFile)) {
2890
- console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
3966
+ console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
2891
3967
  removed = true;
2892
3968
  }
2893
3969
  }
2894
- spinner.stop(removed ? "fnm removido!" : import_picocolors7.default.yellow("fnm nao encontrado"));
3970
+ spinner.stop(removed ? "fnm removido!" : import_picocolors8.default.yellow("fnm nao encontrado"));
2895
3971
  return removed;
2896
3972
  } else {
2897
3973
  spinner.start("Removendo fnm...");
@@ -2900,35 +3976,35 @@ async function removeFnm(fnm) {
2900
3976
  const brewCheck = spawnSync2("brew", ["list", "fnm"], { encoding: "utf-8", shell: true });
2901
3977
  if (brewCheck.status === 0) {
2902
3978
  execSync2("brew uninstall fnm", { stdio: "pipe" });
2903
- console.log(import_picocolors7.default.dim(" Removido via Homebrew"));
3979
+ console.log(import_picocolors8.default.dim(" Removido via Homebrew"));
2904
3980
  removed = true;
2905
3981
  }
2906
3982
  } catch {}
2907
3983
  for (const configFile of fnm.configFiles || []) {
2908
3984
  if (removeFnmFromConfig(configFile)) {
2909
- console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
3985
+ console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
2910
3986
  removed = true;
2911
3987
  }
2912
3988
  }
2913
3989
  const fnmDirs = [
2914
- join3(HOME, ".fnm"),
2915
- join3(HOME, ".local", "share", "fnm")
3990
+ join4(HOME, ".fnm"),
3991
+ join4(HOME, ".local", "share", "fnm")
2916
3992
  ];
2917
3993
  for (const fnmDir of fnmDirs) {
2918
3994
  if (existsSync2(fnmDir)) {
2919
3995
  execSync2(`rm -rf "${fnmDir}"`, { stdio: "pipe" });
2920
- console.log(import_picocolors7.default.dim(` Removido ${fnmDir}`));
3996
+ console.log(import_picocolors8.default.dim(` Removido ${fnmDir}`));
2921
3997
  removed = true;
2922
3998
  }
2923
3999
  }
2924
4000
  const fnmBins = [
2925
- join3(HOME, ".local", "bin", "fnm"),
2926
- join3(HOME, ".cargo", "bin", "fnm")
4001
+ join4(HOME, ".local", "bin", "fnm"),
4002
+ join4(HOME, ".cargo", "bin", "fnm")
2927
4003
  ];
2928
4004
  for (const bin of fnmBins) {
2929
4005
  if (existsSync2(bin)) {
2930
4006
  execSync2(`rm -f "${bin}"`, { stdio: "pipe" });
2931
- console.log(import_picocolors7.default.dim(` Removido ${bin}`));
4007
+ console.log(import_picocolors8.default.dim(` Removido ${bin}`));
2932
4008
  removed = true;
2933
4009
  }
2934
4010
  }
@@ -2936,7 +4012,7 @@ async function removeFnm(fnm) {
2936
4012
  return removed;
2937
4013
  }
2938
4014
  } catch (error) {
2939
- spinner.stop(import_picocolors7.default.red("Erro ao remover fnm"));
4015
+ spinner.stop(import_picocolors8.default.red("Erro ao remover fnm"));
2940
4016
  return false;
2941
4017
  }
2942
4018
  }
@@ -2950,59 +4026,59 @@ async function removeNvm(nvm) {
2950
4026
  const wingetCheck = spawnSync2("winget", ["list", "--name", "nvm"], { encoding: "utf-8", shell: true });
2951
4027
  if (wingetCheck.stdout?.toLowerCase().includes("nvm")) {
2952
4028
  execSync2("winget uninstall nvm --silent", { stdio: "pipe" });
2953
- console.log(import_picocolors7.default.dim(" Removido via winget"));
4029
+ console.log(import_picocolors8.default.dim(" Removido via winget"));
2954
4030
  removed = true;
2955
4031
  }
2956
4032
  } catch {}
2957
4033
  const nvmWinDirs = [
2958
- join3(HOME, "AppData", "Roaming", "nvm"),
2959
- join3("C:", "Program Files", "nvm"),
2960
- join3("C:", "ProgramData", "nvm")
4034
+ join4(HOME, "AppData", "Roaming", "nvm"),
4035
+ join4("C:", "Program Files", "nvm"),
4036
+ join4("C:", "ProgramData", "nvm")
2961
4037
  ];
2962
4038
  for (const dir of nvmWinDirs) {
2963
4039
  if (existsSync2(dir)) {
2964
4040
  try {
2965
4041
  execSync2(`rmdir /s /q "${dir}"`, { stdio: "pipe", shell: "cmd.exe" });
2966
- console.log(import_picocolors7.default.dim(` Removido ${dir}`));
4042
+ console.log(import_picocolors8.default.dim(` Removido ${dir}`));
2967
4043
  removed = true;
2968
4044
  } catch {}
2969
4045
  }
2970
4046
  }
2971
4047
  for (const configFile of nvm.configFiles || []) {
2972
4048
  if (removeNvmFromConfig(configFile)) {
2973
- console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
4049
+ console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
2974
4050
  removed = true;
2975
4051
  }
2976
4052
  }
2977
4053
  if (!removed) {
2978
- console.log(import_picocolors7.default.yellow(`
4054
+ console.log(import_picocolors8.default.yellow(`
2979
4055
  nvm-windows pode precisar de remocao manual:`));
2980
- console.log(import_picocolors7.default.dim(" 1. Abra 'Adicionar ou remover programas'"));
2981
- console.log(import_picocolors7.default.dim(" 2. Procure por 'NVM for Windows'"));
2982
- console.log(import_picocolors7.default.dim(" 3. Clique em Desinstalar"));
4056
+ console.log(import_picocolors8.default.dim(" 1. Abra 'Adicionar ou remover programas'"));
4057
+ console.log(import_picocolors8.default.dim(" 2. Procure por 'NVM for Windows'"));
4058
+ console.log(import_picocolors8.default.dim(" 3. Clique em Desinstalar"));
2983
4059
  }
2984
- spinner.stop(removed ? "nvm removido!" : import_picocolors7.default.yellow("Verifique manualmente"));
4060
+ spinner.stop(removed ? "nvm removido!" : import_picocolors8.default.yellow("Verifique manualmente"));
2985
4061
  return removed;
2986
4062
  } else {
2987
4063
  spinner.start("Removendo nvm...");
2988
4064
  let removed = false;
2989
4065
  for (const configFile of nvm.configFiles || []) {
2990
4066
  if (removeNvmFromConfig(configFile)) {
2991
- console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
4067
+ console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
2992
4068
  removed = true;
2993
4069
  }
2994
4070
  }
2995
- const nvmDir = process.env.NVM_DIR || join3(HOME, ".nvm");
4071
+ const nvmDir = process.env.NVM_DIR || join4(HOME, ".nvm");
2996
4072
  if (existsSync2(nvmDir)) {
2997
4073
  execSync2(`rm -rf "${nvmDir}"`, { stdio: "pipe" });
2998
- console.log(import_picocolors7.default.dim(` Removido ${nvmDir}`));
4074
+ console.log(import_picocolors8.default.dim(` Removido ${nvmDir}`));
2999
4075
  removed = true;
3000
4076
  }
3001
4077
  spinner.stop(removed ? "nvm removido!" : "nvm nao encontrado");
3002
4078
  return removed;
3003
4079
  }
3004
4080
  } catch (error) {
3005
- spinner.stop(import_picocolors7.default.red("Erro ao remover nvm"));
4081
+ spinner.stop(import_picocolors8.default.red("Erro ao remover nvm"));
3006
4082
  return false;
3007
4083
  }
3008
4084
  }
@@ -3021,14 +4097,14 @@ async function installVolta() {
3021
4097
  timeout: 120000
3022
4098
  });
3023
4099
  spinner.stop("Volta instalado!");
3024
- const voltaPath = join3(HOME, ".volta", "bin");
3025
- console.log(import_picocolors7.default.dim(` Adicionando ${voltaPath} ao PATH...`));
4100
+ const voltaPath = join4(HOME, ".volta", "bin");
4101
+ console.log(import_picocolors8.default.dim(` Adicionando ${voltaPath} ao PATH...`));
3026
4102
  try {
3027
4103
  execSync2(`setx PATH "%PATH%;${voltaPath}"`, { stdio: "pipe", shell: "cmd.exe" });
3028
4104
  } catch {}
3029
4105
  return true;
3030
4106
  } catch (e2) {
3031
- spinner.stop(import_picocolors7.default.yellow("winget falhou, tentando outro metodo..."));
4107
+ spinner.stop(import_picocolors8.default.yellow("winget falhou, tentando outro metodo..."));
3032
4108
  }
3033
4109
  }
3034
4110
  const chocoCheck = spawnSync2(CHECK_CMD, ["choco"], { encoding: "utf-8", shell: true });
@@ -3039,7 +4115,7 @@ async function installVolta() {
3039
4115
  spinner.stop("Volta instalado!");
3040
4116
  return true;
3041
4117
  } catch {
3042
- spinner.stop(import_picocolors7.default.yellow("Chocolatey falhou"));
4118
+ spinner.stop(import_picocolors8.default.yellow("Chocolatey falhou"));
3043
4119
  }
3044
4120
  }
3045
4121
  spinner.start("Baixando Volta diretamente...");
@@ -3063,17 +4139,17 @@ async function installVolta() {
3063
4139
  spinner.stop("Volta instalado!");
3064
4140
  return true;
3065
4141
  } catch (e2) {
3066
- spinner.stop(import_picocolors7.default.yellow("Download direto falhou"));
4142
+ spinner.stop(import_picocolors8.default.yellow("Download direto falhou"));
3067
4143
  }
3068
4144
  console.log();
3069
- console.log(import_picocolors7.default.bold(" Instale manualmente:"));
4145
+ console.log(import_picocolors8.default.bold(" Instale manualmente:"));
3070
4146
  console.log();
3071
- console.log(import_picocolors7.default.cyan(" 1. Baixe: https://github.com/volta-cli/volta/releases/latest"));
3072
- console.log(import_picocolors7.default.dim(" (arquivo volta-windows.msi)"));
4147
+ console.log(import_picocolors8.default.cyan(" 1. Baixe: https://github.com/volta-cli/volta/releases/latest"));
4148
+ console.log(import_picocolors8.default.dim(" (arquivo volta-windows.msi)"));
3073
4149
  console.log();
3074
- console.log(import_picocolors7.default.cyan(" 2. Execute o instalador"));
4150
+ console.log(import_picocolors8.default.cyan(" 2. Execute o instalador"));
3075
4151
  console.log();
3076
- console.log(import_picocolors7.default.cyan(" 3. Reinicie o terminal"));
4152
+ console.log(import_picocolors8.default.cyan(" 3. Reinicie o terminal"));
3077
4153
  console.log();
3078
4154
  return false;
3079
4155
  } else {
@@ -3082,7 +4158,7 @@ async function installVolta() {
3082
4158
  stdio: "pipe",
3083
4159
  shell: "/bin/bash"
3084
4160
  });
3085
- const shellConfig = existsSync2(join3(HOME, ".zshrc")) ? join3(HOME, ".zshrc") : join3(HOME, ".bashrc");
4161
+ const shellConfig = existsSync2(join4(HOME, ".zshrc")) ? join4(HOME, ".zshrc") : join4(HOME, ".bashrc");
3086
4162
  const voltaSetup = `
3087
4163
  # Volta - Node.js version manager
3088
4164
  export VOLTA_HOME="$HOME/.volta"
@@ -3092,28 +4168,28 @@ export PATH="$VOLTA_HOME/bin:$PATH"
3092
4168
  const content = readFileSync2(shellConfig, "utf-8");
3093
4169
  if (!content.includes("VOLTA_HOME")) {
3094
4170
  writeFileSync(shellConfig, content + voltaSetup);
3095
- console.log(import_picocolors7.default.dim(` Adicionado ao ${shellConfig}`));
4171
+ console.log(import_picocolors8.default.dim(` Adicionado ao ${shellConfig}`));
3096
4172
  }
3097
4173
  }
3098
4174
  spinner.stop("Volta instalado!");
3099
4175
  return true;
3100
4176
  }
3101
4177
  } catch (error) {
3102
- spinner.stop(import_picocolors7.default.red("Erro ao instalar Volta"));
3103
- console.log(import_picocolors7.default.dim(` ${error}`));
4178
+ spinner.stop(import_picocolors8.default.red("Erro ao instalar Volta"));
4179
+ console.log(import_picocolors8.default.dim(` ${error}`));
3104
4180
  return false;
3105
4181
  }
3106
4182
  }
3107
4183
  async function installNodeWithVolta() {
3108
4184
  const spinner = Y2();
3109
4185
  try {
3110
- const voltaBin = IS_WINDOWS ? "volta" : join3(HOME, ".volta", "bin", "volta");
4186
+ const voltaBin = IS_WINDOWS ? "volta" : join4(HOME, ".volta", "bin", "volta");
3111
4187
  spinner.start("Instalando Node.js LTS via Volta...");
3112
4188
  execSync2(`"${voltaBin}" install node`, { stdio: "pipe" });
3113
4189
  spinner.stop("Node.js instalado!");
3114
4190
  return true;
3115
4191
  } catch (error) {
3116
- spinner.stop(import_picocolors7.default.red("Erro ao instalar Node.js"));
4192
+ spinner.stop(import_picocolors8.default.red("Erro ao instalar Node.js"));
3117
4193
  return false;
3118
4194
  }
3119
4195
  }
@@ -3121,23 +4197,23 @@ async function reinstallGlobalPackages(packages) {
3121
4197
  if (packages.length === 0)
3122
4198
  return;
3123
4199
  const spinner = Y2();
3124
- const voltaBin = IS_WINDOWS ? "volta" : join3(HOME, ".volta", "bin", "volta");
4200
+ const voltaBin = IS_WINDOWS ? "volta" : join4(HOME, ".volta", "bin", "volta");
3125
4201
  for (const pkg of packages) {
3126
4202
  spinner.start(`Instalando ${pkg}...`);
3127
4203
  try {
3128
4204
  execSync2(`"${voltaBin}" install ${pkg}`, { stdio: "pipe" });
3129
4205
  spinner.stop(`${pkg} instalado!`);
3130
4206
  } catch {
3131
- spinner.stop(import_picocolors7.default.yellow(`${pkg} - falha (instale manualmente)`));
4207
+ spinner.stop(import_picocolors8.default.yellow(`${pkg} - falha (instale manualmente)`));
3132
4208
  }
3133
4209
  }
3134
4210
  }
3135
4211
  async function setupNode(args) {
3136
4212
  const checkOnly = args.includes("--check") || args.includes("-c");
3137
4213
  console.log();
3138
- Ie(import_picocolors7.default.bgCyan(import_picocolors7.default.black(" nimbus setup node ")));
4214
+ Ie(import_picocolors8.default.bgCyan(import_picocolors8.default.black(" nimbus setup node ")));
3139
4215
  console.log();
3140
- console.log(import_picocolors7.default.bold(" Detectando ambiente..."));
4216
+ console.log(import_picocolors8.default.bold(" Detectando ambiente..."));
3141
4217
  console.log();
3142
4218
  const fnm = detectFnm();
3143
4219
  const nvm = detectNvm();
@@ -3145,27 +4221,27 @@ async function setupNode(args) {
3145
4221
  const node = detectNode();
3146
4222
  const status = (installed, version) => {
3147
4223
  if (!installed)
3148
- return import_picocolors7.default.dim("nao instalado");
3149
- return import_picocolors7.default.green(`instalado${version ? ` (${version})` : ""}`);
4224
+ return import_picocolors8.default.dim("nao instalado");
4225
+ return import_picocolors8.default.green(`instalado${version ? ` (${version})` : ""}`);
3150
4226
  };
3151
- console.log(` ${import_picocolors7.default.bold("fnm:")} ${status(fnm.installed, fnm.version)}`);
3152
- console.log(` ${import_picocolors7.default.bold("nvm:")} ${status(nvm.installed, nvm.version)}`);
3153
- console.log(` ${import_picocolors7.default.bold("volta:")} ${status(volta.installed, volta.version)}`);
4227
+ console.log(` ${import_picocolors8.default.bold("fnm:")} ${status(fnm.installed, fnm.version)}`);
4228
+ console.log(` ${import_picocolors8.default.bold("nvm:")} ${status(nvm.installed, nvm.version)}`);
4229
+ console.log(` ${import_picocolors8.default.bold("volta:")} ${status(volta.installed, volta.version)}`);
3154
4230
  console.log();
3155
- console.log(` ${import_picocolors7.default.bold("node:")} ${node.version || import_picocolors7.default.dim("nao encontrado")}`);
4231
+ console.log(` ${import_picocolors8.default.bold("node:")} ${node.version || import_picocolors8.default.dim("nao encontrado")}`);
3156
4232
  if (node.manager) {
3157
- console.log(` ${import_picocolors7.default.dim(`gerenciado por: ${node.manager}`)}`);
4233
+ console.log(` ${import_picocolors8.default.dim(`gerenciado por: ${node.manager}`)}`);
3158
4234
  }
3159
4235
  console.log();
3160
4236
  if (volta.installed && !fnm.installed && !nvm.installed) {
3161
4237
  M2.success("Ambiente OK! Volta instalado e configurado.");
3162
- Se(import_picocolors7.default.green("Nada a fazer."));
4238
+ Se(import_picocolors8.default.green("Nada a fazer."));
3163
4239
  return;
3164
4240
  }
3165
4241
  if (checkOnly) {
3166
4242
  if (fnm.installed || nvm.installed) {
3167
- console.log(import_picocolors7.default.yellow(" Recomendacao: migre para Volta"));
3168
- console.log(import_picocolors7.default.dim(" Execute: nimbus setup node"));
4243
+ console.log(import_picocolors8.default.yellow(" Recomendacao: migre para Volta"));
4244
+ console.log(import_picocolors8.default.dim(" Execute: nimbus setup node"));
3169
4245
  }
3170
4246
  Se("");
3171
4247
  return;
@@ -3173,15 +4249,15 @@ async function setupNode(args) {
3173
4249
  const hasOldManager = fnm.installed || nvm.installed;
3174
4250
  const globalPackages = getGlobalPackages();
3175
4251
  if (hasOldManager) {
3176
- console.log(import_picocolors7.default.yellow(" Gerenciadores antigos detectados!"));
4252
+ console.log(import_picocolors8.default.yellow(" Gerenciadores antigos detectados!"));
3177
4253
  console.log();
3178
- console.log(import_picocolors7.default.dim(" fnm e nvm causam problemas de cache do shell."));
3179
- console.log(import_picocolors7.default.dim(" Volta resolve isso e funciona melhor no Windows."));
4254
+ console.log(import_picocolors8.default.dim(" fnm e nvm causam problemas de cache do shell."));
4255
+ console.log(import_picocolors8.default.dim(" Volta resolve isso e funciona melhor no Windows."));
3180
4256
  console.log();
3181
4257
  if (globalPackages.length > 0) {
3182
- console.log(import_picocolors7.default.bold(" Pacotes globais encontrados:"));
4258
+ console.log(import_picocolors8.default.bold(" Pacotes globais encontrados:"));
3183
4259
  for (const pkg of globalPackages) {
3184
- console.log(import_picocolors7.default.dim(` - ${pkg}`));
4260
+ console.log(import_picocolors8.default.dim(` - ${pkg}`));
3185
4261
  }
3186
4262
  console.log();
3187
4263
  }
@@ -3196,9 +4272,9 @@ async function setupNode(args) {
3196
4272
  actions.push("Instalar Node.js via Volta");
3197
4273
  if (globalPackages.length > 0)
3198
4274
  actions.push(`Reinstalar ${globalPackages.length} pacotes globais`);
3199
- console.log(import_picocolors7.default.bold(" O que sera feito:"));
4275
+ console.log(import_picocolors8.default.bold(" O que sera feito:"));
3200
4276
  for (const action of actions) {
3201
- console.log(import_picocolors7.default.cyan(` -> ${action}`));
4277
+ console.log(import_picocolors8.default.cyan(` -> ${action}`));
3202
4278
  }
3203
4279
  console.log();
3204
4280
  const confirm = await ye({
@@ -3211,60 +4287,60 @@ async function setupNode(args) {
3211
4287
  }
3212
4288
  console.log();
3213
4289
  if (fnm.installed) {
3214
- console.log(import_picocolors7.default.bold(" Removendo fnm..."));
4290
+ console.log(import_picocolors8.default.bold(" Removendo fnm..."));
3215
4291
  await removeFnm(fnm);
3216
4292
  console.log();
3217
4293
  }
3218
4294
  if (nvm.installed) {
3219
- console.log(import_picocolors7.default.bold(" Removendo nvm..."));
4295
+ console.log(import_picocolors8.default.bold(" Removendo nvm..."));
3220
4296
  await removeNvm(nvm);
3221
4297
  console.log();
3222
4298
  }
3223
4299
  if (!volta.installed) {
3224
- console.log(import_picocolors7.default.bold(" Instalando Volta..."));
4300
+ console.log(import_picocolors8.default.bold(" Instalando Volta..."));
3225
4301
  const installed = await installVolta();
3226
4302
  if (!installed) {
3227
- Se(import_picocolors7.default.red("Falha na instalacao. Tente manualmente."));
4303
+ Se(import_picocolors8.default.red("Falha na instalacao. Tente manualmente."));
3228
4304
  return;
3229
4305
  }
3230
4306
  console.log();
3231
4307
  }
3232
- console.log(import_picocolors7.default.bold(" Instalando Node.js..."));
4308
+ console.log(import_picocolors8.default.bold(" Instalando Node.js..."));
3233
4309
  await installNodeWithVolta();
3234
4310
  console.log();
3235
4311
  if (globalPackages.length > 0) {
3236
- console.log(import_picocolors7.default.bold(" Reinstalando pacotes globais..."));
4312
+ console.log(import_picocolors8.default.bold(" Reinstalando pacotes globais..."));
3237
4313
  await reinstallGlobalPackages(globalPackages);
3238
4314
  console.log();
3239
4315
  }
3240
- console.log(import_picocolors7.default.green(" ====================================="));
3241
- console.log(import_picocolors7.default.green(" Migracao concluida!"));
3242
- console.log(import_picocolors7.default.green(" ====================================="));
4316
+ console.log(import_picocolors8.default.green(" ====================================="));
4317
+ console.log(import_picocolors8.default.green(" Migracao concluida!"));
4318
+ console.log(import_picocolors8.default.green(" ====================================="));
3243
4319
  console.log();
3244
4320
  if (IS_WINDOWS) {
3245
- console.log(import_picocolors7.default.yellow(" IMPORTANTE: Reinicie o terminal!"));
4321
+ console.log(import_picocolors8.default.yellow(" IMPORTANTE: Reinicie o terminal!"));
3246
4322
  console.log();
3247
- console.log(import_picocolors7.default.dim(" Feche todas as janelas do PowerShell/Terminal"));
3248
- console.log(import_picocolors7.default.dim(" e abra novamente para aplicar as mudancas."));
4323
+ console.log(import_picocolors8.default.dim(" Feche todas as janelas do PowerShell/Terminal"));
4324
+ console.log(import_picocolors8.default.dim(" e abra novamente para aplicar as mudancas."));
3249
4325
  } else {
3250
- console.log(import_picocolors7.default.yellow(" IMPORTANTE: Reinicie o terminal ou execute:"));
4326
+ console.log(import_picocolors8.default.yellow(" IMPORTANTE: Reinicie o terminal ou execute:"));
3251
4327
  console.log();
3252
- console.log(import_picocolors7.default.cyan(" source ~/.zshrc"));
3253
- console.log(import_picocolors7.default.dim(" # ou"));
3254
- console.log(import_picocolors7.default.cyan(" source ~/.bashrc"));
4328
+ console.log(import_picocolors8.default.cyan(" source ~/.zshrc"));
4329
+ console.log(import_picocolors8.default.dim(" # ou"));
4330
+ console.log(import_picocolors8.default.cyan(" source ~/.bashrc"));
3255
4331
  }
3256
4332
  console.log();
3257
- console.log(import_picocolors7.default.bold(" Depois, verifique:"));
3258
- console.log(import_picocolors7.default.dim(" volta --version"));
3259
- console.log(import_picocolors7.default.dim(" node --version"));
3260
- console.log(import_picocolors7.default.dim(" nimbus --version"));
4333
+ console.log(import_picocolors8.default.bold(" Depois, verifique:"));
4334
+ console.log(import_picocolors8.default.dim(" volta --version"));
4335
+ console.log(import_picocolors8.default.dim(" node --version"));
4336
+ console.log(import_picocolors8.default.dim(" nimbus --version"));
3261
4337
  console.log();
3262
- Se(import_picocolors7.default.green("Pronto! Volta configurado."));
4338
+ Se(import_picocolors8.default.green("Pronto! Volta configurado."));
3263
4339
  }
3264
4340
 
3265
4341
  // src/index.ts
3266
4342
  var PACKAGE_NAME2 = "@nimbuslab/cli";
3267
- var CURRENT_VERSION = "1.0.0";
4343
+ var CURRENT_VERSION = "1.2.0";
3268
4344
  var LOGO = `
3269
4345
  \u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
3270
4346
  \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
@@ -3300,18 +4376,18 @@ function showUpdateNotice(latestVersion) {
3300
4376
  const line2 = ` Atualize com: ${command}`;
3301
4377
  const maxLen = Math.max(line1.length, line2.length);
3302
4378
  const border = "\u2500".repeat(maxLen + 2);
3303
- console.log(import_picocolors8.default.yellow(` \u250C${border}\u2510`));
3304
- console.log(import_picocolors8.default.yellow(` \u2502`) + import_picocolors8.default.white(line1.padEnd(maxLen + 2)) + import_picocolors8.default.yellow(`\u2502`));
3305
- console.log(import_picocolors8.default.yellow(` \u2502`) + import_picocolors8.default.cyan(line2.padEnd(maxLen + 2)) + import_picocolors8.default.yellow(`\u2502`));
3306
- console.log(import_picocolors8.default.yellow(` \u2514${border}\u2518`));
4379
+ console.log(import_picocolors9.default.yellow(` \u250C${border}\u2510`));
4380
+ console.log(import_picocolors9.default.yellow(` \u2502`) + import_picocolors9.default.white(line1.padEnd(maxLen + 2)) + import_picocolors9.default.yellow(`\u2502`));
4381
+ console.log(import_picocolors9.default.yellow(` \u2502`) + import_picocolors9.default.cyan(line2.padEnd(maxLen + 2)) + import_picocolors9.default.yellow(`\u2502`));
4382
+ console.log(import_picocolors9.default.yellow(` \u2514${border}\u2518`));
3307
4383
  console.log();
3308
4384
  }
3309
4385
  async function main() {
3310
4386
  const args = process.argv.slice(2);
3311
4387
  const command = args[0];
3312
- console.log(import_picocolors8.default.cyan(LOGO));
3313
- console.log(import_picocolors8.default.white(" nimbuslab CLI"));
3314
- console.log(import_picocolors8.default.dim(" Create awesome projects"));
4388
+ console.log(import_picocolors9.default.cyan(LOGO));
4389
+ console.log(import_picocolors9.default.white(" nimbuslab CLI"));
4390
+ console.log(import_picocolors9.default.dim(" Create awesome projects"));
3315
4391
  console.log();
3316
4392
  const latestVersion = await checkForUpdates();
3317
4393
  if (latestVersion) {
@@ -3330,8 +4406,8 @@ async function main() {
3330
4406
  if (subcommand === "node") {
3331
4407
  await setupNode(args.slice(2));
3332
4408
  } else {
3333
- console.log(import_picocolors8.default.red(`Subcomando desconhecido: ${subcommand || "(vazio)"}`));
3334
- console.log(import_picocolors8.default.dim(" Uso: nimbus setup node"));
4409
+ console.log(import_picocolors9.default.red(`Subcomando desconhecido: ${subcommand || "(vazio)"}`));
4410
+ console.log(import_picocolors9.default.dim(" Uso: nimbus setup node"));
3335
4411
  process.exit(1);
3336
4412
  }
3337
4413
  } else if (command === "help" || command === "--help" || command === "-h") {
@@ -3339,16 +4415,16 @@ async function main() {
3339
4415
  } else if (command === "version" || command === "--version" || command === "-v") {
3340
4416
  showVersion();
3341
4417
  } else {
3342
- console.log(import_picocolors8.default.red(`Comando desconhecido: ${command}`));
4418
+ console.log(import_picocolors9.default.red(`Comando desconhecido: ${command}`));
3343
4419
  showHelp();
3344
4420
  process.exit(1);
3345
4421
  }
3346
4422
  }
3347
4423
  function showHelp() {
3348
4424
  console.log(`
3349
- ${import_picocolors8.default.bold("Uso:")} nimbus [comando] [op\xE7\xF5es]
4425
+ ${import_picocolors9.default.bold("Uso:")} nimbus [comando] [op\xE7\xF5es]
3350
4426
 
3351
- ${import_picocolors8.default.bold("Comandos:")}
4427
+ ${import_picocolors9.default.bold("Comandos:")}
3352
4428
  create [nome] Criar novo projeto
3353
4429
  analyze [dir] Analisar stack do projeto
3354
4430
  upgrade [alvo] Atualizar depend\xEAncias
@@ -3358,52 +4434,52 @@ ${import_picocolors8.default.bold("Comandos:")}
3358
4434
  help Mostrar esta ajuda
3359
4435
  version Mostrar vers\xE3o
3360
4436
 
3361
- ${import_picocolors8.default.bold("Templates:")}
4437
+ ${import_picocolors9.default.bold("Templates:")}
3362
4438
  --landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
3363
4439
  --app Web app (Landing + Better Auth + Drizzle)
3364
4440
  --turborepo Monorepo (Turborepo + apps/packages)
3365
4441
 
3366
- ${import_picocolors8.default.bold("Analyze & Upgrade:")}
4442
+ ${import_picocolors9.default.bold("Analyze & Upgrade:")}
3367
4443
  analyze . Detectar stack e mostrar recomenda\xE7\xF5es
3368
4444
  analyze --json Output em JSON
3369
4445
  upgrade --plan Mostrar plano de upgrade
3370
4446
  upgrade next Atualizar Next.js
3371
4447
  upgrade tailwind Atualizar Tailwind CSS
3372
4448
 
3373
- ${import_picocolors8.default.bold("Update (CLI):")}
4449
+ ${import_picocolors9.default.bold("Update (CLI):")}
3374
4450
  update Atualizar para ultima versao
3375
4451
  update 0.11.0 Instalar versao especifica
3376
4452
  update --list Listar versoes disponiveis
3377
4453
  update --force Forcar reinstalacao (limpa cache)
3378
4454
 
3379
- ${import_picocolors8.default.bold("Setup (Ambiente):")}
4455
+ ${import_picocolors9.default.bold("Setup (Ambiente):")}
3380
4456
  setup node Migrar para Volta (remove fnm/nvm)
3381
4457
  setup node --check Verificar ambiente atual
3382
4458
 
3383
- ${import_picocolors8.default.bold("Op\xE7\xF5es:")}
4459
+ ${import_picocolors9.default.bold("Op\xE7\xF5es:")}
3384
4460
  -y, --yes Aceitar padr\xF5es
3385
4461
  --no-git N\xE3o inicializar Git
3386
4462
  --no-install N\xE3o instalar depend\xEAncias
3387
4463
  --template <url> Usar template customizado
3388
4464
 
3389
- ${import_picocolors8.default.bold("Lola (Code Agent):")}
4465
+ ${import_picocolors9.default.bold("Lola (Code Agent):")}
3390
4466
  lola install Instalar/atualizar Lola
3391
4467
  lola suggest Sugerir melhoria (cria issue)
3392
4468
 
3393
- ${import_picocolors8.default.bold("Exemplos:")}
3394
- ${import_picocolors8.default.dim("$")} nimbus create my-landing --landing
3395
- ${import_picocolors8.default.dim("$")} nimbus create my-app --app
3396
- ${import_picocolors8.default.dim("$")} nimbus analyze ./my-project
3397
- ${import_picocolors8.default.dim("$")} nimbus upgrade --plan
3398
- ${import_picocolors8.default.dim("$")} nimbus update
3399
- ${import_picocolors8.default.dim("$")} nimbus setup node
3400
- ${import_picocolors8.default.dim("$")} nimbus lola install
4469
+ ${import_picocolors9.default.bold("Exemplos:")}
4470
+ ${import_picocolors9.default.dim("$")} nimbus create my-landing --landing
4471
+ ${import_picocolors9.default.dim("$")} nimbus create my-app --app
4472
+ ${import_picocolors9.default.dim("$")} nimbus analyze ./my-project
4473
+ ${import_picocolors9.default.dim("$")} nimbus upgrade --plan
4474
+ ${import_picocolors9.default.dim("$")} nimbus update
4475
+ ${import_picocolors9.default.dim("$")} nimbus setup node
4476
+ ${import_picocolors9.default.dim("$")} nimbus lola install
3401
4477
  `);
3402
4478
  }
3403
4479
  function showVersion() {
3404
4480
  console.log(`${PACKAGE_NAME2} v${CURRENT_VERSION}`);
3405
4481
  }
3406
4482
  main().catch((err) => {
3407
- console.error(import_picocolors8.default.red("Erro:"), err.message);
4483
+ console.error(import_picocolors9.default.red("Erro:"), err.message);
3408
4484
  process.exit(1);
3409
4485
  });