@qubiit/lmagent 2.5.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 (155) hide show
  1. package/.editorconfig +18 -0
  2. package/AGENTS.md +169 -0
  3. package/CLAUDE.md +122 -0
  4. package/CONTRIBUTING.md +90 -0
  5. package/LICENSE +21 -0
  6. package/README.md +195 -0
  7. package/config/commands.yaml +194 -0
  8. package/config/levels.yaml +135 -0
  9. package/config/models.yaml +192 -0
  10. package/config/settings.yaml +405 -0
  11. package/config/tools-extended.yaml +534 -0
  12. package/config/tools.yaml +437 -0
  13. package/docs/assets/logo.png +0 -0
  14. package/docs/commands.md +132 -0
  15. package/docs/customization-guide.md +445 -0
  16. package/docs/getting-started.md +154 -0
  17. package/docs/how-to-start.md +242 -0
  18. package/docs/navigation-index.md +227 -0
  19. package/docs/usage-guide.md +113 -0
  20. package/install.js +1044 -0
  21. package/package.json +35 -0
  22. package/pyproject.toml +182 -0
  23. package/rules/_bootstrap.md +138 -0
  24. package/rules/agents-ia.md +607 -0
  25. package/rules/api-design.md +337 -0
  26. package/rules/automations-n8n.md +646 -0
  27. package/rules/code-style.md +570 -0
  28. package/rules/documentation.md +98 -0
  29. package/rules/security.md +316 -0
  30. package/rules/stack.md +395 -0
  31. package/rules/testing.md +326 -0
  32. package/rules/workflow.md +353 -0
  33. package/scripts/create_skill.js +300 -0
  34. package/scripts/validate_skills.js +283 -0
  35. package/skills/ai-agent-engineer/SKILL.md +394 -0
  36. package/skills/ai-agent-engineer/references/agent-patterns.md +149 -0
  37. package/skills/api-designer/SKILL.md +429 -0
  38. package/skills/api-designer/references/api-standards.md +13 -0
  39. package/skills/architect/SKILL.md +285 -0
  40. package/skills/architect/references/c4-model.md +133 -0
  41. package/skills/automation-engineer/SKILL.md +352 -0
  42. package/skills/automation-engineer/references/n8n-patterns.md +127 -0
  43. package/skills/backend-engineer/SKILL.md +261 -0
  44. package/skills/backend-engineer/assets/fastapi-project-structure.yaml +74 -0
  45. package/skills/backend-engineer/references/debugging-guide.md +174 -0
  46. package/skills/backend-engineer/references/design-patterns.md +208 -0
  47. package/skills/backend-engineer/scripts/scaffold_backend.py +313 -0
  48. package/skills/bmad-methodology/SKILL.md +202 -0
  49. package/skills/bmad-methodology/references/scale-adaptive-levels.md +141 -0
  50. package/skills/browser-agent/SKILL.md +502 -0
  51. package/skills/browser-agent/scripts/playwright_setup.ts +16 -0
  52. package/skills/code-reviewer/SKILL.md +306 -0
  53. package/skills/code-reviewer/references/code-review-checklist.md +16 -0
  54. package/skills/data-engineer/SKILL.md +474 -0
  55. package/skills/data-engineer/assets/pg-monitoring-queries.sql +154 -0
  56. package/skills/data-engineer/references/index-strategy.md +128 -0
  57. package/skills/data-engineer/scripts/backup_postgres.py +221 -0
  58. package/skills/devops-engineer/SKILL.md +547 -0
  59. package/skills/devops-engineer/references/ci-cd-patterns.md +265 -0
  60. package/skills/devops-engineer/scripts/docker_healthcheck.py +125 -0
  61. package/skills/document-generator/SKILL.md +746 -0
  62. package/skills/document-generator/references/pdf-generation.md +22 -0
  63. package/skills/frontend-engineer/SKILL.md +532 -0
  64. package/skills/frontend-engineer/references/accessibility-guide.md +146 -0
  65. package/skills/frontend-engineer/scripts/audit_bundle.py +144 -0
  66. package/skills/git-workflow/SKILL.md +374 -0
  67. package/skills/git-workflow/references/git-flow.md +25 -0
  68. package/skills/mcp-builder/SKILL.md +471 -0
  69. package/skills/mcp-builder/references/mcp-server-guide.md +23 -0
  70. package/skills/mobile-engineer/SKILL.md +502 -0
  71. package/skills/mobile-engineer/references/platform-guidelines.md +160 -0
  72. package/skills/orchestrator/SKILL.md +246 -0
  73. package/skills/orchestrator/references/methodology-routing.md +117 -0
  74. package/skills/orchestrator/references/persona-mapping.md +85 -0
  75. package/skills/orchestrator/references/routing-logic.md +110 -0
  76. package/skills/performance-engineer/SKILL.md +549 -0
  77. package/skills/performance-engineer/references/caching-patterns.md +181 -0
  78. package/skills/performance-engineer/scripts/profile_endpoint.py +170 -0
  79. package/skills/product-manager/SKILL.md +488 -0
  80. package/skills/product-manager/references/prioritization-frameworks.md +126 -0
  81. package/skills/prompt-engineer/SKILL.md +433 -0
  82. package/skills/prompt-engineer/references/prompt-patterns.md +158 -0
  83. package/skills/qa-engineer/SKILL.md +441 -0
  84. package/skills/qa-engineer/references/testing-strategy.md +166 -0
  85. package/skills/qa-engineer/scripts/run_coverage.py +147 -0
  86. package/skills/scrum-master/SKILL.md +225 -0
  87. package/skills/scrum-master/references/sprint-ceremonies.md +159 -0
  88. package/skills/security-analyst/SKILL.md +390 -0
  89. package/skills/security-analyst/references/owasp-top10.md +188 -0
  90. package/skills/security-analyst/scripts/audit_security.py +242 -0
  91. package/skills/seo-auditor/SKILL.md +523 -0
  92. package/skills/seo-auditor/references/seo-checklist.md +17 -0
  93. package/skills/spec-driven-dev/SKILL.md +342 -0
  94. package/skills/spec-driven-dev/references/phase-gates.md +107 -0
  95. package/skills/supabase-expert/SKILL.md +602 -0
  96. package/skills/supabase-expert/references/supabase-patterns.md +19 -0
  97. package/skills/swe-agent/SKILL.md +311 -0
  98. package/skills/swe-agent/references/trajectory-format.md +134 -0
  99. package/skills/systematic-debugger/SKILL.md +512 -0
  100. package/skills/systematic-debugger/references/debugging-guide.md +12 -0
  101. package/skills/tech-lead/SKILL.md +409 -0
  102. package/skills/tech-lead/references/code-review-checklist.md +111 -0
  103. package/skills/technical-writer/SKILL.md +631 -0
  104. package/skills/technical-writer/references/doc-templates.md +218 -0
  105. package/skills/testing-strategist/SKILL.md +476 -0
  106. package/skills/testing-strategist/references/testing-pyramid.md +16 -0
  107. package/skills/ux-ui-designer/SKILL.md +419 -0
  108. package/skills/ux-ui-designer/references/design-system-foundation.md +168 -0
  109. package/skills_overview.txt +94 -0
  110. package/templates/PROJECT_KICKOFF.md +284 -0
  111. package/templates/SKILL_TEMPLATE.md +131 -0
  112. package/templates/USAGE.md +95 -0
  113. package/templates/agent-python/README.md +71 -0
  114. package/templates/agent-python/agent.py +272 -0
  115. package/templates/agent-python/config.yaml +76 -0
  116. package/templates/agent-python/prompts/system.md +109 -0
  117. package/templates/agent-python/requirements.txt +7 -0
  118. package/templates/automation-n8n/README.md +14 -0
  119. package/templates/automation-n8n/webhook-handler.json +57 -0
  120. package/templates/backend-node/Dockerfile +12 -0
  121. package/templates/backend-node/README.md +15 -0
  122. package/templates/backend-node/package.json +30 -0
  123. package/templates/backend-node/src/index.ts +19 -0
  124. package/templates/backend-node/src/routes.ts +7 -0
  125. package/templates/backend-node/tsconfig.json +22 -0
  126. package/templates/backend-python/Dockerfile +11 -0
  127. package/templates/backend-python/README.md +78 -0
  128. package/templates/backend-python/app/core/config.py +12 -0
  129. package/templates/backend-python/app/core/database.py +12 -0
  130. package/templates/backend-python/app/main.py +17 -0
  131. package/templates/backend-python/app/routers/__init__.py +1 -0
  132. package/templates/backend-python/app/routers/health.py +7 -0
  133. package/templates/backend-python/requirements-dev.txt +6 -0
  134. package/templates/backend-python/requirements.txt +4 -0
  135. package/templates/backend-python/tests/test_health.py +9 -0
  136. package/templates/checkpoint.yaml +117 -0
  137. package/templates/database/README.md +474 -0
  138. package/templates/frontend-react/README.md +446 -0
  139. package/templates/plan.yaml +320 -0
  140. package/templates/session.yaml +125 -0
  141. package/templates/spec.yaml +229 -0
  142. package/templates/tasks.yaml +330 -0
  143. package/workflows/bugfix-backend.md +380 -0
  144. package/workflows/documentation.md +232 -0
  145. package/workflows/generate-prd.md +320 -0
  146. package/workflows/ideation.md +396 -0
  147. package/workflows/new-agent-ia.md +497 -0
  148. package/workflows/new-automation.md +374 -0
  149. package/workflows/new-feature.md +290 -0
  150. package/workflows/optimize-performance.md +373 -0
  151. package/workflows/resolve-github-issue.md +524 -0
  152. package/workflows/security-review.md +291 -0
  153. package/workflows/spec-driven.md +476 -0
  154. package/workflows/testing-strategy.md +296 -0
  155. package/workflows/third-party-integration.md +277 -0
