@ronaldjdevfs/forge 1.0.1

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 (56) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +9 -0
  3. package/README.md +338 -0
  4. package/logo.png +0 -0
  5. package/package.json +47 -0
  6. package/skills/forge/SKILL.md +207 -0
  7. package/skills/forge/command/forge.md +110 -0
  8. package/skills/forge/profiles/express-mongodb.md +289 -0
  9. package/skills/forge/profiles/express-postgres.md +164 -0
  10. package/skills/forge/profiles/express-prisma.md +116 -0
  11. package/skills/forge/profiles/fastify-postgres.md +110 -0
  12. package/skills/forge/profiles/nestjs-prisma.md +160 -0
  13. package/skills/forge/reference/cast.md +77 -0
  14. package/skills/forge/reference/chain.md +73 -0
  15. package/skills/forge/reference/forge.md +44 -0
  16. package/skills/forge/reference/inscribe.md +129 -0
  17. package/skills/forge/reference/inspect.md +58 -0
  18. package/skills/forge/reference/patterns.md +108 -0
  19. package/skills/forge/reference/principles.md +29 -0
  20. package/skills/forge/reference/quench.md +74 -0
  21. package/skills/forge/reference/reforge.md +40 -0
  22. package/skills/forge/reference/relocate.md +38 -0
  23. package/skills/forge/reference/smelt.md +31 -0
  24. package/skills/forge/reference/temper.md +49 -0
  25. package/skills/forge/scripts/architecture.mjs +176 -0
  26. package/skills/forge/scripts/armorer.mjs +421 -0
  27. package/skills/forge/scripts/bootstrap.mjs +187 -0
  28. package/skills/forge/scripts/chain.mjs +258 -0
  29. package/skills/forge/scripts/context.mjs +237 -0
  30. package/skills/forge/scripts/detect.mjs +843 -0
  31. package/skills/forge/scripts/graph.mjs +594 -0
  32. package/skills/forge/scripts/inspect.mjs +193 -0
  33. package/skills/forge/scripts/profile.mjs +92 -0
  34. package/skills/forge/templates/feature/controller.ts.md +66 -0
  35. package/skills/forge/templates/feature/entity.ts.md +11 -0
  36. package/skills/forge/templates/feature/mapper.ts.md +18 -0
  37. package/skills/forge/templates/feature/repository-impl.ts.md +59 -0
  38. package/skills/forge/templates/feature/repository-interface.ts.md +12 -0
  39. package/skills/forge/templates/feature/routes.ts.md +17 -0
  40. package/skills/forge/templates/feature/schema.ts.md +16 -0
  41. package/skills/forge/templates/feature/use-case.ts.md +19 -0
  42. package/skills/forge/templates/infra/mail.ts.md +31 -0
  43. package/skills/forge/templates/infra/mongodb.ts.md +12 -0
  44. package/skills/forge/templates/infra/prisma.ts.md +21 -0
  45. package/skills/forge/templates/infra/redis.ts.md +30 -0
  46. package/skills/forge/templates/platform/config.ts.md +37 -0
  47. package/skills/forge/templates/platform/database.ts.md +40 -0
  48. package/skills/forge/templates/platform/di.ts.md +18 -0
  49. package/skills/forge/templates/platform/http.ts.md +29 -0
  50. package/skills/forge/templates/platform/logger.ts.md +38 -0
  51. package/skills/forge/templates/platform/server.ts.md +25 -0
  52. package/skills/forge/templates/shared/contract.ts.md +20 -0
  53. package/skills/forge/templates/shared/error.ts.md +27 -0
  54. package/skills/forge/templates/shared/type.ts.md +18 -0
  55. package/skills/forge/templates/shared/util.ts.md +23 -0
  56. package/src/cli.js +179 -0
