elsabro 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/commands/elsabro/add-phase.md +17 -0
  2. package/commands/elsabro/add-todo.md +111 -53
  3. package/commands/elsabro/audit-milestone.md +19 -0
  4. package/commands/elsabro/check-todos.md +210 -31
  5. package/commands/elsabro/complete-milestone.md +20 -1
  6. package/commands/elsabro/debug.md +19 -0
  7. package/commands/elsabro/discuss-phase.md +18 -1
  8. package/commands/elsabro/execute.md +288 -12
  9. package/commands/elsabro/insert-phase.md +18 -1
  10. package/commands/elsabro/list-phase-assumptions.md +17 -0
  11. package/commands/elsabro/new-milestone.md +19 -0
  12. package/commands/elsabro/new.md +19 -0
  13. package/commands/elsabro/pause-work.md +19 -0
  14. package/commands/elsabro/plan-milestone-gaps.md +20 -1
  15. package/commands/elsabro/plan.md +264 -36
  16. package/commands/elsabro/progress.md +203 -79
  17. package/commands/elsabro/quick.md +19 -0
  18. package/commands/elsabro/remove-phase.md +17 -0
  19. package/commands/elsabro/research-phase.md +18 -1
  20. package/commands/elsabro/resume-work.md +19 -0
  21. package/commands/elsabro/start.md +365 -98
  22. package/commands/elsabro/verify-work.md +109 -5
  23. package/package.json +1 -1
  24. package/references/SYSTEM_INDEX.md +241 -0
  25. package/references/command-flow.md +352 -0
  26. package/references/enforcement-rules.md +331 -0
  27. package/references/error-handling-instructions.md +26 -12
  28. package/references/state-sync.md +381 -0
  29. package/references/task-dispatcher.md +388 -0
  30. package/references/tasks-integration.md +380 -0
  31. package/skills/api-microservice.md +765 -0
  32. package/skills/api-setup.md +76 -3
  33. package/skills/auth-setup.md +46 -6
  34. package/skills/chrome-extension.md +584 -0
  35. package/skills/cicd-setup.md +1206 -0
  36. package/skills/cli-tool.md +884 -0
  37. package/skills/database-setup.md +41 -5
  38. package/skills/desktop-app.md +1351 -0
  39. package/skills/expo-app.md +35 -2
  40. package/skills/full-stack-app.md +543 -0
  41. package/skills/mobile-app.md +813 -0
  42. package/skills/nextjs-app.md +33 -2
  43. package/skills/payments-setup.md +76 -1
  44. package/skills/saas-starter.md +639 -0
  45. package/skills/sentry-setup.md +41 -7
  46. package/skills/testing-setup.md +1218 -0
@@ -1,6 +1,15 @@
1
1
  ---
2
2
  name: expo-app
3
3
  description: Skill para crear aplicaciones móviles con Expo/React Native. Usa este skill cuando el usuario quiere crear una app para celular (iOS/Android).
4
+ tags:
5
+ - mobile
6
+ - react-native
7
+ - expo
8
+ - ios
9
+ - android
10
+ - typescript
11
+ difficulty: intermediate
12
+ estimated_time: 30-45 min
4
13
  ---
5
14
 
6
15
  # Skill: Crear App Expo (React Native)
@@ -16,6 +25,30 @@ Usar cuando el usuario menciona:
16
25
  - "aplicación móvil"
17
26
  </when_to_use>
18
27
 
28
+ <pre_requisites>
29
+ ## Pre-requisitos
30
+
31
+ ### Conocimientos
32
+ - JavaScript/TypeScript basico
33
+ - React fundamentals (components, hooks, state)
34
+ - Terminal/CLI basico
35
+
36
+ ### Software
37
+ - Node.js 20+ LTS
38
+ - npm o yarn
39
+ - Editor de codigo (VS Code recomendado)
40
+
41
+ ### Para desarrollo movil
42
+ - **iOS:** Mac con Xcode 15+ (opcional, puede usar Expo Go)
43
+ - **Android:** Android Studio con emulador (opcional, puede usar Expo Go)
44
+ - **Expo Go app** en tu celular (recomendado para empezar)
45
+
46
+ ### Cuentas (opcionales para empezar)
47
+ - Cuenta de Expo (gratis) para EAS Build
48
+ - Apple Developer ($99/year) para publicar en App Store
49
+ - Google Play Developer ($25 una vez) para publicar en Play Store
50
+ </pre_requisites>
51
+
19
52
  <before_starting>