@@ -0,0 +1,570 @@
1
+ # Guía de Estilo de Código - LMAgent
2
+
3
+ > **Tipo**: `rule` | **Versión**: 2.1 | **Actualización**: 2026-01
4
+
5
+ ## 📌 Quick Reference
6
+
7
+ | Regla | Python | TypeScript |
8
+ |-------|--------|------------|
9
+ | **Naming** | `snake_case` funciones/vars, `PascalCase` clases | `camelCase` funciones/vars, `PascalCase` clases |
10
+ | **Indentación** | 4 espacios | 2 espacios |
11
+ | **Línea máx** | 88 chars | 100 chars |
12
+ | **Types** | OBLIGATORIO (type hints) | OBLIGATORIO (strict TS) |
13
+ | **Lint** | `ruff check .` + `ruff format .` | `eslint .` + `prettier` |
14
+ | **Imports** | Stdlib → Third-party → Local | Built-in → External → Internal |
15
+
16
+ ### 👥 Roles que usan esta regla
17
+ `backend-engineer`, `frontend-engineer`, `mobile-engineer`, `qa-engineer`
18
+
19
+ ---
20
+
21
+ Este documento define las convenciones de estilo para Python y TypeScript.
22
+
23
+ ## Python
24
+
25
+ ### Herramientas
26
+ ```bash
27
+ # Linting y formatting
28
+ ruff check . # Linting
29
+ ruff format . # Formatting (reemplaza black)
30
+
31
+ # Type checking (opcional pero recomendado)
32
+ mypy app/
33
+ ```
34
+
35
+ ### Configuración (pyproject.toml)
36
+ ```toml
37
+ [tool.ruff]
38
+ target-version = "py311"
39
+ line-length = 88
40
+ select = [
41
+ "E", # pycodestyle errors
42
+ "W", # pycodestyle warnings
43
+ "F", # Pyflakes
44
+ "I", # isort
45
+ "B", # flake8-bugbear
46
+ "C4", # flake8-comprehensions
47
+ "UP", # pyupgrade
48
+ ]
49
+ ignore = [
50
+ "E501", # line too long (handled by formatter)
51
+ ]
52
+
53
+ [tool.ruff.isort]
54
+ known-first-party = ["app"]
55
+ ```
56
+
57
+ ### Imports
58
+
59
+ ```python
60
+ # ✅ Correcto - Agrupados y ordenados
61
+ from __future__ import annotations
62
+
63
+ # Standard library
64
+ import json
65
+ from datetime import datetime
66
+ from typing import Optional, List
67
+
68
+ # Third party
69
+ from fastapi import APIRouter, Depends, HTTPException
70
+ from pydantic import BaseModel
71
+ from sqlmodel import Session, select
72
+
73
+ # Local
74
+ from app.config import settings
75
+ from app.core.database import get_session
76
+ from app.models.user import User
77
+
78
+ # ❌ Incorrecto
79
+ from app.models.user import * # No usar import *
80
+ import json, os, sys # No múltiples en una línea
81
+ ```
82
+
83
+ ### Naming Conventions
84
+
85
+ ```python
86
+ # Módulos y archivos: snake_case
87
+ user_service.py
88
+ database_utils.py
89
+
90
+ # Clases: PascalCase
91
+ class UserService:
92
+ pass
93
+
94
+ class HTTPRequestHandler: # Acronyms en mayúsculas
95
+ pass
96
+
97
+ # Funciones y métodos: snake_case
98
+ def get_user_by_email(email: str) -> User:
99
+ pass
100
+
101
+ async def fetch_external_data():
102
+ pass
103
+
104
+ # Variables: snake_case
105
+ user_count = 0
106
+ is_active = True
107
+ api_response = {}
108
+
109
+ # Constantes: UPPER_SNAKE_CASE
110
+ MAX_RETRY_COUNT = 3
111
+ DEFAULT_TIMEOUT = 30
112
+ API_VERSION = "v1"
113
+
114
+ # Privados: prefijo _
115
+ def _internal_helper():
116
+ pass
117
+
118
+ class MyClass:
119
+ def __init__(self):
120
+ self._private_attr = None
121
+ ```
122
+
123
+ ### Type Hints (Obligatorios)
124
+
125
+ ```python
126
+ # ✅ Correcto - Type hints en todo
127
+ from typing import Optional, List, Dict, Any
128
+
129
+ def process_user(
130
+ user_id: int,
131
+ options: Optional[Dict[str, Any]] = None
132
+ ) -> User:
133
+ """Procesa un usuario por ID."""
134
+ pass
135
+
136
+ async def fetch_users(
137
+ limit: int = 10,
138
+ offset: int = 0
139
+ ) -> List[User]:
140
+ """Obtiene lista de usuarios paginada."""
141
+ pass
142
+
143
+ # Variables con tipos cuando no es obvio
144
+ users: List[User] = []
145
+ config: Dict[str, Any] = load_config()
146
+
147
+ # ❌ Incorrecto - Sin types
148
+ def process_user(user_id, options=None):
149
+ pass
150
+ ```
151
+
152
+ ### Docstrings
153
+
154
+ ```python
155
+ def calculate_discount(
156
+ price: float,
157
+ discount_percent: float,
158
+ max_discount: Optional[float] = None
159
+ ) -> float:
160
+ """
161
+ Calcula el precio con descuento aplicado.
162
+
163
+ Args:
164
+ price: Precio original del producto.
165
+ discount_percent: Porcentaje de descuento (0-100).
166
+ max_discount: Descuento máximo permitido en valor absoluto.
167
+
168
+ Returns:
169
+ Precio final después de aplicar el descuento.
170
+
171
+ Raises:
172
+ ValueError: Si discount_percent está fuera de rango (0-100).
173
+
174
+ Example:
175
+ >>> calculate_discount(100.0, 20.0)
176
+ 80.0
177
+ >>> calculate_discount(100.0, 50.0, max_discount=30.0)
178
+ 70.0
179
+ """
180
+ if not 0 <= discount_percent <= 100:
181
+ raise ValueError("discount_percent must be between 0 and 100")
182
+
183
+ discount = price * (discount_percent / 100)
184
+ if max_discount is not None:
185
+ discount = min(discount, max_discount)
186
+
187
+ return price - discount
188
+
189
+
190
+ class UserService:
191
+ """
192
+ Servicio para gestión de usuarios.
193
+
194
+ Maneja la lógica de negocio relacionada con usuarios,
195
+ incluyendo creación, actualización y validaciones.
196
+
197
+ Attributes:
198
+ repository: Repositorio para acceso a datos de usuarios.
199
+ cache: Cliente de cache para optimización.
200
+
201
+ Example:
202
+ >>> service = UserService(repository, cache)
203
+ >>> user = await service.create({"email": "test@example.com"})
204
+ """
205
+ ```
206
+
207
+ ### Clases y Métodos
208
+
209
+ ```python
210
+ from abc import ABC, abstractmethod
211
+ from typing import Optional
212
+
213
+ class BaseService(ABC):
214
+ """Clase base para servicios."""
215
+
216
+ def __init__(self, repository: BaseRepository):
217
+ self.repository = repository
218
+ self._cache: Dict[str, Any] = {}
219
+
220
+ @abstractmethod
221
+ async def get_by_id(self, id: int) -> Optional[Model]:
222
+ """Obtiene entidad por ID."""
223
+ pass
224
+
225
+ async def get_all(self, limit: int = 100) -> List[Model]:
226
+ """Obtiene todas las entidades."""
227
+ return await self.repository.find_all(limit=limit)
228
+
229
+
230
+ class UserService(BaseService):
231
+ """Servicio de usuarios."""
232
+
233
+ async def get_by_id(self, id: int) -> Optional[User]:
234
+ """Obtiene usuario por ID."""
235
+ # Intentar cache primero
236
+ cache_key = f"user:{id}"
237
+ if cache_key in self._cache:
238
+ return self._cache[cache_key]
239
+
240
+ user = await self.repository.find_by_id(id)
241
+ if user:
242
+ self._cache[cache_key] = user
243
+
244
+ return user
245
+
246
+ async def create(self, data: UserCreate) -> User:
247
+ """Crea un nuevo usuario."""
248
+ # Validar
249
+ self._validate_email(data.email)
250
+
251
+ # Crear
252
+ user = await self.repository.create(data)
253
+
254
+ # Invalidar cache
255
+ self._cache.clear()
256
+
257
+ return user
258
+
259
+ def _validate_email(self, email: str) -> None:
260
+ """Valida formato de email."""
261
+ if "@" not in email:
262
+ raise ValueError("Invalid email format")
263
+ ```
264
+
265
+ ### Async/Await
266
+
267
+ ```python
268
+ # ✅ Correcto - Consistente uso de async
269
+ async def fetch_user_data(user_id: int) -> UserData:
270
+ """Obtiene datos completos del usuario."""
271
+ # Ejecutar en paralelo cuando sea posible
272
+ user, orders, preferences = await asyncio.gather(
273
+ get_user(user_id),
274
+ get_orders(user_id),
275
+ get_preferences(user_id)
276
+ )
277
+
278
+ return UserData(user=user, orders=orders, preferences=preferences)
279
+
280
+ # ❌ Incorrecto - Blocking en código async
281
+ async def bad_fetch():
282
+ import requests # Blocking!
283
+ response = requests.get(url) # Bloquea el event loop
284
+ ```
285
+
286
+ ### Manejo de Errores
287
+
288
+ ```python
289
+ # Definir excepciones específicas
290
+ class ServiceError(Exception):
291
+ """Error base para servicios."""
292
+ pass
293
+
294
+ class NotFoundError(ServiceError):
295
+ """Recurso no encontrado."""
296
+ pass
297
+
298
+ class ValidationError(ServiceError):
299
+ """Error de validación."""
300
+ def __init__(self, field: str, message: str):
301
+ self.field = field
302
+ self.message = message
303
+ super().__init__(f"{field}: {message}")
304
+
305
+ # Uso
306
+ async def get_user(user_id: int) -> User:
307
+ user = await repository.find_by_id(user_id)
308
+ if not user:
309
+ raise NotFoundError(f"User {user_id} not found")
310
+ return user
311
+
312
+ # En routers, convertir a HTTPException
313
+ @router.get("/users/{user_id}")
314
+ async def get_user_endpoint(user_id: int):
315
+ try:
316
+ return await service.get_user(user_id)
317
+ except NotFoundError as e:
318
+ raise HTTPException(status_code=404, detail=str(e))
319
+ except ValidationError as e:
320
+ raise HTTPException(status_code=400, detail=str(e))
321
+ ```
322
+
323
+ ---
324
+
325
+ ## TypeScript
326
+
327
+ ### Herramientas
328
+ ```bash
329
+ # Linting y formatting
330
+ eslint .
331
+ prettier --write .
332
+
333
+ # Type checking
334
+ tsc --noEmit
335
+ ```
336
+
337
+ ### Configuración (tsconfig.json)
338
+ ```json
339
+ {
340
+ "compilerOptions": {
341
+ "target": "ES2022",
342
+ "module": "NodeNext",
343
+ "moduleResolution": "NodeNext",
344
+ "strict": true,
345
+ "esModuleInterop": true,
346
+ "skipLibCheck": true,
347
+ "forceConsistentCasingInFileNames": true,
348
+ "declaration": true,
349
+ "outDir": "./dist"
350
+ },
351
+ "include": ["src/**/*"],
352
+ "exclude": ["node_modules", "dist"]
353
+ }
354
+ ```
355
+
356
+ ### Naming Conventions
357
+
358
+ ```typescript
359
+ // Archivos: kebab-case
360
+ user-service.ts
361
+ database-utils.ts
362
+
363
+ // Interfaces: PascalCase con prefijo I (opcional)
364
+ interface User {
365
+ id: number;
366
+ email: string;
367
+ }
368
+
369
+ interface IUserService { // Prefijo I para interfaces de servicio
370
+ getUser(id: number): Promise<User>;
371
+ }
372
+
373
+ // Types: PascalCase
374
+ type UserId = number;
375
+ type UserRole = 'admin' | 'user' | 'guest';
376
+
377
+ // Clases: PascalCase
378
+ class UserService implements IUserService {
379
+ // ...
380
+ }
381
+
382
+ // Funciones y métodos: camelCase
383
+ function getUserById(id: number): Promise<User> {
384
+ // ...
385
+ }
386
+
387
+ // Variables: camelCase
388
+ const userCount = 0;
389
+ const isActive = true;
390
+
391
+ // Constantes: UPPER_SNAKE_CASE o camelCase
392
+ const MAX_RETRY_COUNT = 3;
393
+ const defaultTimeout = 30;
394
+
395
+ // Enums: PascalCase para nombre y valores
396
+ enum UserRole {
397
+ Admin = 'admin',
398
+ User = 'user',
399
+ Guest = 'guest',
400
+ }
401
+ ```
402
+
403
+ ### Types (Obligatorios)
404
+
405
+ ```typescript
406
+ // ✅ Correcto - Types explícitos
407
+ interface CreateUserDto {
408
+ email: string;
409
+ name: string;
410
+ role?: UserRole;
411
+ }
412
+
413
+ interface UserResponse {
414
+ id: number;
415
+ email: string;
416
+ name: string;
417
+ createdAt: Date;
418
+ }
419
+
420
+ async function createUser(data: CreateUserDto): Promise<UserResponse> {
421
+ // ...
422
+ }
423
+
424
+ // Usar generics cuando sea apropiado
425
+ interface Repository<T> {
426
+ findById(id: number): Promise<T | null>;
427
+ create(data: Partial<T>): Promise<T>;
428
+ update(id: number, data: Partial<T>): Promise<T>;
429
+ delete(id: number): Promise<void>;
430
+ }
431
+
432
+ class UserRepository implements Repository<User> {
433
+ // ...
434
+ }
435
+
436
+ // ❌ Incorrecto - Usar any
437
+ function processData(data: any): any {
438
+ // Evitar any, usar unknown si es necesario
439
+ }
440
+ ```
441
+
442
+ ### Imports
443
+
444
+ ```typescript
445
+ // ✅ Correcto - Organizados
446
+ // Node built-ins
447
+ import { readFile } from 'fs/promises';
448
+ import path from 'path';
449
+
450
+ // External packages
451
+ import express, { Request, Response } from 'express';
452
+ import { PrismaClient } from '@prisma/client';
453
+
454
+ // Internal - absolute imports
455
+ import { UserService } from '@/services/user-service';
456
+ import { User } from '@/models/user';
457
+
458
+ // Internal - relative imports
459
+ import { validateEmail } from './utils';
460
+ ```
461
+
462
+ ### Error Handling
463
+
464
+ ```typescript
465
+ // Custom errors
466
+ class AppError extends Error {
467
+ constructor(
468
+ public statusCode: number,
469
+ message: string,
470
+ public isOperational = true
471
+ ) {
472
+ super(message);
473
+ Object.setPrototypeOf(this, AppError.prototype);
474
+ }
475
+ }
476
+
477
+ class NotFoundError extends AppError {
478
+ constructor(resource: string) {
479
+ super(404, `${resource} not found`);
480
+ }
481
+ }
482
+
483
+ class ValidationError extends AppError {
484
+ constructor(
485
+ public field: string,
486
+ message: string
487
+ ) {
488
+ super(400, `${field}: ${message}`);
489
+ }
490
+ }
491
+
492
+ // Uso
493
+ async function getUser(id: number): Promise<User> {
494
+ const user = await prisma.user.findUnique({ where: { id } });
495
+ if (!user) {
496
+ throw new NotFoundError('User');
497
+ }
498
+ return user;
499
+ }
500
+
501
+ // Error handler middleware
502
+ function errorHandler(
503
+ err: Error,
504
+ req: Request,
505
+ res: Response,
506
+ next: NextFunction
507
+ ): void {
508
+ if (err instanceof AppError) {
509
+ res.status(err.statusCode).json({
510
+ error: err.message,
511
+ ...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
512
+ });
513
+ } else {
514
+ res.status(500).json({ error: 'Internal server error' });
515
+ }
516
+ }
517
+ ```
518
+
519
+ ---
520
+
521
+ ## Reglas Comunes
522
+
523
+ ### Comentarios
524
+
525
+ ```python
526
+ # ✅ Comentarios que explican POR QUÉ, no QUÉ
527
+ # Usamos cache de 5 minutos porque los datos de usuario
528
+ # cambian con poca frecuencia pero se consultan mucho
529
+ CACHE_TTL = 300
530
+
531
+ # ❌ Comentarios innecesarios
532
+ # Incrementar contador
533
+ counter += 1 # Increment counter
534
+ ```
535
+
536
+ ### TODO y FIXME
537
+
538
+ ```python
539
+ # TODO: Implementar paginación cuando tengamos más de 1000 usuarios
540
+ # FIXME: Este workaround es necesario por bug en librería X, remover en v2.0
541
+ # HACK: Solución temporal hasta que se resuelva issue #123
542
+ ```
543
+
544
+ ### Longitud de Línea
545
+ - Máximo: 88 caracteres (Python), 100 caracteres (TypeScript)
546
+ - Preferir líneas más cortas cuando sea posible
547
+
548
+ ### Espaciado
549
+ - 4 espacios para indentación (Python)
550
+ - 2 espacios para indentación (TypeScript)
551
+ - Una línea en blanco entre funciones/métodos
552
+ - Dos líneas en blanco entre clases
553
+
554
+ ---
555
+
556
+ ## ✅ Checklist de Validación (Antes de PR)
557
+
558
+ ### Python
559
+ - [ ] `ruff check .` pasa sin errores
560
+ - [ ] `ruff format --check .` pasa
561
+ - [ ] Type hints en todas las funciones públicas
562
+ - [ ] Docstrings en funciones públicas
563
+ - [ ] Imports ordenados (stdlib → 3rd party → local)
564
+
565
+ ### TypeScript
566
+ - [ ] `eslint .` pasa sin errores
567
+ - [ ] `prettier --check .` pasa
568
+ - [ ] `tsc --noEmit` sin errores de tipos
569
+ - [ ] Sin uso de `any`
570
+ - [ ] Imports ordenados
@@ -0,0 +1,98 @@
1
+ # Documentación Continua
2
+
3
+ > **Tipo**: `rule` | **Versión**: 2.1 | **Actualización**: 2026-01
4
+
5
+ ## 📌 Quick Reference
6
+
7
+ | ¿Qué documentar? | ¿Dónde? |
8
+ |------------------|--------|
9
+ | Decisiones de stack | `rules/stack.md` |
10
+ | Patrones de código | `rules/code-style.md` |
11
+ | Flujos de trabajo | `rules/workflow.md` |
12
+ | Comandos del proyecto | `config/commands.yaml` |
13
+ | Cambios de versión | `CHANGELOG.md` |
14
+
15
+ ### Regla de Oro
16
+ > "⚡ Si pensaste más de 5 minutos en algo, probablemente vale la pena documentarlo."
17
+
18
+ ### 👥 Roles que usan esta regla
19
+ `technical-writer`, `backend-engineer`, `frontend-engineer`, `architect`
20
+
21
+ ---
22
+
23
+ > ⚠️ **REGLA CRÍTICA**: Esta regla debe aplicarse SIEMPRE, en cada sesión de trabajo.
24
+
25
+ ## Cuándo Documentar
26
+
27
+ ### Después de CADA implementación significativa:
28
+
29
+ 1. **Nuevas funcionalidades** → Actualizar README o docs relevantes
30
+ 2. **Cambios de arquitectura** → Actualizar `rules/stack.md` o crear diagrama
31
+ 3. **Nuevos patrones** → Documentar en reglas aplicables
32
+ 4. **Bugs resueltos** → Agregar a CHANGELOG o notas
33
+ 5. **Decisiones técnicas** → Documentar el "por qué"
34
+
35
+ ### Al usar el framework:
36
+
37
+ 1. **Nuevas reglas aprendidas** → Agregar a `rules/`
38
+ 2. **Workflows útiles** → Crear en `workflows/`
39
+ 3. **Comandos frecuentes** → Agregar a `config/commands.yaml`
40
+ 4. **Personas personalizadas** → Crear en `personas/`
41
+
42
+ ## Qué Documentar
43
+
44
+ | Tipo | Dónde | Ejemplo |
45
+ |------|-------|---------|
46
+ | Decisiones de stack | `rules/stack.md` | "Usamos PostgreSQL porque..." |
47
+ | Patrones de código | `rules/code-style.md` | "Nombres de funciones en snake_case" |
48
+ | Flujos de trabajo | `rules/workflow.md` | "PRs requieren 2 reviewers" |
49
+ | Comandos del proyecto | `config/commands.yaml` | Alias personalizados |
50
+ | Changelog | `CHANGELOG.md` | Versiones y cambios |
51
+
52
+ ## Instrucciones para el Agente
53
+
54
+ > **SIEMPRE al finalizar una tarea**:
55
+
56
+ ```markdown
57
+ ## Checklist de Cierre
58
+
59
+ - [ ] ¿Creé algo nuevo que otros deberían saber?
60
+ - [ ] ¿Cambié algún patrón o convención?
61
+ - [ ] ¿Resolví un problema que podría repetirse?
62
+ - [ ] ¿Las reglas actuales siguen siendo válidas?
63
+
64
+ Si respondí SÍ a cualquiera → ACTUALIZAR DOCUMENTACIÓN
65
+ ```
66
+
67
+ ## Formato Recomendado
68
+
69
+ ### Para reglas nuevas:
70
+
71
+ ```markdown
72
+ ## [Nombre de la Regla]
73
+
74
+ **Contexto**: Por qué existe esta regla
75
+ **Regla**: Qué hacer específicamente
76
+ **Ejemplo**: Código o configuración de ejemplo
77
+ **Excepciones**: Cuándo no aplica (si hay)
78
+ ```
79
+
80
+ ### Para cambios:
81
+
82
+ ```markdown
83
+ ## [Fecha] - [Título del Cambio]
84
+
85
+ **Antes**: Cómo era
86
+ **Después**: Cómo es ahora
87
+ **Razón**: Por qué se cambió
88
+ ```
89
+
90
+ ## Recordatorio Automático
91
+
92
+ Si el agente no documenta cambios significativos, recordarle:
93
+
94
+ > "¿No deberías documentar este cambio en [archivo relevante]?"
95
+
96
+ ---
97
+
98
+ **⚡ Regla de oro**: Si tuviste que pensar más de 5 minutos en algo, probablemente vale la pena documentarlo.