@nimbuslab/cli 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/dist/index.js +1013 -312
- package/package.json +1 -1
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
|
|
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,666 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
865
865
|
};
|
|
866
866
|
|
|
867
867
|
// src/commands/create.ts
|
|
868
|
-
var
|
|
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 createCompatibilitySymlinks(projectPath);
|
|
881
|
+
}
|
|
882
|
+
async function generateAgentsFile(projectPath, config) {
|
|
883
|
+
const content = `# Project Context for AI Assistants
|
|
884
|
+
|
|
885
|
+
> This file is automatically loaded by Claude Code, Cursor, GitHub Copilot, and other AI coding assistants.
|
|
886
|
+
|
|
887
|
+
## Project Overview
|
|
888
|
+
|
|
889
|
+
**Name:** ${config.name}
|
|
890
|
+
**Type:** ${config.type}
|
|
891
|
+
**Description:** ${config.description}
|
|
892
|
+
|
|
893
|
+
## Quick Start
|
|
894
|
+
|
|
895
|
+
\`\`\`bash
|
|
896
|
+
bun install
|
|
897
|
+
bun dev # http://localhost:3000
|
|
898
|
+
bun build # Production build
|
|
899
|
+
bun lint # ESLint
|
|
900
|
+
bun typecheck # TypeScript check
|
|
901
|
+
\`\`\`
|
|
902
|
+
|
|
903
|
+
## Tech Stack
|
|
904
|
+
|
|
905
|
+
| Category | Technology | Why? |
|
|
906
|
+
|----------|-----------|------|
|
|
907
|
+
| Framework | ${config.stack.framework} | App Router, Turbopack, best DX |
|
|
908
|
+
| Styling | ${config.stack.styling} | Fast, composable, CSS-first |
|
|
909
|
+
| Components | ${config.stack.components} | Copy-paste, zero lock-in |
|
|
910
|
+
${config.stack.forms ? `| Forms | ${config.stack.forms} | Type-safe validation |
|
|
911
|
+
` : ""}${config.stack.email ? `| Email | ${config.stack.email} | Transactional emails |
|
|
912
|
+
` : ""}${config.stack.auth ? `| Auth | ${config.stack.auth} | Secure authentication |
|
|
913
|
+
` : ""}
|
|
914
|
+
## Architecture Decisions
|
|
915
|
+
|
|
916
|
+
### Server vs Client Components
|
|
917
|
+
|
|
918
|
+
**Default: Server Components**
|
|
919
|
+
- Better performance (less JS shipped)
|
|
920
|
+
- SEO-friendly
|
|
921
|
+
- Direct data access
|
|
922
|
+
|
|
923
|
+
**Use Client Components when:**
|
|
924
|
+
- Need \`useState\`/\`useEffect\`
|
|
925
|
+
- Browser APIs (\`localStorage\`, \`window\`)
|
|
926
|
+
- Event handlers (\`onClick\`, \`onChange\`)
|
|
927
|
+
- Third-party libraries that require \`'use client'\`
|
|
928
|
+
|
|
929
|
+
### File Structure
|
|
930
|
+
|
|
931
|
+
\`\`\`
|
|
932
|
+
app/
|
|
933
|
+
\u251C\u2500\u2500 layout.tsx # Root layout
|
|
934
|
+
\u251C\u2500\u2500 page.tsx # Home page
|
|
935
|
+
${config.features.contactForm ? `\u251C\u2500\u2500 api/
|
|
936
|
+
\u2502 \u2514\u2500\u2500 contact/ # Form API
|
|
937
|
+
` : ""}\u2514\u2500\u2500 ...
|
|
938
|
+
|
|
939
|
+
components/
|
|
940
|
+
\u251C\u2500\u2500 ui/ # shadcn/ui components (DON'T EDIT)
|
|
941
|
+
${config.type === "landing" ? `\u251C\u2500\u2500 sections/ # Landing sections
|
|
942
|
+
` : ""}${config.type === "app" ? `\u251C\u2500\u2500 dashboard/ # Dashboard components
|
|
943
|
+
` : ""}\u2514\u2500\u2500 forms/ # Form components
|
|
944
|
+
|
|
945
|
+
lib/
|
|
946
|
+
\u251C\u2500\u2500 utils.ts # Helpers (cn, etc)
|
|
947
|
+
${config.features.contactForm ? `\u251C\u2500\u2500 validations.ts # Zod schemas
|
|
948
|
+
` : ""}${config.stack.email ? `\u251C\u2500\u2500 email.ts # Email client
|
|
949
|
+
` : ""}${config.stack.auth ? `\u251C\u2500\u2500 auth.ts # Auth config
|
|
950
|
+
` : ""}\u2514\u2500\u2500 ...
|
|
951
|
+
\`\`\`
|
|
952
|
+
|
|
953
|
+
## Coding Conventions
|
|
954
|
+
|
|
955
|
+
### Naming
|
|
956
|
+
- Components: \`PascalCase\` (UserProfile.tsx)
|
|
957
|
+
- Files: \`kebab-case\` (user-profile.tsx)
|
|
958
|
+
- Hooks: \`useCamelCase\` (useAuth.ts)
|
|
959
|
+
- Utils: \`camelCase\` (formatDate)
|
|
960
|
+
- Constants: \`SCREAMING_SNAKE_CASE\`
|
|
961
|
+
|
|
962
|
+
### Imports Order
|
|
963
|
+
\`\`\`typescript
|
|
964
|
+
// 1. External
|
|
965
|
+
import { useState } from 'react'
|
|
966
|
+
import { cn } from '@/lib/utils'
|
|
967
|
+
|
|
968
|
+
// 2. Internal components
|
|
969
|
+
import { Button } from '@/components/ui/button'
|
|
970
|
+
|
|
971
|
+
// 3. Local
|
|
972
|
+
import { schema } from './validations'
|
|
973
|
+
|
|
974
|
+
// 4. Types
|
|
975
|
+
import type { User } from '@/types'
|
|
976
|
+
\`\`\`
|
|
977
|
+
|
|
978
|
+
### TypeScript
|
|
979
|
+
- Always use \`type\` for objects
|
|
980
|
+
- Use \`interface\` only for extendable contracts
|
|
981
|
+
- Prefer \`const\` over \`let\`
|
|
982
|
+
- Use arrow functions for components
|
|
983
|
+
- Explicit return types for exported functions
|
|
984
|
+
|
|
985
|
+
## Common Tasks
|
|
986
|
+
|
|
987
|
+
### Add a new section
|
|
988
|
+
\`\`\`bash
|
|
989
|
+
# 1. Create component
|
|
990
|
+
touch components/sections/pricing.tsx
|
|
991
|
+
|
|
992
|
+
# 2. Add to page
|
|
993
|
+
# app/page.tsx
|
|
994
|
+
import { Pricing } from '@/components/sections/pricing'
|
|
995
|
+
\`\`\`
|
|
996
|
+
|
|
997
|
+
${config.features.contactForm ? `### Add form validation
|
|
998
|
+
\`\`\`typescript
|
|
999
|
+
// lib/validations.ts
|
|
1000
|
+
export const contactSchema = z.object({
|
|
1001
|
+
email: z.string().email('Email inv\xE1lido'),
|
|
1002
|
+
message: z.string().min(10, 'M\xEDnimo 10 caracteres'),
|
|
1003
|
+
})
|
|
1004
|
+
|
|
1005
|
+
// components/forms/contact-form.tsx
|
|
1006
|
+
const form = useForm<z.infer<typeof contactSchema>>({
|
|
1007
|
+
resolver: zodResolver(contactSchema),
|
|
1008
|
+
})
|
|
1009
|
+
\`\`\`
|
|
1010
|
+
|
|
1011
|
+
` : ""}${config.stack.email ? `### Send email
|
|
1012
|
+
\`\`\`typescript
|
|
1013
|
+
// app/api/contact/route.ts
|
|
1014
|
+
import { resend } from '@/lib/email'
|
|
1015
|
+
|
|
1016
|
+
await resend.emails.send({
|
|
1017
|
+
from: 'noreply@example.com',
|
|
1018
|
+
to: 'contact@example.com',
|
|
1019
|
+
subject: 'Novo contato',
|
|
1020
|
+
react: ContactEmail({ name, email, message }),
|
|
1021
|
+
})
|
|
1022
|
+
\`\`\`
|
|
1023
|
+
|
|
1024
|
+
` : ""}## Performance Targets
|
|
1025
|
+
|
|
1026
|
+
| Metric | Target |
|
|
1027
|
+
|--------|--------|
|
|
1028
|
+
| Lighthouse Performance | 95+ |
|
|
1029
|
+
| LCP | < 2.0s |
|
|
1030
|
+
| CLS | < 0.05 |
|
|
1031
|
+
| Bundle Size | < 100KB |
|
|
1032
|
+
|
|
1033
|
+
## Environment Variables
|
|
1034
|
+
|
|
1035
|
+
\`\`\`env
|
|
1036
|
+
# Required
|
|
1037
|
+
${config.stack.email ? `RESEND_API_KEY=re_*** # Get: https://resend.com/api-keys
|
|
1038
|
+
` : ""}${config.stack.auth ? `NEXTAUTH_SECRET=*** # Generate: openssl rand -base64 32
|
|
1039
|
+
` : ""}
|
|
1040
|
+
# Optional
|
|
1041
|
+
NEXT_PUBLIC_GA_ID=G-*** # Google Analytics
|
|
1042
|
+
\`\`\`
|
|
1043
|
+
|
|
1044
|
+
## Testing
|
|
1045
|
+
|
|
1046
|
+
\`\`\`bash
|
|
1047
|
+
bun test # Unit tests
|
|
1048
|
+
bun test:e2e # E2E tests
|
|
1049
|
+
bun lint # ESLint
|
|
1050
|
+
bun typecheck # TypeScript
|
|
1051
|
+
\`\`\`
|
|
1052
|
+
|
|
1053
|
+
## Deployment
|
|
1054
|
+
|
|
1055
|
+
Auto-deploys to Vercel on push to \`main\`.
|
|
1056
|
+
|
|
1057
|
+
**Manual:**
|
|
1058
|
+
\`\`\`bash
|
|
1059
|
+
vercel --prod
|
|
1060
|
+
\`\`\`
|
|
1061
|
+
|
|
1062
|
+
## Troubleshooting
|
|
1063
|
+
|
|
1064
|
+
### Build errors
|
|
1065
|
+
- Clear \`.next\`: \`rm -rf .next\`
|
|
1066
|
+
- Clear cache: \`bun install --force\`
|
|
1067
|
+
|
|
1068
|
+
### Type errors
|
|
1069
|
+
- Restart TS server in IDE
|
|
1070
|
+
- Check \`tsconfig.json\` paths
|
|
1071
|
+
|
|
1072
|
+
## Resources
|
|
1073
|
+
|
|
1074
|
+
- [Next.js Docs](https://nextjs.org/docs)
|
|
1075
|
+
- [Tailwind Docs](https://tailwindcss.com/docs)
|
|
1076
|
+
- [shadcn/ui](https://ui.shadcn.com)
|
|
1077
|
+
${config.stack.email ? `- [Resend Docs](https://resend.com/docs)
|
|
1078
|
+
` : ""}${config.stack.auth ? `- [NextAuth Docs](https://authjs.dev)
|
|
1079
|
+
` : ""}
|
|
1080
|
+
---
|
|
1081
|
+
|
|
1082
|
+
*Generated by @nimbuslab/cli*
|
|
1083
|
+
*Last updated: ${new Date().toISOString().split("T")[0]}*
|
|
1084
|
+
`;
|
|
1085
|
+
await Bun.write(join(projectPath, "AGENTS.md"), content);
|
|
1086
|
+
}
|
|
1087
|
+
async function generateLLMsFile(projectPath, config) {
|
|
1088
|
+
const content = `# ${config.name}
|
|
1089
|
+
|
|
1090
|
+
> AI-friendly documentation index
|
|
1091
|
+
|
|
1092
|
+
## Navigation
|
|
1093
|
+
|
|
1094
|
+
- [Project Overview](./AGENTS.md)
|
|
1095
|
+
- [Architecture](./ARCHITECTURE.md)
|
|
1096
|
+
- [Examples](./EXAMPLES.md)
|
|
1097
|
+
- [Contributing](./CONTRIBUTING.md)
|
|
1098
|
+
|
|
1099
|
+
## Quick Context
|
|
1100
|
+
|
|
1101
|
+
${config.description}
|
|
1102
|
+
|
|
1103
|
+
**Stack:** ${config.stack.framework}, ${config.stack.styling}, ${config.stack.components}
|
|
1104
|
+
|
|
1105
|
+
## Common Questions
|
|
1106
|
+
|
|
1107
|
+
### How do I start development?
|
|
1108
|
+
\`\`\`bash
|
|
1109
|
+
bun install && bun dev
|
|
1110
|
+
\`\`\`
|
|
1111
|
+
|
|
1112
|
+
${config.features.contactForm ? `### How do I configure email?
|
|
1113
|
+
See [AGENTS.md#send-email](./AGENTS.md#send-email)
|
|
1114
|
+
|
|
1115
|
+
` : ""}${config.features.auth ? `### How do I set up authentication?
|
|
1116
|
+
See [AGENTS.md#environment-variables](./AGENTS.md#environment-variables)
|
|
1117
|
+
|
|
1118
|
+
` : ""}### How do I deploy?
|
|
1119
|
+
Push to \`main\` branch - auto-deploys to Vercel.
|
|
1120
|
+
|
|
1121
|
+
## File Structure
|
|
1122
|
+
|
|
1123
|
+
\`\`\`
|
|
1124
|
+
app/ # Next.js app router
|
|
1125
|
+
components/ # React components
|
|
1126
|
+
ui/ # shadcn/ui (auto-generated)
|
|
1127
|
+
lib/ # Utilities
|
|
1128
|
+
public/ # Static assets
|
|
1129
|
+
\`\`\`
|
|
1130
|
+
|
|
1131
|
+
---
|
|
1132
|
+
|
|
1133
|
+
*Auto-generated for LLM consumption*
|
|
1134
|
+
*Learn more: https://mintlify.com/blog/simplifying-docs-with-llms-txt*
|
|
1135
|
+
`;
|
|
1136
|
+
await Bun.write(join(projectPath, "llms.txt"), content);
|
|
1137
|
+
}
|
|
1138
|
+
async function generateArchitectureDoc(projectPath, config) {
|
|
1139
|
+
const content = `# Architecture
|
|
1140
|
+
|
|
1141
|
+
## Design Decisions
|
|
1142
|
+
|
|
1143
|
+
### 1. Next.js App Router
|
|
1144
|
+
|
|
1145
|
+
**Why:**
|
|
1146
|
+
- React Server Components by default
|
|
1147
|
+
- Better performance (less client JS)
|
|
1148
|
+
- Simplified data fetching
|
|
1149
|
+
- Native TypeScript support
|
|
1150
|
+
|
|
1151
|
+
**Trade-offs:**
|
|
1152
|
+
- Learning curve vs Pages Router
|
|
1153
|
+
- Some libraries require \`'use client'\`
|
|
1154
|
+
|
|
1155
|
+
### 2. ${config.stack.styling}
|
|
1156
|
+
|
|
1157
|
+
**Why:**
|
|
1158
|
+
- Zero runtime (pure CSS)
|
|
1159
|
+
- Better performance
|
|
1160
|
+
- Smaller bundle size
|
|
1161
|
+
- Familiar DX
|
|
1162
|
+
|
|
1163
|
+
${config.type === "landing" ? `### 3. Landing Page Structure
|
|
1164
|
+
|
|
1165
|
+
\`\`\`
|
|
1166
|
+
Hero
|
|
1167
|
+
\u2193
|
|
1168
|
+
Social Proof / Features
|
|
1169
|
+
\u2193
|
|
1170
|
+
How It Works
|
|
1171
|
+
\u2193
|
|
1172
|
+
Testimonials
|
|
1173
|
+
\u2193
|
|
1174
|
+
FAQ
|
|
1175
|
+
\u2193
|
|
1176
|
+
CTA
|
|
1177
|
+
\u2193
|
|
1178
|
+
Footer
|
|
1179
|
+
\`\`\`
|
|
1180
|
+
|
|
1181
|
+
` : ""}## Data Flow
|
|
1182
|
+
|
|
1183
|
+
\`\`\`
|
|
1184
|
+
User Action
|
|
1185
|
+
\u2193
|
|
1186
|
+
Client Component (onClick)
|
|
1187
|
+
\u2193
|
|
1188
|
+
${config.features.contactForm ? `Server Action / API Route
|
|
1189
|
+
\u2193
|
|
1190
|
+
Validation (Zod)
|
|
1191
|
+
\u2193
|
|
1192
|
+
` : ""}${config.stack.email ? `External API (Resend)
|
|
1193
|
+
\u2193
|
|
1194
|
+
` : ""}Response to client
|
|
1195
|
+
\`\`\`
|
|
1196
|
+
|
|
1197
|
+
## Performance Strategy
|
|
1198
|
+
|
|
1199
|
+
### 1. Server Components First
|
|
1200
|
+
- Default to Server Components
|
|
1201
|
+
- Only use Client when needed
|
|
1202
|
+
- Less JavaScript shipped
|
|
1203
|
+
|
|
1204
|
+
### 2. Image Optimization
|
|
1205
|
+
- Always use \`next/image\`
|
|
1206
|
+
- Lazy loading by default
|
|
1207
|
+
- Modern formats (WebP, AVIF)
|
|
1208
|
+
|
|
1209
|
+
### 3. Code Splitting
|
|
1210
|
+
- Dynamic imports for heavy components
|
|
1211
|
+
- Route-based splitting (automatic)
|
|
1212
|
+
|
|
1213
|
+
## Security
|
|
1214
|
+
|
|
1215
|
+
### 1. Environment Variables
|
|
1216
|
+
- Never commit \`.env\`
|
|
1217
|
+
- Use \`.env.example\` for templates
|
|
1218
|
+
- Validate on startup
|
|
1219
|
+
|
|
1220
|
+
${config.features.contactForm ? `### 2. Form Validation
|
|
1221
|
+
- Client + Server validation
|
|
1222
|
+
- Zod schemas shared
|
|
1223
|
+
- Sanitize inputs
|
|
1224
|
+
|
|
1225
|
+
` : ""}### 3. Rate Limiting
|
|
1226
|
+
- API routes protected
|
|
1227
|
+
- Per-IP limits
|
|
1228
|
+
|
|
1229
|
+
---
|
|
1230
|
+
|
|
1231
|
+
*This document explains WHY, not HOW.*
|
|
1232
|
+
*For HOW, see AGENTS.md*
|
|
1233
|
+
`;
|
|
1234
|
+
await Bun.write(join(projectPath, "ARCHITECTURE.md"), content);
|
|
1235
|
+
}
|
|
1236
|
+
async function generateExamplesDoc(projectPath, config) {
|
|
1237
|
+
const content = `# Examples
|
|
1238
|
+
|
|
1239
|
+
Common tasks with complete code examples.
|
|
1240
|
+
|
|
1241
|
+
## Adding a New Component
|
|
1242
|
+
|
|
1243
|
+
\`\`\`tsx
|
|
1244
|
+
// components/ui/card.tsx
|
|
1245
|
+
export function Card({ children, className }: {
|
|
1246
|
+
children: React.ReactNode
|
|
1247
|
+
className?: string
|
|
1248
|
+
}) {
|
|
1249
|
+
return (
|
|
1250
|
+
<div className={cn("rounded-lg border p-6", className)}>
|
|
1251
|
+
{children}
|
|
1252
|
+
</div>
|
|
1253
|
+
)
|
|
1254
|
+
}
|
|
1255
|
+
\`\`\`
|
|
1256
|
+
|
|
1257
|
+
${config.features.contactForm ? `## Form with Validation
|
|
1258
|
+
|
|
1259
|
+
\`\`\`tsx
|
|
1260
|
+
// lib/validations.ts
|
|
1261
|
+
export const contactSchema = z.object({
|
|
1262
|
+
name: z.string().min(2, 'Nome muito curto'),
|
|
1263
|
+
email: z.string().email('Email inv\xE1lido'),
|
|
1264
|
+
message: z.string().min(10, 'Mensagem muito curta'),
|
|
1265
|
+
})
|
|
1266
|
+
|
|
1267
|
+
// components/forms/contact.tsx
|
|
1268
|
+
'use client'
|
|
1269
|
+
|
|
1270
|
+
import { useForm } from 'react-hook-form'
|
|
1271
|
+
import { zodResolver } from '@hookform/resolvers/zod'
|
|
1272
|
+
|
|
1273
|
+
export function ContactForm() {
|
|
1274
|
+
const form = useForm({
|
|
1275
|
+
resolver: zodResolver(contactSchema),
|
|
1276
|
+
})
|
|
1277
|
+
|
|
1278
|
+
async function onSubmit(data) {
|
|
1279
|
+
const res = await fetch('/api/contact', {
|
|
1280
|
+
method: 'POST',
|
|
1281
|
+
body: JSON.stringify(data),
|
|
1282
|
+
})
|
|
1283
|
+
// Handle response
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
return <form onSubmit={form.handleSubmit(onSubmit)}>...</form>
|
|
1287
|
+
}
|
|
1288
|
+
\`\`\`
|
|
1289
|
+
|
|
1290
|
+
` : ""}## Adding Animation
|
|
1291
|
+
|
|
1292
|
+
\`\`\`tsx
|
|
1293
|
+
'use client'
|
|
1294
|
+
|
|
1295
|
+
import { motion } from 'framer-motion'
|
|
1296
|
+
|
|
1297
|
+
export function FadeIn({ children }: { children: React.ReactNode }) {
|
|
1298
|
+
return (
|
|
1299
|
+
<motion.div
|
|
1300
|
+
initial={{ opacity: 0, y: 20 }}
|
|
1301
|
+
animate={{ opacity: 1, y: 0 }}
|
|
1302
|
+
transition={{ duration: 0.5 }}
|
|
1303
|
+
>
|
|
1304
|
+
{children}
|
|
1305
|
+
</motion.div>
|
|
1306
|
+
)
|
|
1307
|
+
}
|
|
1308
|
+
\`\`\`
|
|
1309
|
+
|
|
1310
|
+
## Environment Variables
|
|
1311
|
+
|
|
1312
|
+
\`\`\`typescript
|
|
1313
|
+
// lib/env.ts
|
|
1314
|
+
import { z } from 'zod'
|
|
1315
|
+
|
|
1316
|
+
const envSchema = z.object({
|
|
1317
|
+
${config.stack.email ? `RESEND_API_KEY: z.string().min(1),
|
|
1318
|
+
` : ""}NODE_ENV: z.enum(['development', 'production', 'test']),
|
|
1319
|
+
})
|
|
1320
|
+
|
|
1321
|
+
export const env = envSchema.parse(process.env)
|
|
1322
|
+
\`\`\`
|
|
1323
|
+
|
|
1324
|
+
---
|
|
1325
|
+
|
|
1326
|
+
*For more examples, see the component files*
|
|
1327
|
+
`;
|
|
1328
|
+
await Bun.write(join(projectPath, "EXAMPLES.md"), content);
|
|
1329
|
+
}
|
|
1330
|
+
async function createCompatibilitySymlinks(projectPath) {
|
|
1331
|
+
const agentsContent = await Bun.file(join(projectPath, "AGENTS.md")).text();
|
|
1332
|
+
await Bun.write(join(projectPath, ".cursorrules"), agentsContent);
|
|
1333
|
+
const githubDir = join(projectPath, ".github");
|
|
1334
|
+
await Bun.$`mkdir -p ${githubDir}`.quiet();
|
|
1335
|
+
await Bun.write(join(githubDir, "copilot-instructions.md"), agentsContent);
|
|
1336
|
+
}
|
|
1337
|
+
// src/lib/generators/interactive-setup.ts
|
|
1338
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
1339
|
+
var SERVICE_INFO = {
|
|
1340
|
+
resend: {
|
|
1341
|
+
name: "Resend",
|
|
1342
|
+
description: "Servi\xE7o de email transacional",
|
|
1343
|
+
pricing: "Gr\xE1tis: 3,000 emails/m\xEAs",
|
|
1344
|
+
signupUrl: "https://resend.com/signup",
|
|
1345
|
+
apiKeyUrl: "https://resend.com/api-keys",
|
|
1346
|
+
keyPrefix: "re_"
|
|
1347
|
+
},
|
|
1348
|
+
googleAnalytics: {
|
|
1349
|
+
name: "Google Analytics",
|
|
1350
|
+
description: "Analytics e m\xE9tricas do site",
|
|
1351
|
+
pricing: "Gr\xE1tis",
|
|
1352
|
+
setupUrl: "https://analytics.google.com",
|
|
1353
|
+
keyFormat: "G-XXXXXXXXXX"
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
async function interactiveSetup(templateType) {
|
|
1357
|
+
console.log();
|
|
1358
|
+
console.log(import_picocolors3.default.cyan(" Configura\xE7\xE3o Interativa"));
|
|
1359
|
+
console.log(import_picocolors3.default.dim(" ======================="));
|
|
1360
|
+
console.log();
|
|
1361
|
+
const skipSetup = await ye({
|
|
1362
|
+
message: "Deseja configurar integra\xE7\xF5es agora?",
|
|
1363
|
+
initialValue: true
|
|
1364
|
+
});
|
|
1365
|
+
if (pD(skipSetup) || !skipSetup) {
|
|
1366
|
+
return {
|
|
1367
|
+
features: {
|
|
1368
|
+
contactForm: false,
|
|
1369
|
+
newsletter: false,
|
|
1370
|
+
analytics: false
|
|
1371
|
+
},
|
|
1372
|
+
apiKeys: {},
|
|
1373
|
+
skipSetup: true
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
const result = {
|
|
1377
|
+
features: {
|
|
1378
|
+
contactForm: false,
|
|
1379
|
+
newsletter: false,
|
|
1380
|
+
analytics: false
|
|
1381
|
+
},
|
|
1382
|
+
apiKeys: {},
|
|
1383
|
+
skipSetup: false
|
|
1384
|
+
};
|
|
1385
|
+
if (templateType === "landing" || templateType === "app") {
|
|
1386
|
+
const contactFormSetup = await setupContactForm();
|
|
1387
|
+
if (!pD(contactFormSetup)) {
|
|
1388
|
+
result.features.contactForm = contactFormSetup.enabled;
|
|
1389
|
+
if (contactFormSetup.apiKey) {
|
|
1390
|
+
result.apiKeys.resend = contactFormSetup.apiKey;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
const analyticsSetup = await setupAnalytics();
|
|
1395
|
+
if (!pD(analyticsSetup)) {
|
|
1396
|
+
result.features.analytics = analyticsSetup.enabled;
|
|
1397
|
+
if (analyticsSetup.trackingId) {
|
|
1398
|
+
result.apiKeys.ga = analyticsSetup.trackingId;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
return result;
|
|
1402
|
+
}
|
|
1403
|
+
async function setupContactForm() {
|
|
1404
|
+
console.log();
|
|
1405
|
+
console.log(import_picocolors3.default.cyan(" \uD83D\uDCE7 Formul\xE1rio de Contato"));
|
|
1406
|
+
console.log();
|
|
1407
|
+
const needsForm = await ve({
|
|
1408
|
+
message: "Incluir formul\xE1rio de contato?",
|
|
1409
|
+
options: [
|
|
1410
|
+
{ value: "now", label: "Sim, configurar agora" },
|
|
1411
|
+
{ value: "later", label: "Sim, mas configurar depois" },
|
|
1412
|
+
{ value: "no", label: "N\xE3o incluir" }
|
|
1413
|
+
]
|
|
1414
|
+
});
|
|
1415
|
+
if (pD(needsForm) || needsForm === "no") {
|
|
1416
|
+
return { enabled: false };
|
|
1417
|
+
}
|
|
1418
|
+
if (needsForm === "later") {
|
|
1419
|
+
return { enabled: true };
|
|
1420
|
+
}
|
|
1421
|
+
showServiceInfo("resend");
|
|
1422
|
+
const apiKey = await he({
|
|
1423
|
+
message: "Resend API Key (deixe vazio para configurar depois):",
|
|
1424
|
+
placeholder: "re_...",
|
|
1425
|
+
validate: (v2) => {
|
|
1426
|
+
if (!v2)
|
|
1427
|
+
return;
|
|
1428
|
+
if (!v2.startsWith(SERVICE_INFO.resend.keyPrefix)) {
|
|
1429
|
+
return `Key inv\xE1lida (deve come\xE7ar com ${SERVICE_INFO.resend.keyPrefix})`;
|
|
1430
|
+
}
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
});
|
|
1434
|
+
if (pD(apiKey)) {
|
|
1435
|
+
return { enabled: true };
|
|
1436
|
+
}
|
|
1437
|
+
return {
|
|
1438
|
+
enabled: true,
|
|
1439
|
+
apiKey: apiKey || undefined
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
async function setupAnalytics() {
|
|
1443
|
+
console.log();
|
|
1444
|
+
console.log(import_picocolors3.default.cyan(" \uD83D\uDCCA Analytics"));
|
|
1445
|
+
console.log();
|
|
1446
|
+
const needsAnalytics = await ye({
|
|
1447
|
+
message: "Incluir Google Analytics?",
|
|
1448
|
+
initialValue: false
|
|
1449
|
+
});
|
|
1450
|
+
if (pD(needsAnalytics) || !needsAnalytics) {
|
|
1451
|
+
return { enabled: false };
|
|
1452
|
+
}
|
|
1453
|
+
showServiceInfo("googleAnalytics");
|
|
1454
|
+
const trackingId = await he({
|
|
1455
|
+
message: "Google Analytics Tracking ID (deixe vazio para configurar depois):",
|
|
1456
|
+
placeholder: "G-XXXXXXXXXX",
|
|
1457
|
+
validate: (v2) => {
|
|
1458
|
+
if (!v2)
|
|
1459
|
+
return;
|
|
1460
|
+
if (!v2.startsWith("G-")) {
|
|
1461
|
+
return "ID inv\xE1lido (deve come\xE7ar com G-)";
|
|
1462
|
+
}
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
});
|
|
1466
|
+
if (pD(trackingId)) {
|
|
1467
|
+
return { enabled: false };
|
|
1468
|
+
}
|
|
1469
|
+
return {
|
|
1470
|
+
enabled: true,
|
|
1471
|
+
trackingId: trackingId || undefined
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
function showServiceInfo(service) {
|
|
1475
|
+
const info = SERVICE_INFO[service];
|
|
1476
|
+
console.log();
|
|
1477
|
+
console.log(import_picocolors3.default.bold(` ${info.name}`));
|
|
1478
|
+
console.log(import_picocolors3.default.dim(` ${info.description}`));
|
|
1479
|
+
console.log(import_picocolors3.default.dim(` ${info.pricing}`));
|
|
1480
|
+
if ("apiKeyUrl" in info) {
|
|
1481
|
+
console.log(import_picocolors3.default.cyan(` ${info.apiKeyUrl}`));
|
|
1482
|
+
} else if ("setupUrl" in info) {
|
|
1483
|
+
console.log(import_picocolors3.default.cyan(` ${info.setupUrl}`));
|
|
1484
|
+
}
|
|
1485
|
+
console.log();
|
|
1486
|
+
}
|
|
1487
|
+
async function generateEnvFile(projectPath, apiKeys, features) {
|
|
1488
|
+
const lines = [
|
|
1489
|
+
"# ====================================",
|
|
1490
|
+
"# Environment Variables",
|
|
1491
|
+
"# ====================================",
|
|
1492
|
+
"",
|
|
1493
|
+
"# IMPORTANT: Add this file to .gitignore",
|
|
1494
|
+
"# Never commit API keys to version control!",
|
|
1495
|
+
""
|
|
1496
|
+
];
|
|
1497
|
+
if (features.contactForm) {
|
|
1498
|
+
lines.push("# Email (Resend)");
|
|
1499
|
+
lines.push("# Get your key: https://resend.com/api-keys");
|
|
1500
|
+
lines.push(`RESEND_API_KEY=${apiKeys.resend || "your_api_key_here"}`);
|
|
1501
|
+
lines.push("");
|
|
1502
|
+
}
|
|
1503
|
+
if (features.analytics) {
|
|
1504
|
+
lines.push("# Analytics (Google Analytics)");
|
|
1505
|
+
lines.push("# Get your ID: https://analytics.google.com");
|
|
1506
|
+
lines.push(`NEXT_PUBLIC_GA_ID=${apiKeys.ga || "G-XXXXXXXXXX"}`);
|
|
1507
|
+
lines.push("");
|
|
1508
|
+
}
|
|
1509
|
+
lines.push("# ====================================");
|
|
1510
|
+
lines.push("# Docs completa em README.md");
|
|
1511
|
+
lines.push("# ====================================");
|
|
1512
|
+
const content = lines.join(`
|
|
1513
|
+
`);
|
|
1514
|
+
await Bun.write(`${projectPath}/.env`, content);
|
|
1515
|
+
const exampleLines = lines.map((line) => {
|
|
1516
|
+
if (line.includes("RESEND_API_KEY=") && !line.startsWith("#")) {
|
|
1517
|
+
return "RESEND_API_KEY=re_your_key_here";
|
|
1518
|
+
}
|
|
1519
|
+
if (line.includes("NEXT_PUBLIC_GA_ID=") && !line.startsWith("#")) {
|
|
1520
|
+
return "NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX";
|
|
1521
|
+
}
|
|
1522
|
+
return line;
|
|
1523
|
+
});
|
|
1524
|
+
await Bun.write(`${projectPath}/.env.example`, exampleLines.join(`
|
|
1525
|
+
`));
|
|
1526
|
+
}
|
|
1527
|
+
// src/commands/create.ts
|
|
872
1528
|
var AI_CONFIGS = {
|
|
873
1529
|
claude: {
|
|
874
1530
|
filename: "CLAUDE.md",
|
|
@@ -1068,7 +1724,7 @@ async function ensureRailwayCli() {
|
|
|
1068
1724
|
const hasRailway = await $2`${checkCmd} railway`.quiet().then(() => true).catch(() => false);
|
|
1069
1725
|
if (hasRailway)
|
|
1070
1726
|
return true;
|
|
1071
|
-
console.log(
|
|
1727
|
+
console.log(import_picocolors4.default.yellow("Railway CLI not found. Installing..."));
|
|
1072
1728
|
console.log();
|
|
1073
1729
|
try {
|
|
1074
1730
|
if (process.platform === "win32") {
|
|
@@ -1076,11 +1732,11 @@ async function ensureRailwayCli() {
|
|
|
1076
1732
|
} else {
|
|
1077
1733
|
await $2`curl -fsSL https://railway.app/install.sh | sh`.quiet();
|
|
1078
1734
|
}
|
|
1079
|
-
console.log(
|
|
1735
|
+
console.log(import_picocolors4.default.green("Railway CLI installed successfully!"));
|
|
1080
1736
|
return true;
|
|
1081
1737
|
} catch (error) {
|
|
1082
|
-
console.log(
|
|
1083
|
-
console.log(
|
|
1738
|
+
console.log(import_picocolors4.default.red("Error installing Railway CLI."));
|
|
1739
|
+
console.log(import_picocolors4.default.dim("Install manually: https://docs.railway.app/guides/cli"));
|
|
1084
1740
|
return false;
|
|
1085
1741
|
}
|
|
1086
1742
|
}
|
|
@@ -1108,38 +1764,38 @@ async function create(args) {
|
|
|
1108
1764
|
const hasGit = await $2`${checkCmd} git`.quiet().then(() => true).catch(() => false);
|
|
1109
1765
|
const hasGh = await $2`${checkCmd} gh`.quiet().then(() => true).catch(() => false);
|
|
1110
1766
|
if (!hasBun) {
|
|
1111
|
-
console.log(
|
|
1112
|
-
console.log(
|
|
1767
|
+
console.log(import_picocolors4.default.red("Error: Bun not found."));
|
|
1768
|
+
console.log(import_picocolors4.default.dim("Install from: https://bun.sh"));
|
|
1113
1769
|
console.log();
|
|
1114
1770
|
if (process.platform === "win32") {
|
|
1115
|
-
console.log(
|
|
1771
|
+
console.log(import_picocolors4.default.cyan('powershell -c "irm bun.sh/install.ps1 | iex"'));
|
|
1116
1772
|
} else {
|
|
1117
|
-
console.log(
|
|
1773
|
+
console.log(import_picocolors4.default.cyan("curl -fsSL https://bun.sh/install | bash"));
|
|
1118
1774
|
}
|
|
1119
1775
|
console.log();
|
|
1120
1776
|
process.exit(1);
|
|
1121
1777
|
}
|
|
1122
1778
|
if (!hasGit) {
|
|
1123
|
-
console.log(
|
|
1124
|
-
console.log(
|
|
1779
|
+
console.log(import_picocolors4.default.red("Error: Git not found."));
|
|
1780
|
+
console.log(import_picocolors4.default.dim("Install git to continue."));
|
|
1125
1781
|
process.exit(1);
|
|
1126
1782
|
}
|
|
1127
1783
|
if (!hasGh) {
|
|
1128
|
-
console.log(
|
|
1129
|
-
console.log(
|
|
1784
|
+
console.log(import_picocolors4.default.dim(" GitHub CLI not found (repo creation will be skipped)"));
|
|
1785
|
+
console.log(import_picocolors4.default.dim(" Install from: https://cli.github.com"));
|
|
1130
1786
|
console.log();
|
|
1131
1787
|
}
|
|
1132
1788
|
const hasRailway = await ensureRailwayCli();
|
|
1133
1789
|
if (hasRailway) {
|
|
1134
1790
|
const railwayAuth = await isRailwayAuthenticated();
|
|
1135
1791
|
if (!railwayAuth) {
|
|
1136
|
-
console.log(
|
|
1137
|
-
console.log(
|
|
1792
|
+
console.log(import_picocolors4.default.yellow("Railway CLI not authenticated."));
|
|
1793
|
+
console.log(import_picocolors4.default.dim("Run: railway login"));
|
|
1138
1794
|
console.log();
|
|
1139
1795
|
}
|
|
1140
1796
|
}
|
|
1141
1797
|
const { flags, projectName } = parseFlags(args);
|
|
1142
|
-
Ie(
|
|
1798
|
+
Ie(import_picocolors4.default.bgCyan(import_picocolors4.default.black(" New nimbuslab Project ")));
|
|
1143
1799
|
let config;
|
|
1144
1800
|
const hasTypeFlag = flags.landing || flags.app || flags.turborepo || flags.fast || flags.fastPlus || flags.fastTurborepo || flags.core;
|
|
1145
1801
|
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 +1824,14 @@ async function create(args) {
|
|
|
1168
1824
|
customTemplate: flags.template
|
|
1169
1825
|
};
|
|
1170
1826
|
const typeLabel = flags.turborepo ? "fast+ (monorepo)" : config.type;
|
|
1171
|
-
console.log(
|
|
1172
|
-
console.log(
|
|
1173
|
-
console.log(
|
|
1174
|
-
console.log(
|
|
1827
|
+
console.log(import_picocolors4.default.dim(` Project: ${projectName}`));
|
|
1828
|
+
console.log(import_picocolors4.default.dim(` Type: ${typeLabel}`));
|
|
1829
|
+
console.log(import_picocolors4.default.dim(` Git: ${config.git ? "yes" : "no"}`));
|
|
1830
|
+
console.log(import_picocolors4.default.dim(` Install: ${config.install ? "yes" : "no"}`));
|
|
1175
1831
|
if (flags.railway)
|
|
1176
|
-
console.log(
|
|
1832
|
+
console.log(import_picocolors4.default.dim(` Railway: configurar`));
|
|
1177
1833
|
if (flags.template)
|
|
1178
|
-
console.log(
|
|
1834
|
+
console.log(import_picocolors4.default.dim(` Template: ${flags.template}`));
|
|
1179
1835
|
console.log();
|
|
1180
1836
|
if (flags.railway) {
|
|
1181
1837
|
const railwayAuthenticated = await isRailwayAuthenticated();
|
|
@@ -1185,21 +1841,21 @@ async function create(args) {
|
|
|
1185
1841
|
const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
|
|
1186
1842
|
if (fastProject) {
|
|
1187
1843
|
config.railwayProject = fastProject;
|
|
1188
|
-
console.log(
|
|
1844
|
+
console.log(import_picocolors4.default.green(` Railway: ${fastProject}`));
|
|
1189
1845
|
}
|
|
1190
1846
|
} else {
|
|
1191
|
-
console.log(
|
|
1847
|
+
console.log(import_picocolors4.default.dim(` Creating project Railway: ${projectName}...`));
|
|
1192
1848
|
try {
|
|
1193
1849
|
const result = await $2`echo "" | railway init -n ${projectName} -w nimbuslab --json`.text();
|
|
1194
1850
|
const newProject = JSON.parse(result);
|
|
1195
1851
|
config.railwayProject = newProject.name || projectName;
|
|
1196
|
-
console.log(
|
|
1852
|
+
console.log(import_picocolors4.default.green(` Railway: ${config.railwayProject} criado`));
|
|
1197
1853
|
} catch {
|
|
1198
|
-
console.log(
|
|
1854
|
+
console.log(import_picocolors4.default.yellow(` Railway: erro ao criar projeto`));
|
|
1199
1855
|
}
|
|
1200
1856
|
}
|
|
1201
1857
|
} else {
|
|
1202
|
-
console.log(
|
|
1858
|
+
console.log(import_picocolors4.default.yellow(` Railway: not authenticated (railway login)`));
|
|
1203
1859
|
}
|
|
1204
1860
|
console.log();
|
|
1205
1861
|
}
|
|
@@ -1211,13 +1867,58 @@ async function create(args) {
|
|
|
1211
1867
|
process.exit(0);
|
|
1212
1868
|
}
|
|
1213
1869
|
await createProject(config);
|
|
1214
|
-
|
|
1870
|
+
const finalConfig = config;
|
|
1871
|
+
const isPublicTemplate = ["landing", "app", "turborepo"].includes(finalConfig.type);
|
|
1872
|
+
if (isPublicTemplate) {
|
|
1873
|
+
const s = Y2();
|
|
1874
|
+
s.start("Configura\xE7\xE3o de servi\xE7os...");
|
|
1875
|
+
const setupResult = await interactiveSetup(finalConfig.type);
|
|
1876
|
+
s.stop("Configura\xE7\xE3o conclu\xEDda");
|
|
1877
|
+
s.start("Gerando documenta\xE7\xE3o AI-friendly...");
|
|
1878
|
+
try {
|
|
1879
|
+
const generatorConfig = {
|
|
1880
|
+
name: finalConfig.name,
|
|
1881
|
+
type: finalConfig.type,
|
|
1882
|
+
description: finalConfig.githubDescription || `${finalConfig.type} criado com nimbus-cli`,
|
|
1883
|
+
stack: {
|
|
1884
|
+
framework: "Next.js 16 (App Router)",
|
|
1885
|
+
styling: "Tailwind CSS 4",
|
|
1886
|
+
components: "shadcn/ui (default)",
|
|
1887
|
+
forms: setupResult.features.contactForm ? "React Hook Form + Zod" : undefined,
|
|
1888
|
+
email: setupResult.features.contactForm ? "Resend" : undefined,
|
|
1889
|
+
auth: finalConfig.type === "app" ? "Better Auth" : undefined
|
|
1890
|
+
},
|
|
1891
|
+
features: {
|
|
1892
|
+
contactForm: setupResult.features.contactForm,
|
|
1893
|
+
newsletter: setupResult.features.newsletter,
|
|
1894
|
+
analytics: setupResult.features.analytics,
|
|
1895
|
+
auth: finalConfig.type === "app"
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
await generateAIFriendlyDocs(finalConfig.name, generatorConfig);
|
|
1899
|
+
s.stop("Documenta\xE7\xE3o AI-friendly gerada");
|
|
1900
|
+
} catch (error) {
|
|
1901
|
+
s.stop("Erro ao gerar documenta\xE7\xE3o AI-friendly");
|
|
1902
|
+
console.log(import_picocolors4.default.dim(" Voc\xEA pode gerar manualmente depois"));
|
|
1903
|
+
}
|
|
1904
|
+
if (!setupResult.skipSetup && (setupResult.apiKeys.resend || setupResult.apiKeys.ga)) {
|
|
1905
|
+
s.start("Gerando arquivos .env...");
|
|
1906
|
+
try {
|
|
1907
|
+
await generateEnvFile(finalConfig.name, setupResult.apiKeys, setupResult.features);
|
|
1908
|
+
s.stop("Arquivos .env gerados (.env e .env.example)");
|
|
1909
|
+
} catch (error) {
|
|
1910
|
+
s.stop("Erro ao gerar .env");
|
|
1911
|
+
console.log(import_picocolors4.default.dim(" Voc\xEA pode criar manualmente depois"));
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
Se(import_picocolors4.default.green("Project created successfully!"));
|
|
1215
1916
|
showNextSteps(config);
|
|
1216
1917
|
}
|
|
1217
1918
|
async function promptConfig(initialName, flags) {
|
|
1218
1919
|
const { isMember, user } = await isNimbuslabMember();
|
|
1219
1920
|
const greeting = user ? `Hello, ${user}!` : "Hello!";
|
|
1220
|
-
console.log(
|
|
1921
|
+
console.log(import_picocolors4.default.dim(` ${greeting}`));
|
|
1221
1922
|
console.log();
|
|
1222
1923
|
const name = await he({
|
|
1223
1924
|
message: "Project name:",
|
|
@@ -1276,12 +1977,12 @@ async function promptConfig(initialName, flags) {
|
|
|
1276
1977
|
return type;
|
|
1277
1978
|
const isPublicTemplate = ["landing", "app", "turborepo"].includes(type);
|
|
1278
1979
|
if (!isMember && !isPublicTemplate) {
|
|
1279
|
-
console.log(
|
|
1980
|
+
console.log(import_picocolors4.default.red("Error: Template available only for nimbuslab members"));
|
|
1280
1981
|
process.exit(1);
|
|
1281
1982
|
}
|
|
1282
1983
|
if (type === "nimbus-core") {
|
|
1283
1984
|
console.log();
|
|
1284
|
-
console.log(
|
|
1985
|
+
console.log(import_picocolors4.default.dim(" nimbus-core: Motor para projetos externos (stealth mode)"));
|
|
1285
1986
|
console.log();
|
|
1286
1987
|
const repoOption = await ve({
|
|
1287
1988
|
message: "Create repository for this project?",
|
|
@@ -1496,7 +2197,7 @@ async function promptConfig(initialName, flags) {
|
|
|
1496
2197
|
const configItems = infraOptions;
|
|
1497
2198
|
if (configItems.includes("urls")) {
|
|
1498
2199
|
console.log();
|
|
1499
|
-
console.log(
|
|
2200
|
+
console.log(import_picocolors4.default.dim(" Project URLs"));
|
|
1500
2201
|
const staging = await he({
|
|
1501
2202
|
message: "Staging URL:",
|
|
1502
2203
|
placeholder: defaultStagingUrl,
|
|
@@ -1516,7 +2217,7 @@ async function promptConfig(initialName, flags) {
|
|
|
1516
2217
|
}
|
|
1517
2218
|
if (configItems.includes("resend")) {
|
|
1518
2219
|
console.log();
|
|
1519
|
-
console.log(
|
|
2220
|
+
console.log(import_picocolors4.default.dim(" Resend (Email)"));
|
|
1520
2221
|
const resendKey = await he({
|
|
1521
2222
|
message: "RESEND_API_KEY:",
|
|
1522
2223
|
placeholder: "re_xxxxxxxxxxxx"
|
|
@@ -1545,16 +2246,16 @@ async function promptConfig(initialName, flags) {
|
|
|
1545
2246
|
const railwayAuthenticated = await isRailwayAuthenticated();
|
|
1546
2247
|
if (railwayAuthenticated) {
|
|
1547
2248
|
console.log();
|
|
1548
|
-
console.log(
|
|
2249
|
+
console.log(import_picocolors4.default.dim(" Railway"));
|
|
1549
2250
|
const projects = await listRailwayProjects();
|
|
1550
2251
|
if (type === "fast") {
|
|
1551
2252
|
const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
|
|
1552
2253
|
if (fastProject) {
|
|
1553
2254
|
railwayProject = fastProject;
|
|
1554
|
-
console.log(
|
|
2255
|
+
console.log(import_picocolors4.default.green(` Project: ${fastProject} (automatico)`));
|
|
1555
2256
|
} else {
|
|
1556
|
-
console.log(
|
|
1557
|
-
console.log(
|
|
2257
|
+
console.log(import_picocolors4.default.yellow(" Project 'Fast by nimbuslab' not found."));
|
|
2258
|
+
console.log(import_picocolors4.default.dim(" Configure manually in .env"));
|
|
1558
2259
|
}
|
|
1559
2260
|
} else {
|
|
1560
2261
|
const projectOptions = [
|
|
@@ -1570,26 +2271,26 @@ async function promptConfig(initialName, flags) {
|
|
|
1570
2271
|
return selectedProject;
|
|
1571
2272
|
if (selectedProject === "__new__") {
|
|
1572
2273
|
const projectNameForRailway = name;
|
|
1573
|
-
console.log(
|
|
2274
|
+
console.log(import_picocolors4.default.dim(` Creating project "${projectNameForRailway}" on Railway...`));
|
|
1574
2275
|
try {
|
|
1575
2276
|
const result = await $2`echo "" | railway init -n ${projectNameForRailway} -w nimbuslab --json`.text();
|
|
1576
2277
|
const newProject = JSON.parse(result);
|
|
1577
2278
|
railwayProject = newProject.name || projectNameForRailway;
|
|
1578
|
-
console.log(
|
|
1579
|
-
console.log(
|
|
2279
|
+
console.log(import_picocolors4.default.green(` Projeto "${railwayProject}" created successfully!`));
|
|
2280
|
+
console.log(import_picocolors4.default.dim(` ID: ${newProject.id || "N/A"}`));
|
|
1580
2281
|
} catch (error) {
|
|
1581
|
-
console.log(
|
|
1582
|
-
console.log(
|
|
2282
|
+
console.log(import_picocolors4.default.yellow(" Error creating project via CLI."));
|
|
2283
|
+
console.log(import_picocolors4.default.dim(" Create manually at: https://railway.app/new"));
|
|
1583
2284
|
}
|
|
1584
2285
|
} else if (selectedProject !== "__skip__") {
|
|
1585
2286
|
railwayProject = selectedProject;
|
|
1586
|
-
console.log(
|
|
2287
|
+
console.log(import_picocolors4.default.green(` Project selected: ${railwayProject}`));
|
|
1587
2288
|
}
|
|
1588
2289
|
}
|
|
1589
2290
|
} else {
|
|
1590
2291
|
console.log();
|
|
1591
|
-
console.log(
|
|
1592
|
-
console.log(
|
|
2292
|
+
console.log(import_picocolors4.default.yellow(" Railway: not authenticated (railway login)"));
|
|
2293
|
+
console.log(import_picocolors4.default.dim(" Configure manually in .env"));
|
|
1593
2294
|
}
|
|
1594
2295
|
}
|
|
1595
2296
|
const install = await ye({
|
|
@@ -1641,7 +2342,7 @@ async function createProject(config) {
|
|
|
1641
2342
|
} else {
|
|
1642
2343
|
await $2`gh repo clone ${templateRepo} ${config.name} -- --depth 1`.quiet();
|
|
1643
2344
|
}
|
|
1644
|
-
await rm(
|
|
2345
|
+
await rm(join2(config.name, ".git"), { recursive: true, force: true });
|
|
1645
2346
|
s.stop(`Template cloned`);
|
|
1646
2347
|
} catch (error) {
|
|
1647
2348
|
s.stop("Error cloning template");
|
|
@@ -1662,7 +2363,7 @@ async function createProject(config) {
|
|
|
1662
2363
|
s.stop(`Client repo cloned: workspace/${projectName}`);
|
|
1663
2364
|
} catch (error) {
|
|
1664
2365
|
s.stop("Error cloning client repo");
|
|
1665
|
-
console.log(
|
|
2366
|
+
console.log(import_picocolors4.default.dim(" You can clone manually: cd workspace && git clone <url>"));
|
|
1666
2367
|
}
|
|
1667
2368
|
}
|
|
1668
2369
|
if (config.type !== "nimbus-core") {
|
|
@@ -1751,7 +2452,7 @@ async function createProject(config) {
|
|
|
1751
2452
|
s.stop(`GitHub: ${repoName}`);
|
|
1752
2453
|
} catch (error) {
|
|
1753
2454
|
s.stop("Error creating GitHub repository");
|
|
1754
|
-
console.log(
|
|
2455
|
+
console.log(import_picocolors4.default.dim(" You can create manually with: gh repo create"));
|
|
1755
2456
|
}
|
|
1756
2457
|
}
|
|
1757
2458
|
}
|
|
@@ -1762,13 +2463,13 @@ async function createProject(config) {
|
|
|
1762
2463
|
s.stop(`Railway linkado: ${config.railwayProject}`);
|
|
1763
2464
|
} catch (error) {
|
|
1764
2465
|
s.stop("Error linking Railway");
|
|
1765
|
-
console.log(
|
|
2466
|
+
console.log(import_picocolors4.default.dim(" Run manually: railway link"));
|
|
1766
2467
|
}
|
|
1767
2468
|
}
|
|
1768
2469
|
if (config.resendApiKey || config.stagingUrl) {
|
|
1769
2470
|
s.start("Gerando arquivo .env...");
|
|
1770
2471
|
try {
|
|
1771
|
-
const envContent =
|
|
2472
|
+
const envContent = generateEnvFile2(config);
|
|
1772
2473
|
await Bun.write(`${config.name}/.env`, envContent);
|
|
1773
2474
|
s.stop("Arquivo .env criado");
|
|
1774
2475
|
} catch (error) {
|
|
@@ -1785,7 +2486,7 @@ async function createProject(config) {
|
|
|
1785
2486
|
}
|
|
1786
2487
|
}
|
|
1787
2488
|
}
|
|
1788
|
-
function
|
|
2489
|
+
function generateEnvFile2(config) {
|
|
1789
2490
|
const lines = [
|
|
1790
2491
|
"# Gerado automaticamente pelo nimbus-cli",
|
|
1791
2492
|
"# Nao commitar este arquivo!",
|
|
@@ -1828,58 +2529,58 @@ function showNextSteps(config) {
|
|
|
1828
2529
|
const isPublicTemplate = ["landing", "app", "turborepo"].includes(config.type);
|
|
1829
2530
|
const needsSetup = config.type === "app";
|
|
1830
2531
|
console.log();
|
|
1831
|
-
console.log(
|
|
2532
|
+
console.log(import_picocolors4.default.bold("Next steps:"));
|
|
1832
2533
|
console.log();
|
|
1833
|
-
console.log(` ${
|
|
2534
|
+
console.log(` ${import_picocolors4.default.cyan("cd")} ${config.name}`);
|
|
1834
2535
|
if (config.type === "nimbus-core") {
|
|
1835
2536
|
console.log();
|
|
1836
|
-
console.log(
|
|
2537
|
+
console.log(import_picocolors4.default.dim(" nimbus-core: Motor para projetos externos"));
|
|
1837
2538
|
console.log();
|
|
1838
|
-
console.log(
|
|
1839
|
-
console.log(` ${
|
|
2539
|
+
console.log(import_picocolors4.default.dim(" Para usar a Lola:"));
|
|
2540
|
+
console.log(` ${import_picocolors4.default.cyan("lola")}`);
|
|
1840
2541
|
console.log();
|
|
1841
|
-
console.log(
|
|
2542
|
+
console.log(import_picocolors4.default.yellow(" STEALTH MODE: Commits sem mencao a nimbuslab/Lola/IA"));
|
|
1842
2543
|
console.log();
|
|
1843
2544
|
if (config.github) {
|
|
1844
2545
|
const repoUrl = `https://github.com/nimbuslab/${config.name}`;
|
|
1845
|
-
console.log(
|
|
2546
|
+
console.log(import_picocolors4.default.green(` GitHub (private): ${repoUrl}`));
|
|
1846
2547
|
console.log();
|
|
1847
2548
|
}
|
|
1848
|
-
console.log(
|
|
2549
|
+
console.log(import_picocolors4.default.dim(" Docs: See README.md for full instructions"));
|
|
1849
2550
|
console.log();
|
|
1850
2551
|
return;
|
|
1851
2552
|
}
|
|
1852
2553
|
if (!config.install) {
|
|
1853
|
-
console.log(` ${
|
|
2554
|
+
console.log(` ${import_picocolors4.default.cyan("bun")} install`);
|
|
1854
2555
|
}
|
|
1855
2556
|
if (!isPublicTemplate || needsSetup) {
|
|
1856
|
-
console.log(` ${
|
|
2557
|
+
console.log(` ${import_picocolors4.default.cyan("bun")} setup`);
|
|
1857
2558
|
}
|
|
1858
|
-
console.log(` ${
|
|
2559
|
+
console.log(` ${import_picocolors4.default.cyan("bun")} dev`);
|
|
1859
2560
|
console.log();
|
|
1860
2561
|
if (needsSetup && isPublicTemplate) {
|
|
1861
|
-
console.log(
|
|
1862
|
-
console.log(
|
|
1863
|
-
console.log(
|
|
1864
|
-
console.log(
|
|
2562
|
+
console.log(import_picocolors4.default.dim(" bun setup will:"));
|
|
2563
|
+
console.log(import_picocolors4.default.dim(" - Start PostgreSQL with Docker"));
|
|
2564
|
+
console.log(import_picocolors4.default.dim(" - Run database migrations"));
|
|
2565
|
+
console.log(import_picocolors4.default.dim(" - Create demo user (demo@example.com / demo1234)"));
|
|
1865
2566
|
console.log();
|
|
1866
2567
|
}
|
|
1867
2568
|
if (config.git) {
|
|
1868
|
-
console.log(
|
|
2569
|
+
console.log(import_picocolors4.default.dim(" Git: main -> staging -> develop (current branch)"));
|
|
1869
2570
|
if (config.github) {
|
|
1870
2571
|
const repoUrl = config.githubOrg ? `https://github.com/${config.githubOrg}/${config.name}` : `https://github.com/${config.name}`;
|
|
1871
|
-
console.log(
|
|
2572
|
+
console.log(import_picocolors4.default.green(` GitHub: ${repoUrl}`));
|
|
1872
2573
|
}
|
|
1873
2574
|
console.log();
|
|
1874
2575
|
}
|
|
1875
2576
|
if (isPublicTemplate) {
|
|
1876
2577
|
if (config.theme !== "dark") {
|
|
1877
|
-
console.log(
|
|
2578
|
+
console.log(import_picocolors4.default.dim(` Theme: ${config.theme}`));
|
|
1878
2579
|
}
|
|
1879
2580
|
if (config.aiAssistant) {
|
|
1880
2581
|
const aiConfig = AI_CONFIGS[config.aiAssistant];
|
|
1881
2582
|
if (aiConfig) {
|
|
1882
|
-
console.log(
|
|
2583
|
+
console.log(import_picocolors4.default.dim(` AI config: ${aiConfig.filename}`));
|
|
1883
2584
|
}
|
|
1884
2585
|
}
|
|
1885
2586
|
if (config.theme !== "dark" || config.aiAssistant) {
|
|
@@ -1887,56 +2588,56 @@ function showNextSteps(config) {
|
|
|
1887
2588
|
}
|
|
1888
2589
|
}
|
|
1889
2590
|
if (config.type === "fast+") {
|
|
1890
|
-
console.log(
|
|
1891
|
-
console.log(
|
|
1892
|
-
console.log(
|
|
1893
|
-
console.log(
|
|
2591
|
+
console.log(import_picocolors4.default.dim(" bun setup will:"));
|
|
2592
|
+
console.log(import_picocolors4.default.dim(" - Start PostgreSQL with Docker"));
|
|
2593
|
+
console.log(import_picocolors4.default.dim(" - Run database migrations"));
|
|
2594
|
+
console.log(import_picocolors4.default.dim(" - Create demo user (demo@example.com / demo1234)"));
|
|
1894
2595
|
console.log();
|
|
1895
|
-
console.log(
|
|
2596
|
+
console.log(import_picocolors4.default.dim(" Tip: Configure DATABASE_URL and BETTER_AUTH_SECRET in .env"));
|
|
1896
2597
|
if (!config.railwayToken) {
|
|
1897
|
-
console.log(
|
|
2598
|
+
console.log(import_picocolors4.default.dim(" Railway: Create a project at https://railway.app/new"));
|
|
1898
2599
|
}
|
|
1899
2600
|
console.log();
|
|
1900
2601
|
}
|
|
1901
2602
|
if (!isPublicTemplate) {
|
|
1902
2603
|
if (config.resendApiKey || config.stagingUrl) {
|
|
1903
|
-
console.log(
|
|
2604
|
+
console.log(import_picocolors4.default.green(" .env configured!"));
|
|
1904
2605
|
console.log();
|
|
1905
2606
|
} else {
|
|
1906
|
-
console.log(
|
|
2607
|
+
console.log(import_picocolors4.default.yellow(" Tip: Configure .env manually or use 'bun setup'."));
|
|
1907
2608
|
console.log();
|
|
1908
2609
|
}
|
|
1909
2610
|
}
|
|
1910
2611
|
if (isPublicTemplate) {
|
|
1911
|
-
console.log(
|
|
1912
|
-
console.log(
|
|
2612
|
+
console.log(import_picocolors4.default.dim(" Open source template (MIT) by nimbuslab"));
|
|
2613
|
+
console.log(import_picocolors4.default.dim(` https://github.com/nimbuslab/create-next-${config.type === "turborepo" ? "turborepo" : config.type}`));
|
|
1913
2614
|
} else {
|
|
1914
|
-
console.log(
|
|
2615
|
+
console.log(import_picocolors4.default.dim(" https://github.com/nimbuslab-templates"));
|
|
1915
2616
|
}
|
|
1916
2617
|
console.log();
|
|
1917
2618
|
}
|
|
1918
2619
|
|
|
1919
2620
|
// src/commands/analyze.ts
|
|
1920
|
-
var
|
|
2621
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
1921
2622
|
import { existsSync, readFileSync } from "fs";
|
|
1922
|
-
import { join as
|
|
2623
|
+
import { join as join3 } from "path";
|
|
1923
2624
|
function detectPackageManager(dir) {
|
|
1924
|
-
if (existsSync(
|
|
2625
|
+
if (existsSync(join3(dir, "bun.lockb")))
|
|
1925
2626
|
return "bun";
|
|
1926
|
-
if (existsSync(
|
|
2627
|
+
if (existsSync(join3(dir, "pnpm-lock.yaml")))
|
|
1927
2628
|
return "pnpm";
|
|
1928
|
-
if (existsSync(
|
|
2629
|
+
if (existsSync(join3(dir, "yarn.lock")))
|
|
1929
2630
|
return "yarn";
|
|
1930
|
-
if (existsSync(
|
|
2631
|
+
if (existsSync(join3(dir, "package-lock.json")))
|
|
1931
2632
|
return "npm";
|
|
1932
2633
|
return "unknown";
|
|
1933
2634
|
}
|
|
1934
2635
|
function detectMonorepo(dir, pkg) {
|
|
1935
|
-
if (existsSync(
|
|
2636
|
+
if (existsSync(join3(dir, "turbo.json")))
|
|
1936
2637
|
return "turborepo";
|
|
1937
|
-
if (existsSync(
|
|
2638
|
+
if (existsSync(join3(dir, "nx.json")))
|
|
1938
2639
|
return "nx";
|
|
1939
|
-
if (existsSync(
|
|
2640
|
+
if (existsSync(join3(dir, "lerna.json")))
|
|
1940
2641
|
return "lerna";
|
|
1941
2642
|
if (pkg.workspaces)
|
|
1942
2643
|
return "workspaces";
|
|
@@ -2041,14 +2742,14 @@ function generateRecommendations(result) {
|
|
|
2041
2742
|
}
|
|
2042
2743
|
async function analyze(args) {
|
|
2043
2744
|
const targetDir = args[0] || ".";
|
|
2044
|
-
const absoluteDir = targetDir.startsWith("/") ? targetDir :
|
|
2745
|
+
const absoluteDir = targetDir.startsWith("/") ? targetDir : join3(process.cwd(), targetDir);
|
|
2045
2746
|
console.log();
|
|
2046
|
-
console.log(
|
|
2747
|
+
console.log(import_picocolors5.default.cyan(" Analisando projeto..."));
|
|
2047
2748
|
console.log();
|
|
2048
|
-
const pkgPath =
|
|
2749
|
+
const pkgPath = join3(absoluteDir, "package.json");
|
|
2049
2750
|
if (!existsSync(pkgPath)) {
|
|
2050
|
-
console.log(
|
|
2051
|
-
console.log(
|
|
2751
|
+
console.log(import_picocolors5.default.red(" Erro: package.json nao encontrado"));
|
|
2752
|
+
console.log(import_picocolors5.default.dim(` Diretorio: ${absoluteDir}`));
|
|
2052
2753
|
process.exit(1);
|
|
2053
2754
|
}
|
|
2054
2755
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
@@ -2065,42 +2766,42 @@ async function analyze(args) {
|
|
|
2065
2766
|
monorepo: detectMonorepo(absoluteDir, pkg),
|
|
2066
2767
|
auth: detectAuth(deps),
|
|
2067
2768
|
database: detectDatabase(deps),
|
|
2068
|
-
typescript: existsSync(
|
|
2769
|
+
typescript: existsSync(join3(absoluteDir, "tsconfig.json")),
|
|
2069
2770
|
dependencies: deps,
|
|
2070
2771
|
devDependencies: devDeps,
|
|
2071
2772
|
recommendations: []
|
|
2072
2773
|
};
|
|
2073
2774
|
result.recommendations = generateRecommendations(result);
|
|
2074
|
-
console.log(
|
|
2775
|
+
console.log(import_picocolors5.default.bold(" Projeto: ") + import_picocolors5.default.cyan(result.name) + import_picocolors5.default.dim(` v${result.version}`));
|
|
2075
2776
|
console.log();
|
|
2076
|
-
console.log(
|
|
2077
|
-
console.log(` Framework: ${result.framework ?
|
|
2078
|
-
console.log(` Styling: ${result.styling.map((s) =>
|
|
2079
|
-
console.log(` Package Manager: ${result.packageManager === "bun" ?
|
|
2080
|
-
console.log(` TypeScript: ${result.typescript ?
|
|
2081
|
-
console.log(` Monorepo: ${result.monorepo ?
|
|
2082
|
-
console.log(` Auth: ${result.auth ?
|
|
2083
|
-
console.log(` Database: ${result.database ?
|
|
2777
|
+
console.log(import_picocolors5.default.bold(" Stack Detectada:"));
|
|
2778
|
+
console.log(` Framework: ${result.framework ? import_picocolors5.default.green(result.framework + "@" + result.frameworkVersion) : import_picocolors5.default.dim("nenhum")}`);
|
|
2779
|
+
console.log(` Styling: ${result.styling.map((s) => import_picocolors5.default.green(s)).join(", ")}`);
|
|
2780
|
+
console.log(` Package Manager: ${result.packageManager === "bun" ? import_picocolors5.default.green(result.packageManager) : import_picocolors5.default.yellow(result.packageManager)}`);
|
|
2781
|
+
console.log(` TypeScript: ${result.typescript ? import_picocolors5.default.green("sim") : import_picocolors5.default.dim("nao")}`);
|
|
2782
|
+
console.log(` Monorepo: ${result.monorepo ? import_picocolors5.default.green(result.monorepo) : import_picocolors5.default.dim("nao")}`);
|
|
2783
|
+
console.log(` Auth: ${result.auth ? import_picocolors5.default.green(result.auth) : import_picocolors5.default.dim("nenhum")}`);
|
|
2784
|
+
console.log(` Database: ${result.database ? import_picocolors5.default.green(result.database) : import_picocolors5.default.dim("nenhum")}`);
|
|
2084
2785
|
console.log();
|
|
2085
2786
|
if (result.recommendations.length > 0) {
|
|
2086
|
-
console.log(
|
|
2787
|
+
console.log(import_picocolors5.default.bold(" Recomendacoes:"));
|
|
2087
2788
|
result.recommendations.forEach((rec, i) => {
|
|
2088
|
-
console.log(
|
|
2789
|
+
console.log(import_picocolors5.default.yellow(` ${i + 1}. ${rec}`));
|
|
2089
2790
|
});
|
|
2090
2791
|
console.log();
|
|
2091
2792
|
} else {
|
|
2092
|
-
console.log(
|
|
2793
|
+
console.log(import_picocolors5.default.green(" Projeto ja esta na stack recomendada!"));
|
|
2093
2794
|
console.log();
|
|
2094
2795
|
}
|
|
2095
2796
|
if (args.includes("--json")) {
|
|
2096
|
-
console.log(
|
|
2797
|
+
console.log(import_picocolors5.default.dim(" JSON:"));
|
|
2097
2798
|
console.log(JSON.stringify(result, null, 2));
|
|
2098
2799
|
}
|
|
2099
2800
|
return result;
|
|
2100
2801
|
}
|
|
2101
2802
|
|
|
2102
2803
|
// src/commands/upgrade.ts
|
|
2103
|
-
var
|
|
2804
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
2104
2805
|
var UPGRADE_PLANS = {
|
|
2105
2806
|
next: (current) => {
|
|
2106
2807
|
const major = parseInt(current.replace(/[^0-9]/g, "").slice(0, 2));
|
|
@@ -2217,10 +2918,10 @@ async function upgrade(args) {
|
|
|
2217
2918
|
const target = args.find((a) => !a.startsWith("-"));
|
|
2218
2919
|
console.log();
|
|
2219
2920
|
if (showPlan || !target) {
|
|
2220
|
-
console.log(
|
|
2921
|
+
console.log(import_picocolors6.default.cyan(" Analisando projeto para plano de upgrade..."));
|
|
2221
2922
|
console.log();
|
|
2222
2923
|
const analysis = await analyze([".", "--quiet"]);
|
|
2223
|
-
console.log(
|
|
2924
|
+
console.log(import_picocolors6.default.bold(" Upgrades Disponiveis:"));
|
|
2224
2925
|
console.log();
|
|
2225
2926
|
let hasUpgrades = false;
|
|
2226
2927
|
if (analysis.frameworkVersion && analysis.framework === "nextjs") {
|
|
@@ -2275,44 +2976,44 @@ async function upgrade(args) {
|
|
|
2275
2976
|
}
|
|
2276
2977
|
}
|
|
2277
2978
|
if (!hasUpgrades) {
|
|
2278
|
-
console.log(
|
|
2979
|
+
console.log(import_picocolors6.default.green(" Projeto ja esta atualizado!"));
|
|
2279
2980
|
}
|
|
2280
2981
|
console.log();
|
|
2281
|
-
console.log(
|
|
2282
|
-
console.log(
|
|
2283
|
-
console.log(
|
|
2284
|
-
console.log(
|
|
2982
|
+
console.log(import_picocolors6.default.dim(" Para executar um upgrade especifico:"));
|
|
2983
|
+
console.log(import_picocolors6.default.dim(" nimbus upgrade next"));
|
|
2984
|
+
console.log(import_picocolors6.default.dim(" nimbus upgrade tailwind"));
|
|
2985
|
+
console.log(import_picocolors6.default.dim(" nimbus upgrade bun"));
|
|
2285
2986
|
console.log();
|
|
2286
2987
|
return;
|
|
2287
2988
|
}
|
|
2288
|
-
console.log(
|
|
2289
|
-
console.log(
|
|
2989
|
+
console.log(import_picocolors6.default.yellow(` Upgrade ${target} ainda nao implementado.`));
|
|
2990
|
+
console.log(import_picocolors6.default.dim(" Por enquanto, siga os passos do --plan manualmente."));
|
|
2290
2991
|
console.log();
|
|
2291
2992
|
}
|
|
2292
2993
|
function printUpgradePlan(name, plan) {
|
|
2293
2994
|
const complexityColor = {
|
|
2294
|
-
low:
|
|
2295
|
-
medium:
|
|
2296
|
-
high:
|
|
2995
|
+
low: import_picocolors6.default.green,
|
|
2996
|
+
medium: import_picocolors6.default.yellow,
|
|
2997
|
+
high: import_picocolors6.default.red
|
|
2297
2998
|
};
|
|
2298
|
-
console.log(` ${
|
|
2299
|
-
console.log(` ${
|
|
2300
|
-
console.log(` ${
|
|
2999
|
+
console.log(` ${import_picocolors6.default.bold(name)}`);
|
|
3000
|
+
console.log(` ${import_picocolors6.default.dim("Atual:")} ${plan.current} ${import_picocolors6.default.dim("->")} ${import_picocolors6.default.cyan(plan.target)}`);
|
|
3001
|
+
console.log(` ${import_picocolors6.default.dim("Complexidade:")} ${complexityColor[plan.complexity](plan.complexity)}`);
|
|
2301
3002
|
console.log();
|
|
2302
|
-
console.log(` ${
|
|
3003
|
+
console.log(` ${import_picocolors6.default.dim("Breaking Changes:")}`);
|
|
2303
3004
|
plan.breakingChanges.forEach((bc) => {
|
|
2304
|
-
console.log(` ${
|
|
3005
|
+
console.log(` ${import_picocolors6.default.yellow("!")} ${bc}`);
|
|
2305
3006
|
});
|
|
2306
3007
|
console.log();
|
|
2307
|
-
console.log(` ${
|
|
3008
|
+
console.log(` ${import_picocolors6.default.dim("Passos:")}`);
|
|
2308
3009
|
plan.steps.forEach((step, i) => {
|
|
2309
|
-
console.log(` ${
|
|
3010
|
+
console.log(` ${import_picocolors6.default.dim(`${i + 1}.`)} ${step}`);
|
|
2310
3011
|
});
|
|
2311
3012
|
console.log();
|
|
2312
3013
|
}
|
|
2313
3014
|
|
|
2314
3015
|
// src/commands/update.ts
|
|
2315
|
-
var
|
|
3016
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
2316
3017
|
import { execSync, spawnSync } from "child_process";
|
|
2317
3018
|
var PACKAGE_NAME = "@nimbuslab/cli";
|
|
2318
3019
|
function hasBunInstall() {
|
|
@@ -2448,7 +3149,7 @@ async function update(args) {
|
|
|
2448
3149
|
const filteredArgs = args.filter((a) => a !== "--force" && a !== "-f");
|
|
2449
3150
|
const flag = filteredArgs[0];
|
|
2450
3151
|
if (flag === "--list" || flag === "-l") {
|
|
2451
|
-
Ie(
|
|
3152
|
+
Ie(import_picocolors7.default.cyan("Versoes disponiveis"));
|
|
2452
3153
|
const spinner2 = Y2();
|
|
2453
3154
|
spinner2.start("Buscando versoes...");
|
|
2454
3155
|
const versions = await getAvailableVersions();
|
|
@@ -2460,29 +3161,29 @@ async function update(args) {
|
|
|
2460
3161
|
const current = getCurrentVersion();
|
|
2461
3162
|
const pm2 = detectPackageManager2();
|
|
2462
3163
|
console.log();
|
|
2463
|
-
console.log(
|
|
3164
|
+
console.log(import_picocolors7.default.bold("Ultimas 10 versoes:"));
|
|
2464
3165
|
versions.slice(0, 10).forEach((v2, i) => {
|
|
2465
3166
|
const isCurrent = v2 === current;
|
|
2466
|
-
const prefix = isCurrent ?
|
|
2467
|
-
const suffix = isCurrent ?
|
|
2468
|
-
const isLatest = i === 0 ?
|
|
3167
|
+
const prefix = isCurrent ? import_picocolors7.default.green("-> ") : " ";
|
|
3168
|
+
const suffix = isCurrent ? import_picocolors7.default.dim(" (instalada)") : "";
|
|
3169
|
+
const isLatest = i === 0 ? import_picocolors7.default.yellow(" (latest)") : "";
|
|
2469
3170
|
console.log(`${prefix}${v2}${suffix}${isLatest}`);
|
|
2470
3171
|
});
|
|
2471
3172
|
console.log();
|
|
2472
|
-
console.log(
|
|
2473
|
-
console.log(
|
|
2474
|
-
console.log(
|
|
2475
|
-
console.log(
|
|
3173
|
+
console.log(import_picocolors7.default.dim(`Total: ${versions.length} versoes`));
|
|
3174
|
+
console.log(import_picocolors7.default.dim(`Package manager detectado: ${pm2 === "unknown" ? "nenhum" : pm2}`));
|
|
3175
|
+
console.log(import_picocolors7.default.dim(`Instalar versao especifica: nimbus update <versao>`));
|
|
3176
|
+
console.log(import_picocolors7.default.dim(`Forcar reinstalacao: nimbus update --force`));
|
|
2476
3177
|
return;
|
|
2477
3178
|
}
|
|
2478
3179
|
const targetVersion = flag || "latest";
|
|
2479
3180
|
const isSpecificVersion = flag && flag !== "latest" && !flag.startsWith("-");
|
|
2480
|
-
Ie(
|
|
3181
|
+
Ie(import_picocolors7.default.cyan(`Atualizando ${PACKAGE_NAME}`));
|
|
2481
3182
|
const spinner = Y2();
|
|
2482
3183
|
spinner.start("Verificando instalacoes...");
|
|
2483
3184
|
const cleanup = cleanupDuplicateInstalls();
|
|
2484
3185
|
if (cleanup.cleaned) {
|
|
2485
|
-
spinner.stop(
|
|
3186
|
+
spinner.stop(import_picocolors7.default.yellow(cleanup.message));
|
|
2486
3187
|
} else {
|
|
2487
3188
|
spinner.stop("OK");
|
|
2488
3189
|
}
|
|
@@ -2500,7 +3201,7 @@ async function update(args) {
|
|
|
2500
3201
|
spinner.stop(`Ultima versao: ${latestVersion || "desconhecida"}`);
|
|
2501
3202
|
if (!forceFlag && latestVersion && latestVersion === currentVersion) {
|
|
2502
3203
|
M2.success("Voce ja esta na ultima versao!");
|
|
2503
|
-
console.log(
|
|
3204
|
+
console.log(import_picocolors7.default.dim(" Use --force para reinstalar"));
|
|
2504
3205
|
return;
|
|
2505
3206
|
}
|
|
2506
3207
|
}
|
|
@@ -2538,37 +3239,37 @@ async function update(args) {
|
|
|
2538
3239
|
const isWindows = process.platform === "win32";
|
|
2539
3240
|
if (isWindows) {
|
|
2540
3241
|
console.log();
|
|
2541
|
-
console.log(
|
|
3242
|
+
console.log(import_picocolors7.default.yellow(" Reinicie o terminal para aplicar a atualizacao."));
|
|
2542
3243
|
} else if (isUsingFnm()) {
|
|
2543
3244
|
console.log();
|
|
2544
|
-
console.log(
|
|
2545
|
-
console.log(
|
|
2546
|
-
console.log(
|
|
3245
|
+
console.log(import_picocolors7.default.yellow(" fnm detectado - execute para aplicar:"));
|
|
3246
|
+
console.log(import_picocolors7.default.cyan(" hash -r"));
|
|
3247
|
+
console.log(import_picocolors7.default.dim(" Ou abra um novo terminal."));
|
|
2547
3248
|
}
|
|
2548
|
-
Se(
|
|
3249
|
+
Se(import_picocolors7.default.green("Pronto!"));
|
|
2549
3250
|
} catch (error) {
|
|
2550
3251
|
spinner.stop("Erro na atualizacao");
|
|
2551
3252
|
const err = error;
|
|
2552
3253
|
M2.error("Falha ao atualizar");
|
|
2553
3254
|
if (err.stderr) {
|
|
2554
|
-
console.log(
|
|
3255
|
+
console.log(import_picocolors7.default.dim(err.stderr));
|
|
2555
3256
|
}
|
|
2556
3257
|
console.log();
|
|
2557
|
-
console.log(
|
|
3258
|
+
console.log(import_picocolors7.default.yellow("Tente manualmente:"));
|
|
2558
3259
|
if (pm === "bun") {
|
|
2559
|
-
console.log(
|
|
3260
|
+
console.log(import_picocolors7.default.cyan(` bun add -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
|
|
2560
3261
|
} else {
|
|
2561
|
-
console.log(
|
|
3262
|
+
console.log(import_picocolors7.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
|
|
2562
3263
|
}
|
|
2563
3264
|
}
|
|
2564
3265
|
}
|
|
2565
3266
|
|
|
2566
3267
|
// src/commands/setup-node.ts
|
|
2567
|
-
var
|
|
3268
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
2568
3269
|
import { execSync as execSync2, spawnSync as spawnSync2 } from "child_process";
|
|
2569
3270
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
2570
3271
|
import { homedir } from "os";
|
|
2571
|
-
import { join as
|
|
3272
|
+
import { join as join4 } from "path";
|
|
2572
3273
|
var HOME = homedir();
|
|
2573
3274
|
var IS_WINDOWS = process.platform === "win32";
|
|
2574
3275
|
var CHECK_CMD = IS_WINDOWS ? "where" : "which";
|
|
@@ -2576,23 +3277,23 @@ function detectFnm() {
|
|
|
2576
3277
|
const result = { name: "fnm", installed: false };
|
|
2577
3278
|
const check = spawnSync2(CHECK_CMD, ["fnm"], { encoding: "utf-8", shell: true });
|
|
2578
3279
|
const fnmLocations = IS_WINDOWS ? [
|
|
2579
|
-
|
|
2580
|
-
|
|
3280
|
+
join4(HOME, "scoop", "shims", "fnm.exe"),
|
|
3281
|
+
join4(HOME, "scoop", "apps", "fnm", "current", "fnm.exe"),
|
|
2581
3282
|
"C:\\ProgramData\\chocolatey\\bin\\fnm.exe",
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
3283
|
+
join4(HOME, ".cargo", "bin", "fnm.exe"),
|
|
3284
|
+
join4(HOME, ".fnm", "fnm.exe"),
|
|
3285
|
+
join4(HOME, "AppData", "Local", "fnm", "fnm.exe"),
|
|
3286
|
+
join4(HOME, "AppData", "Roaming", "fnm", "fnm.exe"),
|
|
3287
|
+
join4(HOME, "AppData", "Local", "Microsoft", "fnm", "fnm.exe"),
|
|
3288
|
+
join4(HOME, "AppData", "Roaming", "fnm"),
|
|
3289
|
+
join4(HOME, "AppData", "Local", "fnm_multishells")
|
|
2589
3290
|
] : [
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
3291
|
+
join4(HOME, ".local", "share", "fnm", "fnm"),
|
|
3292
|
+
join4(HOME, ".fnm", "fnm"),
|
|
3293
|
+
join4(HOME, ".local", "bin", "fnm"),
|
|
2593
3294
|
"/opt/homebrew/bin/fnm",
|
|
2594
3295
|
"/usr/local/bin/fnm",
|
|
2595
|
-
|
|
3296
|
+
join4(HOME, ".cargo", "bin", "fnm")
|
|
2596
3297
|
];
|
|
2597
3298
|
let fnmPath = null;
|
|
2598
3299
|
if (check.status === 0) {
|
|
@@ -2612,7 +3313,7 @@ function detectFnm() {
|
|
|
2612
3313
|
}
|
|
2613
3314
|
}
|
|
2614
3315
|
if (!fnmPath && IS_WINDOWS) {
|
|
2615
|
-
const fnmMultishells =
|
|
3316
|
+
const fnmMultishells = join4(HOME, "AppData", "Local", "fnm_multishells");
|
|
2616
3317
|
if (existsSync2(fnmMultishells)) {
|
|
2617
3318
|
fnmPath = fnmMultishells;
|
|
2618
3319
|
}
|
|
@@ -2628,9 +3329,9 @@ function detectFnm() {
|
|
|
2628
3329
|
} catch {}
|
|
2629
3330
|
result.configFiles = [];
|
|
2630
3331
|
if (IS_WINDOWS) {
|
|
2631
|
-
const ps5Profile =
|
|
2632
|
-
const ps7Profile =
|
|
2633
|
-
const psProfile =
|
|
3332
|
+
const ps5Profile = join4(HOME, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
|
|
3333
|
+
const ps7Profile = join4(HOME, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
|
|
3334
|
+
const psProfile = join4(HOME, "Documents", "PowerShell", "profile.ps1");
|
|
2634
3335
|
if (existsSync2(ps5Profile))
|
|
2635
3336
|
result.configFiles.push(ps5Profile);
|
|
2636
3337
|
if (existsSync2(ps7Profile))
|
|
@@ -2639,12 +3340,12 @@ function detectFnm() {
|
|
|
2639
3340
|
result.configFiles.push(psProfile);
|
|
2640
3341
|
} else {
|
|
2641
3342
|
const configs = [
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
3343
|
+
join4(HOME, ".bashrc"),
|
|
3344
|
+
join4(HOME, ".bash_profile"),
|
|
3345
|
+
join4(HOME, ".profile"),
|
|
3346
|
+
join4(HOME, ".zshrc"),
|
|
3347
|
+
join4(HOME, ".zprofile"),
|
|
3348
|
+
join4(HOME, ".config", "fish", "config.fish")
|
|
2648
3349
|
];
|
|
2649
3350
|
for (const cfg of configs) {
|
|
2650
3351
|
if (existsSync2(cfg))
|
|
@@ -2658,10 +3359,10 @@ function detectNvm() {
|
|
|
2658
3359
|
if (IS_WINDOWS) {
|
|
2659
3360
|
const check = spawnSync2(CHECK_CMD, ["nvm"], { encoding: "utf-8", shell: true });
|
|
2660
3361
|
const nvmWinLocations = [
|
|
2661
|
-
|
|
3362
|
+
join4(HOME, "AppData", "Roaming", "nvm", "nvm.exe"),
|
|
2662
3363
|
"C:\\Program Files\\nvm\\nvm.exe",
|
|
2663
3364
|
"C:\\ProgramData\\nvm\\nvm.exe",
|
|
2664
|
-
|
|
3365
|
+
join4(HOME, "nvm", "nvm.exe")
|
|
2665
3366
|
];
|
|
2666
3367
|
let nvmPath = null;
|
|
2667
3368
|
if (check.status === 0) {
|
|
@@ -2685,28 +3386,28 @@ function detectNvm() {
|
|
|
2685
3386
|
} catch {}
|
|
2686
3387
|
result.configFiles = [];
|
|
2687
3388
|
const configs = [
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
3389
|
+
join4(HOME, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1"),
|
|
3390
|
+
join4(HOME, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1"),
|
|
3391
|
+
join4(HOME, "Documents", "PowerShell", "profile.ps1")
|
|
2691
3392
|
];
|
|
2692
3393
|
for (const cfg of configs) {
|
|
2693
3394
|
if (existsSync2(cfg))
|
|
2694
3395
|
result.configFiles.push(cfg);
|
|
2695
3396
|
}
|
|
2696
3397
|
} else {
|
|
2697
|
-
const nvmDir = process.env.NVM_DIR ||
|
|
3398
|
+
const nvmDir = process.env.NVM_DIR || join4(HOME, ".nvm");
|
|
2698
3399
|
if (!existsSync2(nvmDir))
|
|
2699
3400
|
return result;
|
|
2700
3401
|
result.installed = true;
|
|
2701
3402
|
result.path = nvmDir;
|
|
2702
3403
|
result.configFiles = [];
|
|
2703
3404
|
const configs = [
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
3405
|
+
join4(HOME, ".bashrc"),
|
|
3406
|
+
join4(HOME, ".bash_profile"),
|
|
3407
|
+
join4(HOME, ".profile"),
|
|
3408
|
+
join4(HOME, ".zshrc"),
|
|
3409
|
+
join4(HOME, ".zprofile"),
|
|
3410
|
+
join4(HOME, ".config", "fish", "config.fish")
|
|
2710
3411
|
];
|
|
2711
3412
|
for (const cfg of configs) {
|
|
2712
3413
|
if (existsSync2(cfg))
|
|
@@ -2833,7 +3534,7 @@ async function removeFnm(fnm) {
|
|
|
2833
3534
|
const scoopCheck = spawnSync2("scoop", ["list"], { encoding: "utf-8", shell: true });
|
|
2834
3535
|
if (scoopCheck.stdout?.includes("fnm")) {
|
|
2835
3536
|
execSync2("scoop uninstall fnm", { stdio: "pipe" });
|
|
2836
|
-
console.log(
|
|
3537
|
+
console.log(import_picocolors8.default.dim(" Removido via Scoop"));
|
|
2837
3538
|
removed = true;
|
|
2838
3539
|
}
|
|
2839
3540
|
} catch {}
|
|
@@ -2842,7 +3543,7 @@ async function removeFnm(fnm) {
|
|
|
2842
3543
|
const chocoCheck = spawnSync2("choco", ["list", "--local-only"], { encoding: "utf-8", shell: true });
|
|
2843
3544
|
if (chocoCheck.stdout?.includes("fnm")) {
|
|
2844
3545
|
execSync2("choco uninstall fnm -y", { stdio: "pipe" });
|
|
2845
|
-
console.log(
|
|
3546
|
+
console.log(import_picocolors8.default.dim(" Removido via Chocolatey"));
|
|
2846
3547
|
removed = true;
|
|
2847
3548
|
}
|
|
2848
3549
|
} catch {}
|
|
@@ -2852,28 +3553,28 @@ async function removeFnm(fnm) {
|
|
|
2852
3553
|
const wingetCheck = spawnSync2("winget", ["list", "--name", "fnm"], { encoding: "utf-8", shell: true });
|
|
2853
3554
|
if (wingetCheck.stdout?.includes("fnm")) {
|
|
2854
3555
|
execSync2("winget uninstall fnm --silent", { stdio: "pipe" });
|
|
2855
|
-
console.log(
|
|
3556
|
+
console.log(import_picocolors8.default.dim(" Removido via winget"));
|
|
2856
3557
|
removed = true;
|
|
2857
3558
|
}
|
|
2858
3559
|
} catch {}
|
|
2859
3560
|
}
|
|
2860
3561
|
const winFnmDirs = [
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
3562
|
+
join4(HOME, ".fnm"),
|
|
3563
|
+
join4(HOME, "AppData", "Local", "fnm"),
|
|
3564
|
+
join4(HOME, "AppData", "Roaming", "fnm"),
|
|
3565
|
+
join4(HOME, "AppData", "Local", "fnm_multishells"),
|
|
3566
|
+
join4(HOME, "AppData", "Local", "Microsoft", "fnm")
|
|
2866
3567
|
];
|
|
2867
3568
|
for (const dir of winFnmDirs) {
|
|
2868
3569
|
if (existsSync2(dir)) {
|
|
2869
3570
|
try {
|
|
2870
3571
|
execSync2(`rmdir /s /q "${dir}"`, { stdio: "pipe", shell: "cmd.exe" });
|
|
2871
|
-
console.log(
|
|
3572
|
+
console.log(import_picocolors8.default.dim(` Removido ${dir}`));
|
|
2872
3573
|
removed = true;
|
|
2873
3574
|
} catch {
|
|
2874
3575
|
try {
|
|
2875
3576
|
execSync2(`powershell -Command "Remove-Item -Path '${dir}' -Recurse -Force"`, { stdio: "pipe" });
|
|
2876
|
-
console.log(
|
|
3577
|
+
console.log(import_picocolors8.default.dim(` Removido ${dir}`));
|
|
2877
3578
|
removed = true;
|
|
2878
3579
|
} catch {}
|
|
2879
3580
|
}
|
|
@@ -2882,16 +3583,16 @@ async function removeFnm(fnm) {
|
|
|
2882
3583
|
try {
|
|
2883
3584
|
execSync2(`powershell -Command "[Environment]::SetEnvironmentVariable('FNM_DIR', $null, 'User')"`, { stdio: "pipe" });
|
|
2884
3585
|
execSync2(`powershell -Command "[Environment]::SetEnvironmentVariable('FNM_MULTISHELL_PATH', $null, 'User')"`, { stdio: "pipe" });
|
|
2885
|
-
console.log(
|
|
3586
|
+
console.log(import_picocolors8.default.dim(" Variaveis de ambiente FNM removidas"));
|
|
2886
3587
|
removed = true;
|
|
2887
3588
|
} catch {}
|
|
2888
3589
|
for (const configFile of fnm.configFiles || []) {
|
|
2889
3590
|
if (removeFnmFromConfig(configFile)) {
|
|
2890
|
-
console.log(
|
|
3591
|
+
console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
|
|
2891
3592
|
removed = true;
|
|
2892
3593
|
}
|
|
2893
3594
|
}
|
|
2894
|
-
spinner.stop(removed ? "fnm removido!" :
|
|
3595
|
+
spinner.stop(removed ? "fnm removido!" : import_picocolors8.default.yellow("fnm nao encontrado"));
|
|
2895
3596
|
return removed;
|
|
2896
3597
|
} else {
|
|
2897
3598
|
spinner.start("Removendo fnm...");
|
|
@@ -2900,35 +3601,35 @@ async function removeFnm(fnm) {
|
|
|
2900
3601
|
const brewCheck = spawnSync2("brew", ["list", "fnm"], { encoding: "utf-8", shell: true });
|
|
2901
3602
|
if (brewCheck.status === 0) {
|
|
2902
3603
|
execSync2("brew uninstall fnm", { stdio: "pipe" });
|
|
2903
|
-
console.log(
|
|
3604
|
+
console.log(import_picocolors8.default.dim(" Removido via Homebrew"));
|
|
2904
3605
|
removed = true;
|
|
2905
3606
|
}
|
|
2906
3607
|
} catch {}
|
|
2907
3608
|
for (const configFile of fnm.configFiles || []) {
|
|
2908
3609
|
if (removeFnmFromConfig(configFile)) {
|
|
2909
|
-
console.log(
|
|
3610
|
+
console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
|
|
2910
3611
|
removed = true;
|
|
2911
3612
|
}
|
|
2912
3613
|
}
|
|
2913
3614
|
const fnmDirs = [
|
|
2914
|
-
|
|
2915
|
-
|
|
3615
|
+
join4(HOME, ".fnm"),
|
|
3616
|
+
join4(HOME, ".local", "share", "fnm")
|
|
2916
3617
|
];
|
|
2917
3618
|
for (const fnmDir of fnmDirs) {
|
|
2918
3619
|
if (existsSync2(fnmDir)) {
|
|
2919
3620
|
execSync2(`rm -rf "${fnmDir}"`, { stdio: "pipe" });
|
|
2920
|
-
console.log(
|
|
3621
|
+
console.log(import_picocolors8.default.dim(` Removido ${fnmDir}`));
|
|
2921
3622
|
removed = true;
|
|
2922
3623
|
}
|
|
2923
3624
|
}
|
|
2924
3625
|
const fnmBins = [
|
|
2925
|
-
|
|
2926
|
-
|
|
3626
|
+
join4(HOME, ".local", "bin", "fnm"),
|
|
3627
|
+
join4(HOME, ".cargo", "bin", "fnm")
|
|
2927
3628
|
];
|
|
2928
3629
|
for (const bin of fnmBins) {
|
|
2929
3630
|
if (existsSync2(bin)) {
|
|
2930
3631
|
execSync2(`rm -f "${bin}"`, { stdio: "pipe" });
|
|
2931
|
-
console.log(
|
|
3632
|
+
console.log(import_picocolors8.default.dim(` Removido ${bin}`));
|
|
2932
3633
|
removed = true;
|
|
2933
3634
|
}
|
|
2934
3635
|
}
|
|
@@ -2936,7 +3637,7 @@ async function removeFnm(fnm) {
|
|
|
2936
3637
|
return removed;
|
|
2937
3638
|
}
|
|
2938
3639
|
} catch (error) {
|
|
2939
|
-
spinner.stop(
|
|
3640
|
+
spinner.stop(import_picocolors8.default.red("Erro ao remover fnm"));
|
|
2940
3641
|
return false;
|
|
2941
3642
|
}
|
|
2942
3643
|
}
|
|
@@ -2950,59 +3651,59 @@ async function removeNvm(nvm) {
|
|
|
2950
3651
|
const wingetCheck = spawnSync2("winget", ["list", "--name", "nvm"], { encoding: "utf-8", shell: true });
|
|
2951
3652
|
if (wingetCheck.stdout?.toLowerCase().includes("nvm")) {
|
|
2952
3653
|
execSync2("winget uninstall nvm --silent", { stdio: "pipe" });
|
|
2953
|
-
console.log(
|
|
3654
|
+
console.log(import_picocolors8.default.dim(" Removido via winget"));
|
|
2954
3655
|
removed = true;
|
|
2955
3656
|
}
|
|
2956
3657
|
} catch {}
|
|
2957
3658
|
const nvmWinDirs = [
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
3659
|
+
join4(HOME, "AppData", "Roaming", "nvm"),
|
|
3660
|
+
join4("C:", "Program Files", "nvm"),
|
|
3661
|
+
join4("C:", "ProgramData", "nvm")
|
|
2961
3662
|
];
|
|
2962
3663
|
for (const dir of nvmWinDirs) {
|
|
2963
3664
|
if (existsSync2(dir)) {
|
|
2964
3665
|
try {
|
|
2965
3666
|
execSync2(`rmdir /s /q "${dir}"`, { stdio: "pipe", shell: "cmd.exe" });
|
|
2966
|
-
console.log(
|
|
3667
|
+
console.log(import_picocolors8.default.dim(` Removido ${dir}`));
|
|
2967
3668
|
removed = true;
|
|
2968
3669
|
} catch {}
|
|
2969
3670
|
}
|
|
2970
3671
|
}
|
|
2971
3672
|
for (const configFile of nvm.configFiles || []) {
|
|
2972
3673
|
if (removeNvmFromConfig(configFile)) {
|
|
2973
|
-
console.log(
|
|
3674
|
+
console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
|
|
2974
3675
|
removed = true;
|
|
2975
3676
|
}
|
|
2976
3677
|
}
|
|
2977
3678
|
if (!removed) {
|
|
2978
|
-
console.log(
|
|
3679
|
+
console.log(import_picocolors8.default.yellow(`
|
|
2979
3680
|
nvm-windows pode precisar de remocao manual:`));
|
|
2980
|
-
console.log(
|
|
2981
|
-
console.log(
|
|
2982
|
-
console.log(
|
|
3681
|
+
console.log(import_picocolors8.default.dim(" 1. Abra 'Adicionar ou remover programas'"));
|
|
3682
|
+
console.log(import_picocolors8.default.dim(" 2. Procure por 'NVM for Windows'"));
|
|
3683
|
+
console.log(import_picocolors8.default.dim(" 3. Clique em Desinstalar"));
|
|
2983
3684
|
}
|
|
2984
|
-
spinner.stop(removed ? "nvm removido!" :
|
|
3685
|
+
spinner.stop(removed ? "nvm removido!" : import_picocolors8.default.yellow("Verifique manualmente"));
|
|
2985
3686
|
return removed;
|
|
2986
3687
|
} else {
|
|
2987
3688
|
spinner.start("Removendo nvm...");
|
|
2988
3689
|
let removed = false;
|
|
2989
3690
|
for (const configFile of nvm.configFiles || []) {
|
|
2990
3691
|
if (removeNvmFromConfig(configFile)) {
|
|
2991
|
-
console.log(
|
|
3692
|
+
console.log(import_picocolors8.default.dim(` Removido de ${configFile}`));
|
|
2992
3693
|
removed = true;
|
|
2993
3694
|
}
|
|
2994
3695
|
}
|
|
2995
|
-
const nvmDir = process.env.NVM_DIR ||
|
|
3696
|
+
const nvmDir = process.env.NVM_DIR || join4(HOME, ".nvm");
|
|
2996
3697
|
if (existsSync2(nvmDir)) {
|
|
2997
3698
|
execSync2(`rm -rf "${nvmDir}"`, { stdio: "pipe" });
|
|
2998
|
-
console.log(
|
|
3699
|
+
console.log(import_picocolors8.default.dim(` Removido ${nvmDir}`));
|
|
2999
3700
|
removed = true;
|
|
3000
3701
|
}
|
|
3001
3702
|
spinner.stop(removed ? "nvm removido!" : "nvm nao encontrado");
|
|
3002
3703
|
return removed;
|
|
3003
3704
|
}
|
|
3004
3705
|
} catch (error) {
|
|
3005
|
-
spinner.stop(
|
|
3706
|
+
spinner.stop(import_picocolors8.default.red("Erro ao remover nvm"));
|
|
3006
3707
|
return false;
|
|
3007
3708
|
}
|
|
3008
3709
|
}
|
|
@@ -3021,14 +3722,14 @@ async function installVolta() {
|
|
|
3021
3722
|
timeout: 120000
|
|
3022
3723
|
});
|
|
3023
3724
|
spinner.stop("Volta instalado!");
|
|
3024
|
-
const voltaPath =
|
|
3025
|
-
console.log(
|
|
3725
|
+
const voltaPath = join4(HOME, ".volta", "bin");
|
|
3726
|
+
console.log(import_picocolors8.default.dim(` Adicionando ${voltaPath} ao PATH...`));
|
|
3026
3727
|
try {
|
|
3027
3728
|
execSync2(`setx PATH "%PATH%;${voltaPath}"`, { stdio: "pipe", shell: "cmd.exe" });
|
|
3028
3729
|
} catch {}
|
|
3029
3730
|
return true;
|
|
3030
3731
|
} catch (e2) {
|
|
3031
|
-
spinner.stop(
|
|
3732
|
+
spinner.stop(import_picocolors8.default.yellow("winget falhou, tentando outro metodo..."));
|
|
3032
3733
|
}
|
|
3033
3734
|
}
|
|
3034
3735
|
const chocoCheck = spawnSync2(CHECK_CMD, ["choco"], { encoding: "utf-8", shell: true });
|
|
@@ -3039,7 +3740,7 @@ async function installVolta() {
|
|
|
3039
3740
|
spinner.stop("Volta instalado!");
|
|
3040
3741
|
return true;
|
|
3041
3742
|
} catch {
|
|
3042
|
-
spinner.stop(
|
|
3743
|
+
spinner.stop(import_picocolors8.default.yellow("Chocolatey falhou"));
|
|
3043
3744
|
}
|
|
3044
3745
|
}
|
|
3045
3746
|
spinner.start("Baixando Volta diretamente...");
|
|
@@ -3063,17 +3764,17 @@ async function installVolta() {
|
|
|
3063
3764
|
spinner.stop("Volta instalado!");
|
|
3064
3765
|
return true;
|
|
3065
3766
|
} catch (e2) {
|
|
3066
|
-
spinner.stop(
|
|
3767
|
+
spinner.stop(import_picocolors8.default.yellow("Download direto falhou"));
|
|
3067
3768
|
}
|
|
3068
3769
|
console.log();
|
|
3069
|
-
console.log(
|
|
3770
|
+
console.log(import_picocolors8.default.bold(" Instale manualmente:"));
|
|
3070
3771
|
console.log();
|
|
3071
|
-
console.log(
|
|
3072
|
-
console.log(
|
|
3772
|
+
console.log(import_picocolors8.default.cyan(" 1. Baixe: https://github.com/volta-cli/volta/releases/latest"));
|
|
3773
|
+
console.log(import_picocolors8.default.dim(" (arquivo volta-windows.msi)"));
|
|
3073
3774
|
console.log();
|
|
3074
|
-
console.log(
|
|
3775
|
+
console.log(import_picocolors8.default.cyan(" 2. Execute o instalador"));
|
|
3075
3776
|
console.log();
|
|
3076
|
-
console.log(
|
|
3777
|
+
console.log(import_picocolors8.default.cyan(" 3. Reinicie o terminal"));
|
|
3077
3778
|
console.log();
|
|
3078
3779
|
return false;
|
|
3079
3780
|
} else {
|
|
@@ -3082,7 +3783,7 @@ async function installVolta() {
|
|
|
3082
3783
|
stdio: "pipe",
|
|
3083
3784
|
shell: "/bin/bash"
|
|
3084
3785
|
});
|
|
3085
|
-
const shellConfig = existsSync2(
|
|
3786
|
+
const shellConfig = existsSync2(join4(HOME, ".zshrc")) ? join4(HOME, ".zshrc") : join4(HOME, ".bashrc");
|
|
3086
3787
|
const voltaSetup = `
|
|
3087
3788
|
# Volta - Node.js version manager
|
|
3088
3789
|
export VOLTA_HOME="$HOME/.volta"
|
|
@@ -3092,28 +3793,28 @@ export PATH="$VOLTA_HOME/bin:$PATH"
|
|
|
3092
3793
|
const content = readFileSync2(shellConfig, "utf-8");
|
|
3093
3794
|
if (!content.includes("VOLTA_HOME")) {
|
|
3094
3795
|
writeFileSync(shellConfig, content + voltaSetup);
|
|
3095
|
-
console.log(
|
|
3796
|
+
console.log(import_picocolors8.default.dim(` Adicionado ao ${shellConfig}`));
|
|
3096
3797
|
}
|
|
3097
3798
|
}
|
|
3098
3799
|
spinner.stop("Volta instalado!");
|
|
3099
3800
|
return true;
|
|
3100
3801
|
}
|
|
3101
3802
|
} catch (error) {
|
|
3102
|
-
spinner.stop(
|
|
3103
|
-
console.log(
|
|
3803
|
+
spinner.stop(import_picocolors8.default.red("Erro ao instalar Volta"));
|
|
3804
|
+
console.log(import_picocolors8.default.dim(` ${error}`));
|
|
3104
3805
|
return false;
|
|
3105
3806
|
}
|
|
3106
3807
|
}
|
|
3107
3808
|
async function installNodeWithVolta() {
|
|
3108
3809
|
const spinner = Y2();
|
|
3109
3810
|
try {
|
|
3110
|
-
const voltaBin = IS_WINDOWS ? "volta" :
|
|
3811
|
+
const voltaBin = IS_WINDOWS ? "volta" : join4(HOME, ".volta", "bin", "volta");
|
|
3111
3812
|
spinner.start("Instalando Node.js LTS via Volta...");
|
|
3112
3813
|
execSync2(`"${voltaBin}" install node`, { stdio: "pipe" });
|
|
3113
3814
|
spinner.stop("Node.js instalado!");
|
|
3114
3815
|
return true;
|
|
3115
3816
|
} catch (error) {
|
|
3116
|
-
spinner.stop(
|
|
3817
|
+
spinner.stop(import_picocolors8.default.red("Erro ao instalar Node.js"));
|
|
3117
3818
|
return false;
|
|
3118
3819
|
}
|
|
3119
3820
|
}
|
|
@@ -3121,23 +3822,23 @@ async function reinstallGlobalPackages(packages) {
|
|
|
3121
3822
|
if (packages.length === 0)
|
|
3122
3823
|
return;
|
|
3123
3824
|
const spinner = Y2();
|
|
3124
|
-
const voltaBin = IS_WINDOWS ? "volta" :
|
|
3825
|
+
const voltaBin = IS_WINDOWS ? "volta" : join4(HOME, ".volta", "bin", "volta");
|
|
3125
3826
|
for (const pkg of packages) {
|
|
3126
3827
|
spinner.start(`Instalando ${pkg}...`);
|
|
3127
3828
|
try {
|
|
3128
3829
|
execSync2(`"${voltaBin}" install ${pkg}`, { stdio: "pipe" });
|
|
3129
3830
|
spinner.stop(`${pkg} instalado!`);
|
|
3130
3831
|
} catch {
|
|
3131
|
-
spinner.stop(
|
|
3832
|
+
spinner.stop(import_picocolors8.default.yellow(`${pkg} - falha (instale manualmente)`));
|
|
3132
3833
|
}
|
|
3133
3834
|
}
|
|
3134
3835
|
}
|
|
3135
3836
|
async function setupNode(args) {
|
|
3136
3837
|
const checkOnly = args.includes("--check") || args.includes("-c");
|
|
3137
3838
|
console.log();
|
|
3138
|
-
Ie(
|
|
3839
|
+
Ie(import_picocolors8.default.bgCyan(import_picocolors8.default.black(" nimbus setup node ")));
|
|
3139
3840
|
console.log();
|
|
3140
|
-
console.log(
|
|
3841
|
+
console.log(import_picocolors8.default.bold(" Detectando ambiente..."));
|
|
3141
3842
|
console.log();
|
|
3142
3843
|
const fnm = detectFnm();
|
|
3143
3844
|
const nvm = detectNvm();
|
|
@@ -3145,27 +3846,27 @@ async function setupNode(args) {
|
|
|
3145
3846
|
const node = detectNode();
|
|
3146
3847
|
const status = (installed, version) => {
|
|
3147
3848
|
if (!installed)
|
|
3148
|
-
return
|
|
3149
|
-
return
|
|
3849
|
+
return import_picocolors8.default.dim("nao instalado");
|
|
3850
|
+
return import_picocolors8.default.green(`instalado${version ? ` (${version})` : ""}`);
|
|
3150
3851
|
};
|
|
3151
|
-
console.log(` ${
|
|
3152
|
-
console.log(` ${
|
|
3153
|
-
console.log(` ${
|
|
3852
|
+
console.log(` ${import_picocolors8.default.bold("fnm:")} ${status(fnm.installed, fnm.version)}`);
|
|
3853
|
+
console.log(` ${import_picocolors8.default.bold("nvm:")} ${status(nvm.installed, nvm.version)}`);
|
|
3854
|
+
console.log(` ${import_picocolors8.default.bold("volta:")} ${status(volta.installed, volta.version)}`);
|
|
3154
3855
|
console.log();
|
|
3155
|
-
console.log(` ${
|
|
3856
|
+
console.log(` ${import_picocolors8.default.bold("node:")} ${node.version || import_picocolors8.default.dim("nao encontrado")}`);
|
|
3156
3857
|
if (node.manager) {
|
|
3157
|
-
console.log(` ${
|
|
3858
|
+
console.log(` ${import_picocolors8.default.dim(`gerenciado por: ${node.manager}`)}`);
|
|
3158
3859
|
}
|
|
3159
3860
|
console.log();
|
|
3160
3861
|
if (volta.installed && !fnm.installed && !nvm.installed) {
|
|
3161
3862
|
M2.success("Ambiente OK! Volta instalado e configurado.");
|
|
3162
|
-
Se(
|
|
3863
|
+
Se(import_picocolors8.default.green("Nada a fazer."));
|
|
3163
3864
|
return;
|
|
3164
3865
|
}
|
|
3165
3866
|
if (checkOnly) {
|
|
3166
3867
|
if (fnm.installed || nvm.installed) {
|
|
3167
|
-
console.log(
|
|
3168
|
-
console.log(
|
|
3868
|
+
console.log(import_picocolors8.default.yellow(" Recomendacao: migre para Volta"));
|
|
3869
|
+
console.log(import_picocolors8.default.dim(" Execute: nimbus setup node"));
|
|
3169
3870
|
}
|
|
3170
3871
|
Se("");
|
|
3171
3872
|
return;
|
|
@@ -3173,15 +3874,15 @@ async function setupNode(args) {
|
|
|
3173
3874
|
const hasOldManager = fnm.installed || nvm.installed;
|
|
3174
3875
|
const globalPackages = getGlobalPackages();
|
|
3175
3876
|
if (hasOldManager) {
|
|
3176
|
-
console.log(
|
|
3877
|
+
console.log(import_picocolors8.default.yellow(" Gerenciadores antigos detectados!"));
|
|
3177
3878
|
console.log();
|
|
3178
|
-
console.log(
|
|
3179
|
-
console.log(
|
|
3879
|
+
console.log(import_picocolors8.default.dim(" fnm e nvm causam problemas de cache do shell."));
|
|
3880
|
+
console.log(import_picocolors8.default.dim(" Volta resolve isso e funciona melhor no Windows."));
|
|
3180
3881
|
console.log();
|
|
3181
3882
|
if (globalPackages.length > 0) {
|
|
3182
|
-
console.log(
|
|
3883
|
+
console.log(import_picocolors8.default.bold(" Pacotes globais encontrados:"));
|
|
3183
3884
|
for (const pkg of globalPackages) {
|
|
3184
|
-
console.log(
|
|
3885
|
+
console.log(import_picocolors8.default.dim(` - ${pkg}`));
|
|
3185
3886
|
}
|
|
3186
3887
|
console.log();
|
|
3187
3888
|
}
|
|
@@ -3196,9 +3897,9 @@ async function setupNode(args) {
|
|
|
3196
3897
|
actions.push("Instalar Node.js via Volta");
|
|
3197
3898
|
if (globalPackages.length > 0)
|
|
3198
3899
|
actions.push(`Reinstalar ${globalPackages.length} pacotes globais`);
|
|
3199
|
-
console.log(
|
|
3900
|
+
console.log(import_picocolors8.default.bold(" O que sera feito:"));
|
|
3200
3901
|
for (const action of actions) {
|
|
3201
|
-
console.log(
|
|
3902
|
+
console.log(import_picocolors8.default.cyan(` -> ${action}`));
|
|
3202
3903
|
}
|
|
3203
3904
|
console.log();
|
|
3204
3905
|
const confirm = await ye({
|
|
@@ -3211,60 +3912,60 @@ async function setupNode(args) {
|
|
|
3211
3912
|
}
|
|
3212
3913
|
console.log();
|
|
3213
3914
|
if (fnm.installed) {
|
|
3214
|
-
console.log(
|
|
3915
|
+
console.log(import_picocolors8.default.bold(" Removendo fnm..."));
|
|
3215
3916
|
await removeFnm(fnm);
|
|
3216
3917
|
console.log();
|
|
3217
3918
|
}
|
|
3218
3919
|
if (nvm.installed) {
|
|
3219
|
-
console.log(
|
|
3920
|
+
console.log(import_picocolors8.default.bold(" Removendo nvm..."));
|
|
3220
3921
|
await removeNvm(nvm);
|
|
3221
3922
|
console.log();
|
|
3222
3923
|
}
|
|
3223
3924
|
if (!volta.installed) {
|
|
3224
|
-
console.log(
|
|
3925
|
+
console.log(import_picocolors8.default.bold(" Instalando Volta..."));
|
|
3225
3926
|
const installed = await installVolta();
|
|
3226
3927
|
if (!installed) {
|
|
3227
|
-
Se(
|
|
3928
|
+
Se(import_picocolors8.default.red("Falha na instalacao. Tente manualmente."));
|
|
3228
3929
|
return;
|
|
3229
3930
|
}
|
|
3230
3931
|
console.log();
|
|
3231
3932
|
}
|
|
3232
|
-
console.log(
|
|
3933
|
+
console.log(import_picocolors8.default.bold(" Instalando Node.js..."));
|
|
3233
3934
|
await installNodeWithVolta();
|
|
3234
3935
|
console.log();
|
|
3235
3936
|
if (globalPackages.length > 0) {
|
|
3236
|
-
console.log(
|
|
3937
|
+
console.log(import_picocolors8.default.bold(" Reinstalando pacotes globais..."));
|
|
3237
3938
|
await reinstallGlobalPackages(globalPackages);
|
|
3238
3939
|
console.log();
|
|
3239
3940
|
}
|
|
3240
|
-
console.log(
|
|
3241
|
-
console.log(
|
|
3242
|
-
console.log(
|
|
3941
|
+
console.log(import_picocolors8.default.green(" ====================================="));
|
|
3942
|
+
console.log(import_picocolors8.default.green(" Migracao concluida!"));
|
|
3943
|
+
console.log(import_picocolors8.default.green(" ====================================="));
|
|
3243
3944
|
console.log();
|
|
3244
3945
|
if (IS_WINDOWS) {
|
|
3245
|
-
console.log(
|
|
3946
|
+
console.log(import_picocolors8.default.yellow(" IMPORTANTE: Reinicie o terminal!"));
|
|
3246
3947
|
console.log();
|
|
3247
|
-
console.log(
|
|
3248
|
-
console.log(
|
|
3948
|
+
console.log(import_picocolors8.default.dim(" Feche todas as janelas do PowerShell/Terminal"));
|
|
3949
|
+
console.log(import_picocolors8.default.dim(" e abra novamente para aplicar as mudancas."));
|
|
3249
3950
|
} else {
|
|
3250
|
-
console.log(
|
|
3951
|
+
console.log(import_picocolors8.default.yellow(" IMPORTANTE: Reinicie o terminal ou execute:"));
|
|
3251
3952
|
console.log();
|
|
3252
|
-
console.log(
|
|
3253
|
-
console.log(
|
|
3254
|
-
console.log(
|
|
3953
|
+
console.log(import_picocolors8.default.cyan(" source ~/.zshrc"));
|
|
3954
|
+
console.log(import_picocolors8.default.dim(" # ou"));
|
|
3955
|
+
console.log(import_picocolors8.default.cyan(" source ~/.bashrc"));
|
|
3255
3956
|
}
|
|
3256
3957
|
console.log();
|
|
3257
|
-
console.log(
|
|
3258
|
-
console.log(
|
|
3259
|
-
console.log(
|
|
3260
|
-
console.log(
|
|
3958
|
+
console.log(import_picocolors8.default.bold(" Depois, verifique:"));
|
|
3959
|
+
console.log(import_picocolors8.default.dim(" volta --version"));
|
|
3960
|
+
console.log(import_picocolors8.default.dim(" node --version"));
|
|
3961
|
+
console.log(import_picocolors8.default.dim(" nimbus --version"));
|
|
3261
3962
|
console.log();
|
|
3262
|
-
Se(
|
|
3963
|
+
Se(import_picocolors8.default.green("Pronto! Volta configurado."));
|
|
3263
3964
|
}
|
|
3264
3965
|
|
|
3265
3966
|
// src/index.ts
|
|
3266
3967
|
var PACKAGE_NAME2 = "@nimbuslab/cli";
|
|
3267
|
-
var CURRENT_VERSION = "1.
|
|
3968
|
+
var CURRENT_VERSION = "1.1.0";
|
|
3268
3969
|
var LOGO = `
|
|
3269
3970
|
\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
3971
|
\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 +4001,18 @@ function showUpdateNotice(latestVersion) {
|
|
|
3300
4001
|
const line2 = ` Atualize com: ${command}`;
|
|
3301
4002
|
const maxLen = Math.max(line1.length, line2.length);
|
|
3302
4003
|
const border = "\u2500".repeat(maxLen + 2);
|
|
3303
|
-
console.log(
|
|
3304
|
-
console.log(
|
|
3305
|
-
console.log(
|
|
3306
|
-
console.log(
|
|
4004
|
+
console.log(import_picocolors9.default.yellow(` \u250C${border}\u2510`));
|
|
4005
|
+
console.log(import_picocolors9.default.yellow(` \u2502`) + import_picocolors9.default.white(line1.padEnd(maxLen + 2)) + import_picocolors9.default.yellow(`\u2502`));
|
|
4006
|
+
console.log(import_picocolors9.default.yellow(` \u2502`) + import_picocolors9.default.cyan(line2.padEnd(maxLen + 2)) + import_picocolors9.default.yellow(`\u2502`));
|
|
4007
|
+
console.log(import_picocolors9.default.yellow(` \u2514${border}\u2518`));
|
|
3307
4008
|
console.log();
|
|
3308
4009
|
}
|
|
3309
4010
|
async function main() {
|
|
3310
4011
|
const args = process.argv.slice(2);
|
|
3311
4012
|
const command = args[0];
|
|
3312
|
-
console.log(
|
|
3313
|
-
console.log(
|
|
3314
|
-
console.log(
|
|
4013
|
+
console.log(import_picocolors9.default.cyan(LOGO));
|
|
4014
|
+
console.log(import_picocolors9.default.white(" nimbuslab CLI"));
|
|
4015
|
+
console.log(import_picocolors9.default.dim(" Create awesome projects"));
|
|
3315
4016
|
console.log();
|
|
3316
4017
|
const latestVersion = await checkForUpdates();
|
|
3317
4018
|
if (latestVersion) {
|
|
@@ -3330,8 +4031,8 @@ async function main() {
|
|
|
3330
4031
|
if (subcommand === "node") {
|
|
3331
4032
|
await setupNode(args.slice(2));
|
|
3332
4033
|
} else {
|
|
3333
|
-
console.log(
|
|
3334
|
-
console.log(
|
|
4034
|
+
console.log(import_picocolors9.default.red(`Subcomando desconhecido: ${subcommand || "(vazio)"}`));
|
|
4035
|
+
console.log(import_picocolors9.default.dim(" Uso: nimbus setup node"));
|
|
3335
4036
|
process.exit(1);
|
|
3336
4037
|
}
|
|
3337
4038
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
@@ -3339,16 +4040,16 @@ async function main() {
|
|
|
3339
4040
|
} else if (command === "version" || command === "--version" || command === "-v") {
|
|
3340
4041
|
showVersion();
|
|
3341
4042
|
} else {
|
|
3342
|
-
console.log(
|
|
4043
|
+
console.log(import_picocolors9.default.red(`Comando desconhecido: ${command}`));
|
|
3343
4044
|
showHelp();
|
|
3344
4045
|
process.exit(1);
|
|
3345
4046
|
}
|
|
3346
4047
|
}
|
|
3347
4048
|
function showHelp() {
|
|
3348
4049
|
console.log(`
|
|
3349
|
-
${
|
|
4050
|
+
${import_picocolors9.default.bold("Uso:")} nimbus [comando] [op\xE7\xF5es]
|
|
3350
4051
|
|
|
3351
|
-
${
|
|
4052
|
+
${import_picocolors9.default.bold("Comandos:")}
|
|
3352
4053
|
create [nome] Criar novo projeto
|
|
3353
4054
|
analyze [dir] Analisar stack do projeto
|
|
3354
4055
|
upgrade [alvo] Atualizar depend\xEAncias
|
|
@@ -3358,52 +4059,52 @@ ${import_picocolors8.default.bold("Comandos:")}
|
|
|
3358
4059
|
help Mostrar esta ajuda
|
|
3359
4060
|
version Mostrar vers\xE3o
|
|
3360
4061
|
|
|
3361
|
-
${
|
|
4062
|
+
${import_picocolors9.default.bold("Templates:")}
|
|
3362
4063
|
--landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
|
|
3363
4064
|
--app Web app (Landing + Better Auth + Drizzle)
|
|
3364
4065
|
--turborepo Monorepo (Turborepo + apps/packages)
|
|
3365
4066
|
|
|
3366
|
-
${
|
|
4067
|
+
${import_picocolors9.default.bold("Analyze & Upgrade:")}
|
|
3367
4068
|
analyze . Detectar stack e mostrar recomenda\xE7\xF5es
|
|
3368
4069
|
analyze --json Output em JSON
|
|
3369
4070
|
upgrade --plan Mostrar plano de upgrade
|
|
3370
4071
|
upgrade next Atualizar Next.js
|
|
3371
4072
|
upgrade tailwind Atualizar Tailwind CSS
|
|
3372
4073
|
|
|
3373
|
-
${
|
|
4074
|
+
${import_picocolors9.default.bold("Update (CLI):")}
|
|
3374
4075
|
update Atualizar para ultima versao
|
|
3375
4076
|
update 0.11.0 Instalar versao especifica
|
|
3376
4077
|
update --list Listar versoes disponiveis
|
|
3377
4078
|
update --force Forcar reinstalacao (limpa cache)
|
|
3378
4079
|
|
|
3379
|
-
${
|
|
4080
|
+
${import_picocolors9.default.bold("Setup (Ambiente):")}
|
|
3380
4081
|
setup node Migrar para Volta (remove fnm/nvm)
|
|
3381
4082
|
setup node --check Verificar ambiente atual
|
|
3382
4083
|
|
|
3383
|
-
${
|
|
4084
|
+
${import_picocolors9.default.bold("Op\xE7\xF5es:")}
|
|
3384
4085
|
-y, --yes Aceitar padr\xF5es
|
|
3385
4086
|
--no-git N\xE3o inicializar Git
|
|
3386
4087
|
--no-install N\xE3o instalar depend\xEAncias
|
|
3387
4088
|
--template <url> Usar template customizado
|
|
3388
4089
|
|
|
3389
|
-
${
|
|
4090
|
+
${import_picocolors9.default.bold("Lola (Code Agent):")}
|
|
3390
4091
|
lola install Instalar/atualizar Lola
|
|
3391
4092
|
lola suggest Sugerir melhoria (cria issue)
|
|
3392
4093
|
|
|
3393
|
-
${
|
|
3394
|
-
${
|
|
3395
|
-
${
|
|
3396
|
-
${
|
|
3397
|
-
${
|
|
3398
|
-
${
|
|
3399
|
-
${
|
|
3400
|
-
${
|
|
4094
|
+
${import_picocolors9.default.bold("Exemplos:")}
|
|
4095
|
+
${import_picocolors9.default.dim("$")} nimbus create my-landing --landing
|
|
4096
|
+
${import_picocolors9.default.dim("$")} nimbus create my-app --app
|
|
4097
|
+
${import_picocolors9.default.dim("$")} nimbus analyze ./my-project
|
|
4098
|
+
${import_picocolors9.default.dim("$")} nimbus upgrade --plan
|
|
4099
|
+
${import_picocolors9.default.dim("$")} nimbus update
|
|
4100
|
+
${import_picocolors9.default.dim("$")} nimbus setup node
|
|
4101
|
+
${import_picocolors9.default.dim("$")} nimbus lola install
|
|
3401
4102
|
`);
|
|
3402
4103
|
}
|
|
3403
4104
|
function showVersion() {
|
|
3404
4105
|
console.log(`${PACKAGE_NAME2} v${CURRENT_VERSION}`);
|
|
3405
4106
|
}
|
|
3406
4107
|
main().catch((err) => {
|
|
3407
|
-
console.error(
|
|
4108
|
+
console.error(import_picocolors9.default.red("Erro:"), err.message);
|
|
3408
4109
|
process.exit(1);
|
|
3409
4110
|
});
|