20
53
  ## Investigación Obligatoria
21
54
 
@@ -42,8 +75,8 @@ Usar cuando el usuario menciona:
42
75
 
43
76
  | Tecnología | Propósito | Verificar |
44
77
  |------------|-----------|-----------|
45
- | Expo SDK 52+ | Framework React Native | Context7 |
46
- | React Native 0.76+ | UI móvil | Context7 |
78
+ | Expo SDK 52.x | Framework React Native | Context7 |
79
+ | React Native 0.76.x | UI movil | Context7 |
47
80
  | Expo Router | Navegación file-based | Context7 |
48
81
  | TypeScript | Type safety | Context7 |
49
82
  | NativeWind | Estilos (Tailwind) | Context7 |
@@ -0,0 +1,543 @@
1
+ ---
2
+ name: full-stack-app
3
+ description: Crear aplicacion full-stack completa con Next.js 15, React 19, Tailwind CSS, Prisma y PostgreSQL. Incluye autenticacion con NextAuth v5 y deploy a Vercel.
4
+ tags: [nextjs, react, tailwind, prisma, postgresql, nextauth, vercel, fullstack]
5
+ difficulty: intermediate
6
+ estimated_time: 30min
7
+ ---
8
+
9
+ # Skill: Full-Stack App
10
+
11
+ <when_to_use>
12
+ Usar cuando el usuario menciona:
13
+ - "crear app full-stack"
14
+ - "aplicacion web completa"
15
+ - "app con base de datos"
16
+ - "proyecto Next.js con auth"
17
+ - "webapp con backend"
18
+ </when_to_use>
19
+
20
+ <pre_requisites>
21
+ ## Pre-requisitos
22
+
23
+ - Node.js 20+
24
+ - PostgreSQL (local o Neon/Supabase)
25
+ - Cuenta de Vercel (para deploy)
26
+ </pre_requisites>
27
+
28
+ <tech_stack>
29
+ ## Stack Tecnologico
30
+
31
+ | Categoria | Tecnologia | Version |
32
+ |-----------|------------|---------|
33
+ | Framework | Next.js | 15.x |
34
+ | UI | React | 19.x |
35
+ | Styling | Tailwind CSS | 4.x |
36
+ | ORM | Prisma | 6.x |
37
+ | Database | PostgreSQL | 16.x |
38
+ | Auth | NextAuth.js | 5.x |
39
+ | Deploy | Vercel | - |
40
+ </tech_stack>
41
+
42
+ <project_structure>
43
+ ## Estructura de Proyecto
44
+
45
+ ```
46
+ my-app/
47
+ ├── src/
48
+ │ ├── app/
49
+ │ │ ├── (auth)/
50
+ │ │ │ ├── login/page.tsx
51
+ │ │ │ └── register/page.tsx
52
+ │ │ ├── (dashboard)/
53
+ │ │ │ ├── layout.tsx
54
+ │ │ │ └── page.tsx
55
+ │ │ ├── api/
56
+ │ │ │ └── [...nextauth]/route.ts
57
+ │ │ ├── layout.tsx
58
+ │ │ ├── page.tsx
59
+ │ │ └── globals.css
60
+ │ ├── components/
61
+ │ │ ├── ui/
62
+ │ │ │ ├── button.tsx
63
+ │ │ │ ├── input.tsx
64
+ │ │ │ └── card.tsx
65
+ │ │ └── providers.tsx
66
+ │ ├── lib/
67
+ │ │ ├── auth.ts
68
+ │ │ ├── db.ts
69
+ │ │ └── utils.ts
70
+ │ └── actions/
71
+ │ └── user.ts
72
+ ├── prisma/
73
+ │ └── schema.prisma
74
+ ├── public/
75
+ ├── .env.local
76
+ ├── next.config.ts
77
+ ├── tailwind.config.ts
78
+ ├── tsconfig.json
79
+ └── package.json
80
+ ```
81
+ </project_structure>
82
+
83
+ <setup_steps>
84
+ ## Pasos de Setup
85
+
86
+ ### Paso 1: Crear proyecto Next.js
87
+
88
+ ```bash
89
+ npx create-next-app@latest my-app --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
90
+ cd my-app
91
+ ```
92
+
93
+ ### Paso 2: Instalar dependencias
94
+
95
+ ```bash
96
+ npm install prisma @prisma/client next-auth@beta bcryptjs
97
+ npm install -D @types/bcryptjs
98
+ ```
99
+
100
+ ### Paso 3: Configurar Prisma
101
+
102
+ ```bash
103
+ npx prisma init
104
+ ```
105
+
106
+ Editar `prisma/schema.prisma`:
107
+
108
+ ```prisma
109
+ generator client {
110
+ provider = "prisma-client-js"
111
+ }
112
+
113
+ datasource db {
114
+ provider = "postgresql"
115
+ url = env("DATABASE_URL")
116
+ }
117
+
118
+ model User {
119
+ id String @id @default(cuid())
120
+ name String?
121
+ email String @unique
122
+ emailVerified DateTime?
123
+ password String?
124
+ image String?
125
+ accounts Account[]
126
+ sessions Session[]
127
+ createdAt DateTime @default(now())
128
+ updatedAt DateTime @updatedAt
129
+ }
130
+
131
+ model Account {
132
+ id String @id @default(cuid())
133
+ userId String
134
+ type String
135
+ provider String
136
+ providerAccountId String
137
+ refresh_token String? @db.Text
138
+ access_token String? @db.Text
139
+ expires_at Int?
140
+ token_type String?
141
+ scope String?
142
+ id_token String? @db.Text
143
+ session_state String?
144
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
145
+
146
+ @@unique([provider, providerAccountId])
147
+ }
148
+
149
+ model Session {
150
+ id String @id @default(cuid())
151
+ sessionToken String @unique
152
+ userId String
153
+ expires DateTime
154
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
155
+ }
156
+ ```
157
+
158
+ ### Paso 4: Configurar variables de entorno
159
+
160
+ Crear `.env.local`:
161
+
162
+ ```env
163
+ DATABASE_URL="postgresql://user:password@localhost:5432/myapp"
164
+ NEXTAUTH_SECRET="tu-secret-super-seguro-generado-con-openssl"
165
+ NEXTAUTH_URL="http://localhost:3000"
166
+ ```
167
+
168
+ ### Paso 5: Crear cliente de base de datos
169
+
170
+ Crear `src/lib/db.ts`:
171
+
172
+ ```typescript
173
+ import { PrismaClient } from "@prisma/client";
174
+
175
+ const globalForPrisma = globalThis as unknown as {
176
+ prisma: PrismaClient | undefined;
177
+ };
178
+
179
+ export const db = globalForPrisma.prisma ?? new PrismaClient();
180
+
181
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
182
+ ```
183
+
184
+ ### Paso 6: Configurar NextAuth
185
+
186
+ Crear `src/lib/auth.ts`:
187
+
188
+ ```typescript
189
+ import NextAuth from "next-auth";
190
+ import Credentials from "next-auth/providers/credentials";
191
+ import { PrismaAdapter } from "@auth/prisma-adapter";
192
+ import bcrypt from "bcryptjs";
193
+ import { db } from "./db";
194
+
195
+ export const { handlers, signIn, signOut, auth } = NextAuth({
196
+ adapter: PrismaAdapter(db),
197
+ session: { strategy: "jwt" },
198
+ pages: {
199
+ signIn: "/login",
200
+ },
201
+ providers: [
202
+ Credentials({
203
+ credentials: {
204
+ email: { label: "Email", type: "email" },
205
+ password: { label: "Password", type: "password" },
206
+ },
207
+ async authorize(credentials) {
208
+ if (!credentials?.email || !credentials?.password) {
209
+ return null;
210
+ }
211
+
212
+ const user = await db.user.findUnique({
213
+ where: { email: credentials.email as string },
214
+ });
215
+
216
+ if (!user || !user.password) {
217
+ return null;
218
+ }
219
+
220
+ const isValid = await bcrypt.compare(
221
+ credentials.password as string,
222
+ user.password
223
+ );
224
+
225
+ if (!isValid) {
226
+ return null;
227
+ }
228
+
229
+ return {
230
+ id: user.id,
231
+ email: user.email,
232
+ name: user.name,
233
+ };
234
+ },
235
+ }),
236
+ ],
237
+ callbacks: {
238
+ async jwt({ token, user }) {
239
+ if (user) {
240
+ token.id = user.id;
241
+ }
242
+ return token;
243
+ },
244
+ async session({ session, token }) {
245
+ if (session.user) {
246
+ session.user.id = token.id as string;
247
+ }
248
+ return session;
249
+ },
250
+ },
251
+ });
252
+ ```
253
+
254
+ ### Paso 7: Crear API route de NextAuth
255
+
256
+ Crear `src/app/api/auth/[...nextauth]/route.ts`:
257
+
258
+ ```typescript
259
+ import { handlers } from "@/lib/auth";
260
+
261
+ export const { GET, POST } = handlers;
262
+ ```
263
+
264
+ ### Paso 8: Crear Server Actions
265
+
266
+ Crear `src/actions/user.ts`:
267
+
268
+ ```typescript
269
+ "use server";
270
+
271
+ import { db } from "@/lib/db";
272
+ import { signIn } from "@/lib/auth";
273
+ import bcrypt from "bcryptjs";
274
+ import { redirect } from "next/navigation";
275
+
276
+ export async function register(formData: FormData) {
277
+ const email = formData.get("email") as string;
278
+ const password = formData.get("password") as string;
279
+ const name = formData.get("name") as string;
280
+
281
+ if (!email || !password) {
282
+ return { error: "Email y password son requeridos" };
283
+ }
284
+
285
+ const exists = await db.user.findUnique({ where: { email } });
286
+ if (exists) {
287
+ return { error: "El usuario ya existe" };
288
+ }
289
+
290
+ const hashedPassword = await bcrypt.hash(password, 10);
291
+
292
+ await db.user.create({
293
+ data: {
294
+ email,
295
+ password: hashedPassword,
296
+ name,
297
+ },
298
+ });
299
+
300
+ redirect("/login");
301
+ }
302
+
303
+ export async function login(formData: FormData) {
304
+ const email = formData.get("email") as string;
305
+ const password = formData.get("password") as string;
306
+
307
+ try {
308
+ await signIn("credentials", {
309
+ email,
310
+ password,
311
+ redirectTo: "/dashboard",
312
+ });
313
+ } catch (error) {
314
+ return { error: "Credenciales invalidas" };
315
+ }
316
+ }
317
+ ```
318
+
319
+ ### Paso 9: Crear componentes UI basicos
320
+
321
+ Crear `src/components/ui/button.tsx`:
322
+
323
+ ```typescript
324
+ import { ButtonHTMLAttributes, forwardRef } from "react";
325
+ import { cn } from "@/lib/utils";
326
+
327
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
328
+ variant?: "primary" | "secondary" | "outline";
329
+ }
330
+
331
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
332
+ ({ className, variant = "primary", ...props }, ref) => {
333
+ return (
334
+ <button
335
+ ref={ref}
336
+ className={cn(
337
+ "px-4 py-2 rounded-lg font-medium transition-colors",
338
+ variant === "primary" && "bg-blue-600 text-white hover:bg-blue-700",
339
+ variant === "secondary" && "bg-gray-200 text-gray-900 hover:bg-gray-300",
340
+ variant === "outline" && "border border-gray-300 hover:bg-gray-50",
341
+ className
342
+ )}
343
+ {...props}
344
+ />
345
+ );
346
+ }
347
+ );
348
+ Button.displayName = "Button";
349
+ ```
350
+
351
+ Crear `src/lib/utils.ts`:
352
+
353
+ ```typescript
354
+ import { clsx, type ClassValue } from "clsx";
355
+ import { twMerge } from "tailwind-merge";
356
+
357
+ export function cn(...inputs: ClassValue[]) {
358
+ return twMerge(clsx(inputs));
359
+ }
360
+ ```
361
+
362
+ Instalar clsx:
363
+
364
+ ```bash
365
+ npm install clsx tailwind-merge
366
+ ```
367
+
368
+ ### Paso 10: Crear paginas
369
+
370
+ Crear `src/app/login/page.tsx`:
371
+
372
+ ```typescript
373
+ import { login } from "@/actions/user";
374
+ import { Button } from "@/components/ui/button";
375
+
376
+ export default function LoginPage() {
377
+ return (
378
+ <div className="min-h-screen flex items-center justify-center bg-gray-50">
379
+ <div className="w-full max-w-md p-8 bg-white rounded-xl shadow-lg">
380
+ <h1 className="text-2xl font-bold text-center mb-6">Iniciar Sesion</h1>
381
+
382
+ <form action={login} className="space-y-4">
383
+ <div>
384
+ <label htmlFor="email" className="block text-sm font-medium mb-1">
385
+ Email
386
+ </label>
387
+ <input
388
+ id="email"
389
+ name="email"
390
+ type="email"
391
+ required
392
+ className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
393
+ />
394
+ </div>
395
+
396
+ <div>
397
+ <label htmlFor="password" className="block text-sm font-medium mb-1">
398
+ Password
399
+ </label>
400
+ <input
401
+ id="password"
402
+ name="password"
403
+ type="password"
404
+ required
405
+ className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
406
+ />
407
+ </div>
408
+
409
+ <Button type="submit" className="w-full">
410
+ Entrar
411
+ </Button>
412
+ </form>
413
+
414
+ <p className="mt-4 text-center text-sm text-gray-600">
415
+ No tienes cuenta?{" "}
416
+ <a href="/register" className="text-blue-600 hover:underline">
417
+ Registrate
418
+ </a>
419
+ </p>
420
+ </div>
421
+ </div>
422
+ );
423
+ }
424
+ ```
425
+
426
+ Crear `src/app/(dashboard)/page.tsx`:
427
+
428
+ ```typescript
429
+ import { auth, signOut } from "@/lib/auth";
430
+ import { redirect } from "next/navigation";
431
+ import { Button } from "@/components/ui/button";
432
+
433
+ export default async function DashboardPage() {
434
+ const session = await auth();
435
+
436
+ if (!session) {
437
+ redirect("/login");
438
+ }
439
+
440
+ return (
441
+ <div className="min-h-screen bg-gray-50">
442
+ <nav className="bg-white shadow">
443
+ <div className="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
444
+ <h1 className="text-xl font-bold">Dashboard</h1>
445
+ <form
446
+ action={async () => {
447
+ "use server";
448
+ await signOut({ redirectTo: "/" });
449
+ }}
450
+ >
451
+ <Button variant="outline" type="submit">
452
+ Cerrar Sesion
453
+ </Button>
454
+ </form>
455
+ </div>
456
+ </nav>
457
+
458
+ <main className="max-w-7xl mx-auto px-4 py-8">
459
+ <div className="bg-white rounded-xl shadow p-6">
460
+ <h2 className="text-lg font-semibold mb-4">
461
+ Bienvenido, {session.user?.name || session.user?.email}
462
+ </h2>
463
+ <p className="text-gray-600">
464
+ Esta es tu area privada. Aqui puedes agregar tu contenido.
465
+ </p>
466
+ </div>
467
+ </main>
468
+ </div>
469
+ );
470
+ }
471
+ ```
472
+
473
+ ### Paso 11: Ejecutar migraciones
474
+
475
+ ```bash
476
+ npx prisma migrate dev --name init
477
+ npx prisma generate
478
+ ```
479
+ </setup_steps>
480
+
481
+ <verification>
482
+ ## Verificacion
483
+
484
+ ### 1. Iniciar servidor de desarrollo
485
+ ```bash
486
+ npm run dev
487
+ ```
488
+
489
+ ### 2. Verificar paginas
490
+ - http://localhost:3000 - Home
491
+ - http://localhost:3000/login - Login
492
+ - http://localhost:3000/register - Registro
493
+
494
+ ### 3. Probar flujo completo
495
+ 1. Registrar nuevo usuario
496
+ 2. Login con credenciales
497
+ 3. Verificar acceso a dashboard
498
+ 4. Logout
499
+
500
+ ### 4. Verificar Prisma Studio
501
+ ```bash
502
+ npx prisma studio
503
+ ```
504
+ </verification>
505
+
506
+ <deploy>
507
+ ## Deploy a Vercel
508
+
509
+ ### 1. Push a GitHub
510
+ ```bash
511
+ git init
512
+ git add .
513
+ git commit -m "Initial commit"
514
+ git remote add origin <tu-repo>
515
+ git push -u origin main
516
+ ```
517
+
518
+ ### 2. Conectar a Vercel
519
+ ```bash
520
+ npx vercel
521
+ ```
522
+
523
+ ### 3. Configurar variables de entorno
524
+ En Vercel Dashboard:
525
+ - DATABASE_URL (usar Neon o Supabase para production)
526
+ - NEXTAUTH_SECRET
527
+ - NEXTAUTH_URL=https://tu-dominio.vercel.app
528
+ </deploy>
529
+
530
+ <common_issues>
531
+ ## Problemas Comunes
532
+
533
+ ### "PrismaClientInitializationError"
534
+ - Verificar DATABASE_URL en .env.local
535
+ - Ejecutar `npx prisma generate`
536
+
537
+ ### "NEXTAUTH_SECRET is not set"
538
+ - Generar secret: `openssl rand -base64 32`
539
+ - Agregar a .env.local
540
+
541
+ ### "Module not found: @prisma/client"
542
+ - Ejecutar `npx prisma generate`
543
+ </common_issues>