@@ -0,0 +1,44 @@
1
+ # Forge
2
+
3
+ Inicializa un proyecto para trabajar con Forge como Backend Architecture Operating System.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - Proyecto nuevo sin estructura definida
8
+ - Proyecto existente sin `ARCHITECTURE.md`
9
+ - Después de clonar un repositorio
10
+ - Para bootstrappear los layers Platform, Shared e Infrastructure
11
+
12
+ ## Flujo
13
+
14
+ 1. Ejecutar `scripts/context.mjs` para detectar stack actual (incluye platform, features, shared, infra)
15
+ 2. Ejecutar `scripts/bootstrap.mjs` para crear layers faltantes (platform, shared, infra)
16
+ 3. Ejecutar `scripts/profile.mjs` para determinar perfil tecnológico
17
+ 4. Ejecutar `scripts/armorer.mjs` para detectar ownership y huérfanos
18
+ 5. Ejecutar `scripts/graph.mjs` para construir grafo arquitectónico global
19
+ 6. Ejecutar `scripts/chain.mjs` para analizar dependencias multi-capa
20
+ 7. Si `ARCHITECTURE.md` no existe, crearlo con `forge inscribe`
21
+ 8. Si faltan dependencias clave (según perfil), listarlas
22
+ 9. Si el proyecto tiene código legacy, sugerir `forge relocate`
23
+ 10. Si el proyecto está listo, sugerir `forge cast`
24
+
25
+ ## Output esperado
26
+
27
+ - `ARCHITECTURE.md` creado en la raíz del proyecto
28
+ - Layers Platform, Shared e Infrastructure creados si no existían
29
+ - Perfil tecnológico detectado y registrado
30
+ - Ownership analizado
31
+ - Dependencias base verificadas
32
+ - Próximos pasos sugeridos según el estado del proyecto
33
+
34
+ ## Severidades
35
+
36
+ | Condición | Severidad |
37
+ |---|---|
38
+ | Sin `src/` directory | ERROR |
39
+ | Sin `package.json` | ERROR |
40
+ | Sin perfil detectable | WARNING |
41
+ | Sin `ARCHITECTURE.md` | INFO |
42
+ | Platform layer ausente | SUGGESTION |
43
+ | Dependencias faltantes | WARNING |
44
+ | Ownership con huérfanos | WARNING |
@@ -0,0 +1,129 @@
1
+ # Inscribe
2
+
3
+ Genera y mantiene el archivo `ARCHITECTURE.md` del proyecto.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - Proyecto nuevo (crear ARCHITECTURE.md inicial)
8
+ - Después de migrar un feature (actualizar estado)
9
+ - Después de refactorizar (actualizar decisiones)
10
+ - Cuando se detecta que ARCHITECTURE.md está desactualizado
11
+ - On demand: `forge inscribe`
12
+
13
+ ## Formato generado
14
+
15
+ ```md
16
+ # Architecture State
17
+
18
+ **Project Name:** <detectado>
19
+ **Framework:** <detectado>
20
+ **Runtime:** <detectado>
21
+ **Database:** <detectado>
22
+ **ORM:** <detectado>
23
+ **DI Strategy:** <detectado>
24
+ **Profile:** <detectado>
25
+ **Architecture:** hexagonal-feature (Platform + Features + Shared + Infra)
26
+ **Last Audit:** <fecha> (score: <puntaje>)
27
+
28
+ ## Platform
29
+ - platform/config/
30
+ - platform/database/
31
+ - platform/http/
32
+ - platform/logger/
33
+
34
+ ## Features
35
+ - features/users/
36
+ - features/payments/
37
+
38
+ ## Shared
39
+ - shared/errors/
40
+ - shared/types/
41
+ - shared/utils/
42
+
43
+ ## Infrastructure
44
+ - infra/prisma/
45
+ - infra/redis/
46
+
47
+ ## Ownership
48
+ **Health:** healthy | degraded | critical
49
+ **Score:** 85/100
50
+ **Orphans:** 0
51
+ **Duplicates:** 0
52
+ **Misplaced:** 0
53
+
54
+ ## Architecture Graph
55
+ **Nodes:** 15
56
+ **Edges:** 20
57
+ **Risk Score:** 12/100
58
+ **Health:** healthy
59
+ **Dependency Health:** 95%
60
+
61
+ ### Platform Layer
62
+ - `platform:config` — config
63
+
64
+ ### Feature Layer
65
+ - `feature:users` — users
66
+
67
+ ### Shared Layer
68
+ - `shared:errors` — errors
69
+
70
+ ### Infrastructure Layer
71
+ - `infra:prisma` — prisma
72
+
73
+ ### Domain Layer
74
+ - `domain:users` — users/domain
75
+
76
+ ### Adapter Layer
77
+ - `adapter:users` — users/adapters
78
+
79
+ ### Violations
80
+ | Rule | From | To | Severity | Description |
81
+ |------|------|----|----------|-------------|
82
+ | R1 | `feature:users` | `infra:prisma` | CRITICAL | Features no acceden infraestructura directamente |
83
+
84
+ ### Dependency Graph
85
+ - `feature:users` → [domain:users, adapter:users]
86
+
87
+ ## Dependency Health
88
+ **Valid Edges:** 19/20
89
+ **Dependency Health:** 95%
90
+ **Risk Score:** 12/100
91
+ **Health:** healthy
92
+
93
+ ## Violations
94
+ ...
95
+
96
+ ## Context
97
+ ...
98
+
99
+ ## Tech Stack
100
+ ...
101
+ ```
102
+
103
+ ## Campos auto-detectados
104
+
105
+ | Campo | Fuente |
106
+ |---|---|
107
+ | Framework | `scripts/context.mjs` |
108
+ | Database | `scripts/context.mjs` |
109
+ | ORM | `scripts/context.mjs` |
110
+ | DI Strategy | `scripts/context.mjs` |
111
+ | Active Profile | `scripts/profile.mjs` |
112
+ | Platform | `scripts/context.mjs` → platform |
113
+ | Features | `scripts/context.mjs` → features |
114
+ | Shared | `scripts/context.mjs` → shared |
115
+ | Infra | `scripts/context.mjs` → infra |
116
+ | Ownership | `scripts/armorer.mjs` |
117
+ | Architecture Graph | `scripts/graph.mjs` |
118
+ | Risk Score | `scripts/graph.mjs` → stats.riskScore |
119
+ | Violations | `scripts/graph.mjs` → violations |
120
+ | Last Audit | `scripts/inspect.mjs` → fecha + score |
121
+
122
+ ## Reglas
123
+
124
+ - ARCHITECTURE.md se guarda en la raíz del proyecto
125
+ - Forge lo lee antes de cada ejecución
126
+ - Si está desactualizado (última auditoría > 7 días), Forge sugiere actualizarlo
127
+ - Se actualiza automáticamente después de cada comando
128
+ - No editar manualmente los campos auto-detectados
129
+ - Forge preserva cualquier sección adicional que el usuario agregue
@@ -0,0 +1,58 @@
1
+ # Inspect
2
+
3
+ Inspecciona la conformidad arquitectónica del proyecto.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - Diagnóstico inicial del proyecto
8
+ - Post-migración de feature
9
+ - On demand para verificar estado actual
10
+ - Pre-deploy para garantizar calidad arquitectónica
11
+
12
+ ## Flujo
13
+
14
+ 1. Ejecutar `scripts/context.mjs` → detectar stack y estructura
15
+ 2. Ejecutar `scripts/profile.mjs` → determinar perfil activo
16
+ 3. Ejecutar `scripts/chain.mjs` → construir cadena de dependencias
17
+ 4. Ejecutar `scripts/detect.mjs` → detectar todas las violaciones
18
+ 5. Construir reporte con puntuación y severidades
19
+ 6. Mostrar resultado al usuario
20
+
21
+ ## Categorías
22
+
23
+ | Categoría | Pts | Qué mide |
24
+ |---|---|---|
25
+ | Estructura | 30 | Features completos (domain, application, adapters) |
26
+ | Capas | 25 | Imports prohibidos, lógica en controllers, BD directa |
27
+ | Decoradores | 20 | @injectable y @inject presentes donde corresponde |
28
+ | Legacy | 15 | Archivos residuales en ubicaciones antiguas |
29
+ | Configuración | 10 | tsconfig, dependencias, reflect-metadata |
30
+ | Grafo | 20 | Violaciones arquitectónicas (R1-R6), risk score, salud del grafo |
31
+
32
+ ## Severidades
33
+
34
+ | Severidad | Significado | Ejemplo |
35
+ |---|---|---|
36
+ | CRITICAL | Viola principio fundamental de la arquitectura | Domain importa de adapters |
37
+ | ERROR | Viola una regla de capas o estructura | Controller con lógica de negocio |
38
+ | WARNING | Inconsistencia que requiere atención | Feature sin repository interface |
39
+ | INFO | Observación sobre el estado actual | Feature incompleto |
40
+ | SUGGESTION | Recomendación de mejora | Usar tokens de clase en @inject |
41
+
42
+ ## Interpretación del score
43
+
44
+ | Rango | Nota | Significado |
45
+ |---|---|---|
46
+ | 90-100 | A | Arquitectura sólida. Cumple todos los principios. |
47
+ | 80-89 | B | Inconsistencias menores. Fáciles de corregir. |
48
+ | 65-79 | C | Varias violaciones. Requiere trabajo estructurado. |
49
+ | 50-64 | D | Arquitectura comprometida. Migración necesaria. |
50
+ | 0-49 | F | Proyecto no migrado o con violaciones generalizadas. |
51
+
52
+ ## Ejecución
53
+
54
+ ```bash
55
+ node .opencode/skills/forge/scripts/inspect.mjs
56
+ node .opencode/skills/forge/scripts/inspect.mjs --json
57
+ node .opencode/skills/forge/scripts/detect.mjs --severity ERROR
58
+ ```
@@ -0,0 +1,108 @@
1
+ # Patterns — Naming Conventions
2
+
3
+ ## Global
4
+
5
+ | Elemento | Formato | Ejemplo |
6
+ |---|---|---|
7
+ | Directorios | `kebab-case/` | `credit-card/`, `event-bus/` |
8
+ | Archivos | `<PascalCase>.<artefacto>.ts` | `User.entity.ts` |
9
+ | Interfaces | `I<PascalCase>.<artefacto>.ts` | `IUser.repository.ts` |
10
+ | Use cases | `<Action>.uc.ts` | `CreateUser.uc.ts` |
11
+ | Clases | `PascalCase` | `UserController`, `DatabaseConfig` |
12
+ | Funciones/variables | `camelCase` | `formatDate`, `userService` |
13
+ | Constantes | `UPPER_SNAKE_CASE` | `MAX_RETRY_COUNT` |
14
+ | Tipos (type/interface puros) | `PascalCase` | `UserPayload`, `PaginatedResult` |
15
+ | Enums | `PascalCase` | `UserRole`, `OrderStatus` |
16
+ | Barrel files | `index.ts` | named exports, no `export default` |
17
+
18
+ ---
19
+
20
+ ## Platform Layer
21
+
22
+ | Directorio | Archivos |
23
+ |---|---|
24
+ | `config/` | `App.config.ts`, `Env.config.ts`, `Database.config.ts` |
25
+ | `server/` | `Server.ts`, `App.ts` |
26
+ | `database/` | `Database.config.ts`, `Connection.ts` |
27
+ | `http/` | `Router.ts`, `Auth.middleware.ts`, `Error.middleware.ts`, `RateLimiter.middleware.ts` |
28
+ | `logger/` | `Logger.config.ts`, `Logger.service.ts` |
29
+ | `cache/` | `Cache.config.ts`, `Cache.service.ts` |
30
+ | `security/` | `Auth.middleware.ts`, `Encryption.service.ts` |
31
+ | `events/` | `EventBus.ts`, `EventHandler.ts` |
32
+ | `scheduler/` | `Scheduler.config.ts`, `Scheduler.service.ts` |
33
+ | `observability/` | `Metrics.ts`, `Tracing.ts`, `Health.ts` |
34
+ | `di/` | `Container.ts`, `Tokens.ts`, `Module.ts` |
35
+
36
+ ---
37
+
38
+ ## Feature Layer
39
+
40
+ | Ruta | Archivo | Ejemplo |
41
+ |---|---|---|
42
+ | `domain/` | `<Name>.entity.ts` | `User.entity.ts` |
43
+ | `domain/` | `I<Name>.repository.ts` | `IUser.repository.ts` |
44
+ | `application/use-cases/` | `<Action>.uc.ts` | `CreateUser.uc.ts`, `GetUser.uc.ts` |
45
+ | `application/mappers/` | `<Name>.mapper.ts` | `User.mapper.ts` |
46
+ | `adapters/in/http/` | `<Name>.controller.ts` | `User.controller.ts` |
47
+ | `adapters/in/http/` | `<Name>.routes.ts` | `User.routes.ts` |
48
+ | `adapters/out/persistence/` | `<Name>.repository.ts` | `User.repository.ts` |
49
+ | `adapters/out/persistence/` | `<Name>.schema.ts` | `User.schema.ts` |
50
+
51
+ Estructura de directorios:
52
+
53
+ ```
54
+ src/features/<feature-name>/
55
+ ├── domain/
56
+ │ ├── <Domain>.entity.ts
57
+ │ └── I<Domain>.repository.ts
58
+ ├── application/
59
+ │ ├── use-cases/
60
+ │ │ ├── Create<Domain>.uc.ts
61
+ │ │ ├── Get<Domain>.uc.ts
62
+ │ │ ├── List<Domain>.uc.ts
63
+ │ │ ├── Update<Domain>.uc.ts
64
+ │ │ └── Delete<Domain>.uc.ts
65
+ │ └── mappers/
66
+ │ └── <Domain>.mapper.ts
67
+ └── adapters/
68
+ ├── in/http/
69
+ │ ├── <Domain>.controller.ts
70
+ │ └── <Domain>.routes.ts
71
+ └── out/persistence/
72
+ ├── <Domain>.repository.ts
73
+ └── <Domain>.schema.ts
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Shared Layer
79
+
80
+ | Directorio | Archivos | Ejemplo |
81
+ |---|---|---|
82
+ | `errors/` | `<Name>Error.ts` | `NotFoundError.ts`, `ValidationError.ts` |
83
+ | `contracts/` | `I<Name>.ts` | `IPaginatedResponse.ts` |
84
+ | `types/` | `<dominio>.types.ts` | `user.types.ts`, `api.types.ts` |
85
+ | `utils/` | `<util>.ts` (camelCase) | `formatDate.ts`, `pagination.ts` |
86
+
87
+ ---
88
+
89
+ ## Infra Layer
90
+
91
+ | Directorio | Archivos | Ejemplo |
92
+ |---|---|---|
93
+ | `prisma/` | `Prisma.client.ts`, `Prisma.service.ts` | — |
94
+ | `mongodb/` | `Mongo.config.ts`, `<Name>.model.ts` | `User.model.ts` |
95
+ | `redis/` | `Redis.config.ts`, `Redis.service.ts` | — |
96
+ | `mail/` | `Mail.config.ts`, `Mail.service.ts` | — |
97
+ | `s3/` | `S3.config.ts`, `S3.service.ts` | — |
98
+
99
+ ---
100
+
101
+ ## Export Conventions
102
+
103
+ - Cada directorio expone un `index.ts` barrel con named exports
104
+ - Usar `export * from "./<Name>.<artifact>.js"` en barrels
105
+ - Preferir `export function` / `export class` sobre `export default`
106
+ - Imports relativos dentro del mismo feature (`../../domain/`)
107
+ - Path alias para cross-layer: `@/platform/`, `@/shared/`, `@/infra/`
108
+ - Extension `.js` en imports (ESM compat): `import { X } from "./foo.js"`
@@ -0,0 +1,29 @@
1
+ # Principles
2
+
3
+ > Forge es una **disciplina arquitectónica**, no un template. Nace de la convicción de que el código limpio no se escribe, se forja. Combina **Arquitectura Hexagonal**, **DDD ligero** (sin sobreingeniería) y **vertical slices** para producir sistemas donde cada dominio de negocio es dueño absoluto de su destino. La inyección de dependencias no es un detalle técnico: es la herramienta que garantiza que el dominio nunca se contamine de infraestructura.
4
+
5
+ ## Principios Inquebrantables
6
+
7
+ 1. **Arquitectura hexagonal basada en features** — La unidad de organización es el feature, no la capa técnica. Cada dominio contiene su propio `domain/`, `application/` y `adapters/`. Las capas existen *dentro* de cada feature, no al revés.
8
+
9
+ 2. **DDD ligero, sin sobreingeniería** — Usa la terminología y estructura de Domain-Driven Design (entidades, repositorios, casos de uso) pero sin la rigidez académica. No crees "value objects" donde basta un `string`. No fuerces aggregate roots donde una interfaz limpia resuelve el problema. Pragmatismo sobre dogma.
10
+
11
+ 3. **Separación estricta entre dominio e infraestructura** — El dominio no sabe qué framework, base de datos o servicios externos existen. Las interfaces (puertos) están en `domain/`. Las implementaciones (adapters) están en `adapters/out/`. Esta frontera es la razón de ser de la arquitectura hexagonal.
12
+
13
+ 4. **Un feature es una unidad autónoma** — Todo lo que pertenece a un dominio vive dentro de `features/<name>/`. Entidades, repositorios, casos de uso, controladores, rutas, esquemas, mappers, DTOs. Si un archivo importa código de otro feature fuera de su directorio, la separación está rota.
14
+
15
+ 5. **Dependencias unidireccionales** — La flecha apunta SIEMPRE hacia adentro: `adapters → application → domain → (nada)`. Domain no importa nada. Application solo importa de domain y shared. Cualquier import que viole esto se rechaza en code review. No hay excepciones.
16
+
17
+ 6. **Cero lógica de negocio en controladores** — El controller parsea la request, llama al caso de uso, y responde. No valida reglas, no calcula montos, no decide flujos. Si hay un `if` con lógica de dominio en un controller, está en el lugar equivocado.
18
+
19
+ 7. **Cero acceso a BD fuera de infraestructura** — Los repositories son la ÚNICA puerta a la base de datos. Ningún use case, controller o servicio llama al ORM, toca esquemas o ejecuta queries directamente. Las operaciones de BD solo aparecen en los repositories.
20
+
21
+ 8. **Código explícito sobre código mágico** — Prefiere imports explícitos, inyección por constructor y tipos declarados sobre decoradores ocultos, proxies automáticos o registros implícitos. El código debe leerse de arriba a abajo y entender su flujo sin herramientas externas de análisis.
22
+
23
+ 9. **Inyección de dependencias disciplinada** — La inyección de dependencias es por constructor, sin service locators ni singletons globales. Si el proyecto es pequeño, DI manual basta. Si crece, usar el sistema de DI del framework o un contenedor externo. Nunca `container.resolve()` dentro de lógica de negocio.
24
+
25
+ 10. **Escalabilidad horizontal de features** — Agregar un nuevo feature NUNCA implica modificar un feature existente. Nuevo dominio = nuevo directorio `features/<name>/`, nuevos casos de uso, nuevos adapters. El acoplamiento entre features solo ocurre mediante inyección de interfaces, nunca con imports directos entre features.
26
+
27
+ 11. **El sistema es un grafo arquitectónico vivo** — Todo componente es un nodo tipado (platform, feature, shared, infra, domain, adapter, application). Toda relación es un edge validado. Las violaciones son edges prohibidos. El grafo es la fuente de verdad del sistema y se regenera en cada auditoría. Riesgo, salud y ownership se derivan del grafo, no de opiniones.
28
+
29
+ 12. **Cuatro dominios arquitectónicos con ownership estricto** — Todo backend se modela en cuatro capas: Platform (backbone técnico), Features (negocio), Shared (código puro reutilizable) e Infrastructure (implementaciones concretas). Cada componente tiene un único propietario arquitectónico. Los huérfanos, duplicados y componentes mal ubicados se detectan automáticamente. Las reglas de dependencia entre capas son obligatorias: `feature → platform → infra`, `feature → shared`, `adapter → infra`. Cualquier violación es una degradación arquitectónica.
@@ -0,0 +1,74 @@
1
+ # Quench
2
+
3
+ Valida que el proyecto cumpla las reglas arquitectónicas.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - Después de migrar un feature
8
+ - Después de crear un feature con `forge cast`
9
+ - Después de refactorizar con `forge reforge`
10
+ - Pre-commit o pre-deploy
11
+
12
+ ## Reglas críticas
13
+
14
+ | Regla | Código | Severidad | Descripción |
15
+ |---|---|---|---|
16
+ | Domain no importa infraestructura | — | CRITICAL | Domain no puede importar adapters, setting ni infraestructura |
17
+ | Application no importa adapters | — | ERROR | Application solo importa de domain y shared |
18
+ | Sin container.resolve() en use cases | — | ERROR | El contenedor solo se usa en bootstrap |
19
+ | Sin lógica de negocio en controllers | — | ERROR | Controllers solo parsean, delegan y responden |
20
+ | Sin BD directa fuera de repositorios | — | ERROR | Repositories son la única puerta a datos |
21
+ | Sin imports directos entre features | — | WARNING | Comunicación via interfaces inyectadas |
22
+ | DI consistente dentro del feature | — | WARNING | No mezclar manual + contenedor en el mismo feature |
23
+ | Tests pasando | — | ERROR | Tests deben pasar después de cualquier cambio |
24
+
25
+ ## Reglas del grafo arquitectónico
26
+
27
+ | Código | Regla | Severidad | Descripción |
28
+ |---|---|---|---|
29
+ | R1 | core → feature | CRITICAL | Core nunca debe depender de features |
30
+ | R2 | domain → infra | CRITICAL | Domain no puede importar infraestructura |
31
+ | R3 | feature → infra (directo) | CRITICAL | Features no acceden infraestructura sin adapter |
32
+ | R4 | feature → feature (directo) | ERROR | Features no se importan directamente entre sí |
33
+ | R5 | Ciclo de dependencias | ERROR | Ciclo detectado en el grafo de features |
34
+ | R6 | infra → domain/feature | WARNING | Infraestructura no debe importar dominio interno |
35
+
36
+ El grafo se construye automáticamente con `scripts/graph.mjs` y las violaciones se incluyen en `scripts/detect.mjs` (categoría `graph`).
37
+
38
+ ## Checklist pre-migración
39
+
40
+ - [ ] Dependencias del perfil instaladas (tsyringe, reflect-metadata, etc.)
41
+ - [ ] Decoradores habilitados en tsconfig (si aplica)
42
+ - [ ] Entry point configurado
43
+ - [ ] Orden topológico definido
44
+ - [ ] Dependencias de cada feature identificadas
45
+
46
+ ## Checklist post-migración (por feature)
47
+
48
+ - [ ] @injectable() en use cases, controller y repository
49
+ - [ ] @inject() con tokens de clase (no strings)
50
+ - [ ] Sin container.resolve() en lógica de negocio
51
+ - [ ] Imports actualizados (sin referencias legacy)
52
+ - [ ] Archivo .di.ts legacy eliminado
53
+ - [ ] Controller usa arrow-methods
54
+ - [ ] Use case tiene un único execute()
55
+ - [ ] Repository implementa la interfaz del dominio
56
+ - [ ] Mapper tiene toDomain() y toPersistence()
57
+ - [ ] Routes/index.ts actualizado
58
+ - [ ] Tests migrados y pasando
59
+ - [ ] pnpm lint pasa
60
+ - [ ] pnpm build pasa
61
+ - [ ] pnpm test pasa
62
+
63
+ ## Ejecución
64
+
65
+ ```bash
66
+ # Validación completa
67
+ node .opencode/skills/forge/scripts/detect.mjs
68
+
69
+ # Solo errores y críticos
70
+ node .opencode/skills/forge/scripts/detect.mjs --severity ERROR
71
+
72
+ # Solo un tipo específico
73
+ node .opencode/skills/forge/scripts/detect.mjs --type layers
74
+ ```
@@ -0,0 +1,40 @@
1
+ # Reforge
2
+
3
+ Refactoriza la arquitectura de un feature o de un componente de platform/shared/infra.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - Un feature tiene violaciones arquitectónicas
8
+ - Un feature legacy necesita reestructurarse
9
+ - Un componente de platform necesita refinarse
10
+ - Un componente de shared necesita rediseñarse
11
+ - El grafo arquitectónico muestra violaciones que requieren intervención
12
+
13
+ ## Flujo básico
14
+
15
+ 1. Ejecutar `forge inspect` para obtener estado actual
16
+ 2. Identificar violaciones en el grafo arquitectónico
17
+ 3. Identificar ownership problemático (huérfanos, duplicados, mal ubicados)
18
+ 4. Decidir las acciones correctivas en orden:
19
+ - Violaciones CRITICAL primero (R1, R2, R5, R6)
20
+ - Violaciones ERROR después (R3, R4, R8, R9)
21
+ - Ownership problemático
22
+ - Warnings
23
+ 5. Ejecutar cambios en el feature o componente
24
+ 6. Ejecutar `forge quench` para verificar
25
+ 7. Actualizar `ARCHITECTURE.md`
26
+
27
+ ## Refactorización multi-capa
28
+
29
+ Reforge ahora considera las cuatro capas arquitectónicas:
30
+
31
+ - **Platform**: Mover componentes técnicos sueltos a `src/platform/`
32
+ - **Features**: Reestructurar features con violaciones
33
+ - **Shared**: Extraer código duplicado a `src/shared/`
34
+ - **Infra**: Organizar implementaciones concretas en `src/infra/`
35
+
36
+ ## Post-refactorización
37
+
38
+ - `forge inspect` — confirmar mejora en puntuación
39
+ - `forge chain` — verificar que no se introdujeron ciclos
40
+ - `forge armorer` — verificar ownership saludable
@@ -0,0 +1,38 @@
1
+ # Relocate
2
+
3
+ Migra un feature existente desde estructura legacy hacia la arquitectura basada en features.
4
+
5
+ También puede migrar componentes legacy a los layers Platform, Shared o Infrastructure.
6
+
7
+ ## Cuándo usarlo
8
+
9
+ - El proyecto tiene código legacy fuera de `src/features/`
10
+ - Hay componentes en directorios legacy que deben migrarse a:
11
+ - `src/platform/` (si es infraestructura técnica global)
12
+ - `src/shared/` (si es código reutilizable puro)
13
+ - `src/infra/` (si es implementación concreta)
14
+ - `src/features/<name>/` (si es lógica de negocio)
15
+
16
+ ## Flujo
17
+
18
+ 1. Identificar el componente a migrar
19
+ 2. Clasificarlo en el layer correcto:
20
+ - Configuración, servidor, logger, DI → **Platform**
21
+ - Lógica de negocio, entidades, casos de uso → **Feature**
22
+ - Código reutilizable sin dependencias externas → **Shared**
23
+ - Implementaciones de BD, servicios externos → **Infra**
24
+ 3. Crear la estructura target según el layer
25
+ 4. Migrar archivos manteniendo la lógica intacta
26
+ 5. Actualizar imports
27
+ 6. Eliminar estructura legacy
28
+ 7. Ejecutar `forge quench` para verificar
29
+ 8. Actualizar `ARCHITECTURE.md`
30
+
31
+ ## Estrategias por layer
32
+
33
+ | Layer | Desde | Hacia |
34
+ |---|---|---|
35
+ | Platform | `src/config/`, `src/setting/`, `src/middleware/` | `src/platform/<name>/` |
36
+ | Feature | `src/application/use-cases/<name>/` | `src/features/<name>/` |
37
+ | Shared | `src/utils/`, `src/helpers/`, `src/lib/` | `src/shared/<name>/` |
38
+ | Infra | `src/database/`, `src/providers/` | `src/infra/<name>/` |
@@ -0,0 +1,31 @@
1
+ # Smelt
2
+
3
+ Extrae código reutilizable desde features hacia `shared/`.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - Dos o más features usan el mismo tipo, interfaz o utility
8
+ - Un feature contiene lógica que no es de negocio y podría ser compartida
9
+ - Se detecta duplicación de código entre features
10
+ - Se necesita mover un tipo o utilidad a `shared/` para mantener el principio DRY
11
+
12
+ ## Flujo
13
+
14
+ 1. Identificar el código candidato a extraer
15
+ 2. Verificar que no tenga dependencias de infraestructura
16
+ 3. Verificar que no tenga lógica de negocio específica de un feature
17
+ 4. Mover el código a `src/shared/<category>/`:
18
+ - Tipos → `src/shared/types/`
19
+ - Interfaces → `src/shared/contracts/`
20
+ - Errores → `src/shared/errors/`
21
+ - Utilidades → `src/shared/utils/`
22
+ 5. Actualizar todos los imports en los features que lo usaban
23
+ 6. Ejecutar `forge quench` para verificar que no hay violaciones
24
+ 7. Actualizar `ARCHITECTURE.md`
25
+
26
+ ## Reglas
27
+
28
+ - El código extraído NO debe importar de features
29
+ - El código extraído NO debe importar de infraestructura
30
+ - El código extraído debe ser puro o depender solo de otros componentes shared
31
+ - Si el código depende de platform, considerar moverlo a platform en lugar de shared
@@ -0,0 +1,49 @@
1
+ # Temper
2
+
3
+ Templa la arquitectura aplicando reglas de inyección de dependencias, seguridad y consistencia.
4
+
5
+ ## Cuándo usarlo
6
+
7
+ - El proyecto tiene código legacy con DI manual que necesita migrar a contenedor
8
+ - Se detectaron violaciones de inyección de dependencias
9
+ - El proyecto usa strings como tokens de DI
10
+ - Hay container.resolve() esparcido en la lógica de negocio
11
+
12
+ ## Reglas de DI
13
+
14
+ ### Universal (aplica a cualquier perfil)
15
+
16
+ | Regla | Severidad |
17
+ |---|---|
18
+ | Siempre inyección por constructor | ERROR |
19
+ | Sin service locators | ERROR |
20
+ | Sin singletons globales | WARNING |
21
+ | Sin new de dependencias en clases inyectadas | WARNING |
22
+
23
+ ### Para perfiles con tsyringe
24
+
25
+ - `@injectable()` en toda clase con dependencias
26
+ - `@inject(Token)` con tokens de clase, nunca strings
27
+ - `container.resolve()` solo en bootstrap (app.ts, routes)
28
+ - `container.registerSingleton()` para interfaces en app.ts
29
+ - `container.registerInstance()` para mocks en tests
30
+
31
+ ### Para DI manual
32
+
33
+ - Crear instancias explícitamente en bootstrap
34
+ - Pasar dependencias por constructor
35
+ - Usar factories o functions para lazy initialization
36
+
37
+ ### Para NestJS
38
+
39
+ - Usar `@Injectable()` de NestJS
40
+ - Configurar módulos con `providers` y `exports`
41
+ - Usar `@InjectRepository()` para TypeORM
42
+
43
+ ## Prohibiciones
44
+
45
+ - ❌ `container.resolve()` dentro de use cases, entities o adapters
46
+ - ❌ `new UseCase(dep1, dep2)` en features migrados a contenedor
47
+ - ❌ Importar tsyringe en archivos de dominio
48
+ - ❌ Mezclar DI manual y contenedor en el mismo feature
49
+ - ❌ Proxies automáticos o decoradores ocultos que dificulten el rastreo