@cristiancorreau/forge 2.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/CHANGELOG.md +228 -0
- package/LICENSE +191 -0
- package/README.md +156 -0
- package/assets/adapters/claude-code/commands/deploy-check.md +12 -0
- package/assets/adapters/claude-code/commands/new-feature.md +11 -0
- package/assets/adapters/claude-code/commands/plan.md +116 -0
- package/assets/adapters/claude-code/commands/review.md +219 -0
- package/assets/adapters/claude-code/commands/session-close.md +109 -0
- package/assets/adapters/claude-code/commands/session-start.md +59 -0
- package/assets/adapters/claude-code/commands/ship.md +133 -0
- package/assets/adapters/claude-code/commands/wiki-ingest.md +7 -0
- package/assets/adapters/claude-code/commands/wiki-lint.md +5 -0
- package/assets/adapters/claude-code/commands/wiki-query.md +7 -0
- package/assets/adapters/claude-code/commands/work.md +101 -0
- package/assets/adapters/claude-code/generate-claude-md.py +304 -0
- package/assets/adapters/codex/commands/plan.md +63 -0
- package/assets/adapters/codex/commands/review.md +53 -0
- package/assets/adapters/codex/commands/session-close.md +53 -0
- package/assets/adapters/codex/commands/session-start.md +49 -0
- package/assets/adapters/codex/commands/ship.md +53 -0
- package/assets/adapters/codex/commands/work.md +53 -0
- package/assets/adapters/codex/generate-codex-config.py +269 -0
- package/assets/adapters/codex/hooks/codex.yaml.tpl +43 -0
- package/assets/adapters/codex/hooks/forge-codex-finish.sh +158 -0
- package/assets/adapters/codex/hooks/forge-codex-start.sh +186 -0
- package/assets/adapters/kiro/generate-steering.py +367 -0
- package/assets/adapters/opencode/HOOKS.md +123 -0
- package/assets/adapters/opencode/commands/plan.md +119 -0
- package/assets/adapters/opencode/commands/review.md +164 -0
- package/assets/adapters/opencode/commands/session-close.md +111 -0
- package/assets/adapters/opencode/commands/session-start.md +62 -0
- package/assets/adapters/opencode/commands/ship.md +135 -0
- package/assets/adapters/opencode/commands/work.md +82 -0
- package/assets/adapters/opencode/generate-agents-md.py +262 -0
- package/assets/core/agents/backend-engineer.md +61 -0
- package/assets/core/agents/compliance-reviewer.md +83 -0
- package/assets/core/agents/docs-writer.md +77 -0
- package/assets/core/agents/frontend-engineer.md +70 -0
- package/assets/core/agents/orchestrator.md +104 -0
- package/assets/core/agents/security-auditor.md +54 -0
- package/assets/core/agents/test-engineer.md +57 -0
- package/assets/core/hooks/hooks-registry.yaml +48 -0
- package/assets/core/hooks/post-turn-check.sh +139 -0
- package/assets/core/hooks/pre-bash-check.py +202 -0
- package/assets/core/hooks/pre-edit-check.py +317 -0
- package/assets/core/hooks/session-start.sh +184 -0
- package/assets/core/schemas/project.schema.json +503 -0
- package/assets/core/skills/README.md +88 -0
- package/assets/core/skills/aitmpl-search/SKILL.md +74 -0
- package/assets/core/skills/browser-test/SKILL.md +177 -0
- package/assets/core/skills/db-migrate/SKILL.md +163 -0
- package/assets/core/skills/local2prod/SKILL.md +147 -0
- package/assets/core/skills/new-feature/SKILL.md +155 -0
- package/assets/core/skills/obsidian-sync/SKILL.md +152 -0
- package/assets/core/skills/phase-kickoff/SKILL.md +69 -0
- package/assets/core/skills/security-audit/SKILL.md +125 -0
- package/assets/core/skills/spec/SKILL.md +72 -0
- package/assets/core/skills/wiki-ingest/SKILL.md +183 -0
- package/assets/core/skills/wiki-lint/SKILL.md +109 -0
- package/assets/core/skills/wiki-query/SKILL.md +100 -0
- package/assets/core/templates/claude-md/architecture.rules +20 -0
- package/assets/core/templates/claude-md/global.md +30 -0
- package/assets/core/templates/claude-md/project.md +36 -0
- package/assets/core/templates/daily-note.md +38 -0
- package/assets/core/templates/spec-template.md +43 -0
- package/assets/core/workflows/sdd.md +69 -0
- package/assets/core/workflows/sprint.md +59 -0
- package/assets/forge.py +1265 -0
- package/assets/hooks/pre-commit +43 -0
- package/assets/manifest.json +274 -0
- package/assets/profiles/astro/README.md +24 -0
- package/assets/profiles/astro/agents/frontend-engineer.md +74 -0
- package/assets/profiles/django/agents/api-engineer.md +83 -0
- package/assets/profiles/expo/README.md +24 -0
- package/assets/profiles/expo/agents/mobile-engineer.md +69 -0
- package/assets/profiles/express/agents/api-engineer.md +60 -0
- package/assets/profiles/fastapi/README.md +32 -0
- package/assets/profiles/fastapi/agents/api-engineer.md +87 -0
- package/assets/profiles/go-gin/agents/api-engineer.md +98 -0
- package/assets/profiles/hono-drizzle/README.md +31 -0
- package/assets/profiles/hono-drizzle/agents/api-engineer.md +82 -0
- package/assets/profiles/laravel/README.md +32 -0
- package/assets/profiles/laravel/agents/api-engineer.md +114 -0
- package/assets/profiles/laravel/agents/fullstack-engineer.md +67 -0
- package/assets/profiles/laravel/agents/migration-specialist.md +420 -0
- package/assets/profiles/nestjs/agents/api-engineer.md +79 -0
- package/assets/profiles/nextjs-admin/README.md +32 -0
- package/assets/profiles/nextjs-admin/agents/admin-engineer.md +78 -0
- package/assets/profiles/playwright-crawler/agents/scanner-engineer.md +51 -0
- package/assets/profiles/rails/agents/fullstack-engineer.md +61 -0
- package/assets/profiles/sveltekit/agents/frontend-engineer.md +96 -0
- package/assets/profiles/vuenuxt/agents/frontend-engineer.md +82 -0
- package/assets/profiles/wordpress/README.md +30 -0
- package/assets/profiles/wordpress/agents/divi-engineer.md +273 -0
- package/assets/profiles/wordpress/agents/elementor-engineer.md +310 -0
- package/assets/profiles/wordpress/agents/wp-engineer.md +216 -0
- package/assets/requirements.txt +2 -0
- package/assets/scripts/aitmpl-search.py +808 -0
- package/assets/scripts/forge-add-opportunities.py +92 -0
- package/assets/scripts/forge-audit.py +1061 -0
- package/assets/scripts/forge-generate-all.py +283 -0
- package/assets/scripts/forge-init.py +900 -0
- package/assets/scripts/forge-migrate-project-yaml.py +397 -0
- package/assets/scripts/forge-scaffold-profile.py +181 -0
- package/assets/scripts/forge-teardown.py +193 -0
- package/assets/scripts/forge-validate-project-yaml.py +457 -0
- package/assets/scripts/forge-wizard.py +1003 -0
- package/assets/scripts/setup-codex.sh +229 -0
- package/assets/scripts/team-install.sh +147 -0
- package/assets/scripts/token-stats.py +201 -0
- package/assets/templates/modes/enterprise.yaml.tpl +114 -0
- package/assets/templates/modes/multi-runtime.yaml.tpl +89 -0
- package/assets/templates/modes/new-stack.yaml.tpl +101 -0
- package/assets/templates/modes/startup.yaml.tpl +74 -0
- package/assets/templates/project.yaml.tpl +185 -0
- package/assets/templates/wiki/concepts/_template.md +22 -0
- package/assets/templates/wiki/entities/_template.md +19 -0
- package/assets/templates/wiki/index.md +32 -0
- package/assets/templates/wiki/log.md +6 -0
- package/assets/templates/wiki/sources/_template.md +25 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/audit.d.ts +2 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +21 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +58 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/generate.d.ts +2 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +27 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +22 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/validate.d.ts +2 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +20 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/lib/paths.d.ts +10 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +49 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/python.d.ts +4 -0
- package/dist/lib/python.d.ts.map +1 -0
- package/dist/lib/python.js +46 -0
- package/dist/lib/python.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# work
|
|
2
|
+
|
|
3
|
+
Implementa una spec con un agent team. Flags soportados: `--serial`, `--autorun`.
|
|
4
|
+
|
|
5
|
+
Scope: $ARGUMENTS (ej: `--serial`, `--autorun`, o vacío para modo paralelo estándar)
|
|
6
|
+
|
|
7
|
+
## Paso 1 — Identificar la spec
|
|
8
|
+
|
|
9
|
+
Buscar archivos `.md` en `docs/specs/` que contengan `**Estado:** ready`.
|
|
10
|
+
|
|
11
|
+
- Si hay exactamente una: mostrarla y confirmar "Implementando: `<archivo>`."
|
|
12
|
+
- Si hay varias: mostrarlas como lista numerada y pedir que el usuario elija.
|
|
13
|
+
- Si no hay ninguna: "No hay spec en estado ready. Ejecutá `/plan` primero." y detener.
|
|
14
|
+
|
|
15
|
+
Leer la spec seleccionada completa antes de continuar.
|
|
16
|
+
|
|
17
|
+
## Paso 2 — Leer configuración del proyecto
|
|
18
|
+
|
|
19
|
+
Leer `project.yaml` si existe. Obtener:
|
|
20
|
+
- `project.mode` (startup/standard/enterprise) — default: startup si no existe
|
|
21
|
+
- `agents.active` — lista de agentes disponibles
|
|
22
|
+
- `agents.by_role` — mapeo de roles a agentes
|
|
23
|
+
- `agents.profiles` — profiles activos
|
|
24
|
+
|
|
25
|
+
Si `project.yaml` no existe, continuar con defaults: mode=startup, team mínimo.
|
|
26
|
+
|
|
27
|
+
## Paso 3 — Proponer composición del team
|
|
28
|
+
|
|
29
|
+
Evaluar la naturaleza de la tarea según el acceptance criteria de la spec:
|
|
30
|
+
|
|
31
|
+
**Cuándo NO crear team (usar `--serial` implícitamente):**
|
|
32
|
+
- Cambio en un solo archivo
|
|
33
|
+
- Bugfix trivial sin impacto en otros módulos
|
|
34
|
+
- Tarea de lectura o análisis de código
|
|
35
|
+
|
|
36
|
+
**Composición según mode:**
|
|
37
|
+
|
|
38
|
+
| Mode | Team típico | Tamaño |
|
|
39
|
+
|------|-------------|--------|
|
|
40
|
+
| startup | orchestrator + 1 especialista | 2 agentes |
|
|
41
|
+
| standard | orchestrator + backend + frontend + test-engineer | 3-4 agentes |
|
|
42
|
+
| enterprise | orchestrator + backend + frontend + test-engineer + compliance-reviewer o security-auditor | 4-5 agentes |
|
|
43
|
+
|
|
44
|
+
Límites absolutos: máximo 5-6 tasks por teammate, máximo 5 teammates.
|
|
45
|
+
|
|
46
|
+
Mostrar el team propuesto con el rol y la tarea concreta de cada agente. Ejemplo:
|
|
47
|
+
```
|
|
48
|
+
Team propuesto:
|
|
49
|
+
- orchestrator: coordinar implementación y resolver dependencias entre módulos
|
|
50
|
+
- backend-engineer: implementar endpoints de API y lógica de negocio
|
|
51
|
+
- frontend-engineer: construir componentes UI y conectar con la API
|
|
52
|
+
- test-engineer: escribir tests unitarios e integración para los cambios
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Paso 4 — Confirmar con el usuario
|
|
56
|
+
|
|
57
|
+
Preguntar: "¿Aprobás este team o querés ajustarlo?"
|
|
58
|
+
|
|
59
|
+
Si el usuario ajusta: modificar el team según su feedback antes de ejecutar.
|
|
60
|
+
|
|
61
|
+
Si se detectó que la tarea no requiere team (ver criterios arriba): informar "Esta tarea es simple — implementaré en modo serial sin team." y continuar con modo `--serial`.
|
|
62
|
+
|
|
63
|
+
## Paso 5 — Ejecutar
|
|
64
|
+
|
|
65
|
+
### Con `--serial` (o tarea simple detectada en Paso 3)
|
|
66
|
+
|
|
67
|
+
Implementar secuencialmente sin subagentes. Seguir el acceptance criteria de la spec como checklist. Reportar progreso por ítem.
|
|
68
|
+
|
|
69
|
+
### Sin flags (modo paralelo estándar)
|
|
70
|
+
|
|
71
|
+
Antes de ejecutar: si se usó `--autorun`, advertir una sola vez: "Modo --autorun activado: ejecutaré hasta completar sin confirmaciones intermedias. Esto es experimental."
|
|
72
|
+
|
|
73
|
+
Spawnar cada teammate con:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
Agent({
|
|
77
|
+
subagent_type: "<nombre-agente>",
|
|
78
|
+
description: "<rol y tarea concreta en una línea>",
|
|
79
|
+
prompt: "<prompt auto-contenido con: contexto completo del proyecto, spec completa, tarea específica del agente, instrucciones de qué reportar al terminar>",
|
|
80
|
+
run_in_background: true
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
El prompt de cada agente debe ser auto-contenido: incluir la spec completa, el stack técnico del proyecto y la tarea específica. El agente no tiene acceso al contexto de esta sesión.
|
|
85
|
+
|
|
86
|
+
## Paso 6 — Monitorear y sintetizar
|
|
87
|
+
|
|
88
|
+
Cuando los teammates terminan:
|
|
89
|
+
- Revisar los resultados de cada uno
|
|
90
|
+
- Identificar conflictos o dependencias no resueltas
|
|
91
|
+
- Reportar al usuario: qué implementó cada agente, qué tests pasaron, si hubo errores
|
|
92
|
+
|
|
93
|
+
Si hay errores o conflictos: reportar claramente y preguntar cómo proceder. No resolver conflictos automáticamente sin confirmación.
|
|
94
|
+
|
|
95
|
+
## Paso 7 — Actualizar la spec
|
|
96
|
+
|
|
97
|
+
- Al iniciar la implementación: cambiar `**Estado:** ready` → `**Estado:** in-progress`
|
|
98
|
+
- Al completar exitosamente: cambiar `**Estado:** in-progress` → `**Estado:** implemented`
|
|
99
|
+
- Completar las secciones "Implementation notes" y "Decisiones tomadas" con lo que se hizo
|
|
100
|
+
|
|
101
|
+
Confirmar: "Implementación completa. Spec actualizada a `implemented`. Podés ejecutar `/review` y luego `/ship`."
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright 2026 Cristian Correa — Apache License 2.0
|
|
3
|
+
# https://github.com/cristiancorreau/forge
|
|
4
|
+
"""
|
|
5
|
+
Genera CLAUDE.md para un proyecto usando forge.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python3 .agentic/adapters/claude-code/generate-claude-md.py
|
|
9
|
+
|
|
10
|
+
Lee project.yaml en la raíz y genera CLAUDE.md adaptado al stack del proyecto.
|
|
11
|
+
Si ya existe un CLAUDE.md, muestra el diff antes de sobreescribir.
|
|
12
|
+
|
|
13
|
+
Requiere: pyyaml
|
|
14
|
+
"""
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
FORCE = "--force" in sys.argv
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import yaml
|
|
23
|
+
except ImportError:
|
|
24
|
+
print("ERROR: pyyaml requerido. pip install pyyaml", file=sys.stderr)
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def find_project_root() -> Path:
|
|
29
|
+
here = Path.cwd()
|
|
30
|
+
for p in [here] + list(here.parents):
|
|
31
|
+
if (p / "project.yaml").exists():
|
|
32
|
+
return p
|
|
33
|
+
raise FileNotFoundError("No se encontró project.yaml")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _render_phases(config: dict) -> str:
|
|
37
|
+
sprint = config.get("sprint", {})
|
|
38
|
+
current = sprint.get("current", 1)
|
|
39
|
+
phases = sprint.get("phases", [])
|
|
40
|
+
if not phases:
|
|
41
|
+
return (
|
|
42
|
+
f"- **Sprint actual:** Sprint {current}\n"
|
|
43
|
+
"- **Completadas:** —\n"
|
|
44
|
+
"- **En curso:** —\n"
|
|
45
|
+
"- **Pendientes:** —"
|
|
46
|
+
)
|
|
47
|
+
lines = [f"- **Sprint actual:** Sprint {current}"]
|
|
48
|
+
for phase in phases:
|
|
49
|
+
pid = phase.get("id", "?")
|
|
50
|
+
name = phase.get("name", "")
|
|
51
|
+
specs = phase.get("specs", [])
|
|
52
|
+
status = phase.get("status", "pendiente")
|
|
53
|
+
spec_list = ", ".join(specs) if specs else "—"
|
|
54
|
+
lines.append(f"- **Fase {pid} — {name}** ({status}): {spec_list}")
|
|
55
|
+
return "\n".join(lines)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
_AGENT_TRIGGER = {
|
|
59
|
+
"orchestrator": ("tareas multi-agente, análisis de >3 archivos, descomposición de features completas", None),
|
|
60
|
+
"backend-engineer": ("endpoints, middleware, validaciones, lógica de negocio", "api"),
|
|
61
|
+
"api-engineer": ("endpoints REST, middleware, validaciones, migraciones de BD", "api"),
|
|
62
|
+
"frontend-engineer": ("componentes UI, páginas, estilos, integración con API", "frontend"),
|
|
63
|
+
"admin-engineer": ("UI de gestión interna, dashboards de admin", "admin"),
|
|
64
|
+
"mobile-engineer": ("pantallas móviles, navegación, stores de estado", "mobile"),
|
|
65
|
+
"fullstack-engineer": ("features full-stack end-to-end que abarcan backend y frontend", None),
|
|
66
|
+
"test-engineer": ("tests unitarios, integración, E2E — nunca código de producción", "tests"),
|
|
67
|
+
"docs-writer": ("specs, ADRs, READMEs, documentación — nunca código de producción", "specs"),
|
|
68
|
+
"compliance-reviewer": ("revisión de PRs con PII, consentimientos, logs de auditoría", None),
|
|
69
|
+
"security-auditor": ("auditoría de vulnerabilidades, revisión de dependencias, pentest", None),
|
|
70
|
+
"migration-specialist": ("migraciones de versión de framework (ej: L6→L13)", "migrations"),
|
|
71
|
+
"wp-engineer": ("temas WordPress, FSE, Gutenberg, child themes", "frontend"),
|
|
72
|
+
"divi-engineer": ("layouts Divi 5, módulos custom, Divi Builder", "frontend"),
|
|
73
|
+
"elementor-engineer": ("templates Elementor Pro, widgets custom", "frontend"),
|
|
74
|
+
"scanner-engineer": ("scraping, crawling, extracción estructurada de datos", "scanner"),
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _build_agent_scope_table(agents_cfg: dict, paths: dict) -> str:
|
|
79
|
+
active = agents_cfg.get("active", [])
|
|
80
|
+
compliance = agents_cfg.get("compliance", [])
|
|
81
|
+
agent_paths = {**(paths or {})}
|
|
82
|
+
rows = []
|
|
83
|
+
for agent in active + compliance:
|
|
84
|
+
trigger, path_key = _AGENT_TRIGGER.get(agent, ("implementación", None))
|
|
85
|
+
scope = agent_paths.get(path_key) if path_key else None
|
|
86
|
+
scope_str = f"`{scope}`" if scope else "`/`"
|
|
87
|
+
rows.append(f"| `{agent}` | {scope_str} | {trigger} |")
|
|
88
|
+
if not rows:
|
|
89
|
+
return ""
|
|
90
|
+
header = (
|
|
91
|
+
"## Agentes y su scope\n\n"
|
|
92
|
+
"| Agente | Scope | Cuándo usarlo |\n"
|
|
93
|
+
"|--------|-------|---------------|\n"
|
|
94
|
+
)
|
|
95
|
+
return header + "\n".join(rows) + "\n\n> Invocar el agente del scope correcto, no el orchestrator, para tareas acotadas.\n\n"
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def generate_claude_md(config: dict) -> str:
|
|
99
|
+
proj = config.get("project", {})
|
|
100
|
+
stack = config.get("stack", {})
|
|
101
|
+
team = config.get("team", {})
|
|
102
|
+
compliance_cfg = config.get("compliance", {})
|
|
103
|
+
agents_cfg = config.get("agents", {})
|
|
104
|
+
paths = config.get("paths", {})
|
|
105
|
+
|
|
106
|
+
name = proj.get("name", "Mi Proyecto")
|
|
107
|
+
description = proj.get("description", "")
|
|
108
|
+
language = proj.get("language", "typescript")
|
|
109
|
+
backend = stack.get("backend") or "N/A"
|
|
110
|
+
frontend = stack.get("frontend") or "N/A"
|
|
111
|
+
database = stack.get("database") or "N/A"
|
|
112
|
+
frameworks = compliance_cfg.get("frameworks", [])
|
|
113
|
+
specs_path = paths.get("specs", "docs/specs")
|
|
114
|
+
progress_path = paths.get("progress", "docs/progress.html")
|
|
115
|
+
agent_scope_section = _build_agent_scope_table(agents_cfg, paths)
|
|
116
|
+
|
|
117
|
+
# Agentes activos
|
|
118
|
+
active = agents_cfg.get("active", [])
|
|
119
|
+
|
|
120
|
+
# Comandos según lenguaje
|
|
121
|
+
if language == "typescript":
|
|
122
|
+
dev_cmd = "pnpm dev"
|
|
123
|
+
test_cmd = "pnpm test"
|
|
124
|
+
lint_cmd = "pnpm lint"
|
|
125
|
+
build_cmd = "pnpm build"
|
|
126
|
+
elif language == "python":
|
|
127
|
+
dev_cmd = "python manage.py runserver # o uvicorn main:app"
|
|
128
|
+
test_cmd = "pytest"
|
|
129
|
+
lint_cmd = "ruff check ."
|
|
130
|
+
build_cmd = "# no aplica"
|
|
131
|
+
elif language == "ruby":
|
|
132
|
+
dev_cmd = "rails server"
|
|
133
|
+
test_cmd = "bundle exec rspec"
|
|
134
|
+
lint_cmd = "rubocop"
|
|
135
|
+
build_cmd = "# no aplica"
|
|
136
|
+
elif language == "go":
|
|
137
|
+
dev_cmd = "go run ./cmd/..."
|
|
138
|
+
test_cmd = "go test ./..."
|
|
139
|
+
lint_cmd = "golangci-lint run"
|
|
140
|
+
build_cmd = "go build ./..."
|
|
141
|
+
elif language == "php":
|
|
142
|
+
dev_cmd = "php artisan serve # o php -S localhost:8000 -t public"
|
|
143
|
+
test_cmd = "vendor/bin/phpunit # o ./vendor/bin/pest"
|
|
144
|
+
lint_cmd = "vendor/bin/phpstan analyse"
|
|
145
|
+
build_cmd = "composer install --no-dev --optimize-autoloader"
|
|
146
|
+
elif language == "mixed":
|
|
147
|
+
dev_cmd = "# ver documentación del proyecto (stack mixto)"
|
|
148
|
+
test_cmd = "# ver documentación del proyecto (stack mixto)"
|
|
149
|
+
lint_cmd = "# ver documentación del proyecto (stack mixto)"
|
|
150
|
+
build_cmd = "# ver documentación del proyecto (stack mixto)"
|
|
151
|
+
else:
|
|
152
|
+
dev_cmd = "# ver documentación del proyecto"
|
|
153
|
+
test_cmd = "# ver documentación del proyecto"
|
|
154
|
+
lint_cmd = "# ver documentación del proyecto"
|
|
155
|
+
build_cmd = "# ver documentación del proyecto"
|
|
156
|
+
|
|
157
|
+
compliance_section = ""
|
|
158
|
+
if frameworks:
|
|
159
|
+
compliance_section = f"""
|
|
160
|
+
## Compliance activo
|
|
161
|
+
|
|
162
|
+
Este proyecto opera bajo los siguientes marcos regulatorios:
|
|
163
|
+
{chr(10).join(f'- **{f.upper()}**' for f in frameworks)}
|
|
164
|
+
|
|
165
|
+
Reglas no-negociables:
|
|
166
|
+
- Sin datos personales en logs de stdout
|
|
167
|
+
- Consentimiento explícito antes de cualquier tracker no esencial
|
|
168
|
+
- Logs de auditoría append-only (sin UPDATE/DELETE)
|
|
169
|
+
- Derechos del titular implementados (acceso, rectificación, supresión, oposición, portabilidad)
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
return f"""# CLAUDE.md — {name}
|
|
173
|
+
|
|
174
|
+
> Generado por forge. Actualizar project.yaml para cambiar la configuración.
|
|
175
|
+
> Si actualizás el código de manera que invalide algo aquí, actualizá este archivo en el mismo PR.
|
|
176
|
+
|
|
177
|
+
## Misión del proyecto
|
|
178
|
+
|
|
179
|
+
{description}
|
|
180
|
+
|
|
181
|
+
## Stack
|
|
182
|
+
|
|
183
|
+
- **Lenguaje**: {language}
|
|
184
|
+
- **Backend**: {backend}
|
|
185
|
+
- **Frontend**: {frontend}
|
|
186
|
+
- **Base de datos**: {database}
|
|
187
|
+
- **Testing**: {", ".join(stack.get("testing", []))}
|
|
188
|
+
|
|
189
|
+
{agent_scope_section}## Estructura
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
{proj.get("slug", "proyecto")}/
|
|
193
|
+
├── CLAUDE.md ← Estás acá
|
|
194
|
+
├── AGENTS.md ← Convenciones del agent team
|
|
195
|
+
├── project.yaml ← Config de forge (fuente de verdad)
|
|
196
|
+
├── {specs_path}/ ← Specs de features (requeridas antes de implementar)
|
|
197
|
+
└── {progress_path} ← Dashboard de progreso del proyecto
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Cómo trabajar (SDD)
|
|
201
|
+
|
|
202
|
+
Cuando recibás una tarea:
|
|
203
|
+
|
|
204
|
+
1. **Identificá la spec.** Si no está en `{specs_path}/`, pará y pedí que se cree.
|
|
205
|
+
2. **Leé la spec correspondiente.**
|
|
206
|
+
3. **Leé el `CLAUDE.md` del módulo** que vas a modificar (si existe).
|
|
207
|
+
4. **Proponé opciones** para decisiones arquitectónicas no cubiertas por la spec.
|
|
208
|
+
5. **Esperá aprobación** antes de generar código.
|
|
209
|
+
6. **Tests** junto con la implementación, no al final.
|
|
210
|
+
7. **Al terminar**, actualizá la spec con decisiones tomadas durante la implementación.
|
|
211
|
+
8. **Antes de cerrar**: `{test_cmd}`, `{lint_cmd}`.
|
|
212
|
+
{compliance_section}
|
|
213
|
+
## Phases activas y estado
|
|
214
|
+
|
|
215
|
+
{_render_phases(config)}
|
|
216
|
+
|
|
217
|
+
> Actualizar `project.yaml` (sprint.phases) para reflejar el estado real.
|
|
218
|
+
|
|
219
|
+
## Comandos frecuentes
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
{dev_cmd} # Desarrollo
|
|
223
|
+
{test_cmd} # Tests
|
|
224
|
+
{lint_cmd} # Lint
|
|
225
|
+
{build_cmd} # Build
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Qué NO hacer
|
|
229
|
+
|
|
230
|
+
- No implementar sin spec en `{specs_path}/`
|
|
231
|
+
- No hardcodear tokens, passwords o secrets
|
|
232
|
+
- No usar `any` en TypeScript sin comentario que explique por qué
|
|
233
|
+
- No commits con `console.log` o `print` de depuración
|
|
234
|
+
- No hacer force push a main/master
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _generate_architecture_rules(root: Path, forge: Path, config: dict):
|
|
239
|
+
"""Crea .claude/architecture.rules desde el template si no existe. Nunca sobreescribe."""
|
|
240
|
+
dst = root / ".claude" / "architecture.rules"
|
|
241
|
+
if dst.exists():
|
|
242
|
+
return
|
|
243
|
+
|
|
244
|
+
# Buscar el template en forge
|
|
245
|
+
tpl_path = forge / "core" / "templates" / "claude-md" / "architecture.rules"
|
|
246
|
+
if not tpl_path.exists():
|
|
247
|
+
return
|
|
248
|
+
|
|
249
|
+
project_name = config.get("project", {}).get("name", "Mi Proyecto")
|
|
250
|
+
content = tpl_path.read_text(encoding="utf-8")
|
|
251
|
+
content = content.replace("<NOMBRE_PROYECTO>", project_name)
|
|
252
|
+
|
|
253
|
+
dst.parent.mkdir(parents=True, exist_ok=True)
|
|
254
|
+
dst.write_text(content, encoding="utf-8")
|
|
255
|
+
print(f"[OK] .claude/architecture.rules — creado desde template")
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _find_forge_dir(root: Path) -> Path:
|
|
259
|
+
"""Localiza el directorio de forge relativo a este script."""
|
|
260
|
+
# Este script está en forge/adapters/claude-code/generate-claude-md.py
|
|
261
|
+
script_dir = Path(__file__).parent
|
|
262
|
+
# forge_dir = forge/
|
|
263
|
+
candidate = script_dir.parent.parent
|
|
264
|
+
if (candidate / "core").exists():
|
|
265
|
+
return candidate
|
|
266
|
+
# Fallback: buscar .agentic o forge en la raíz del proyecto
|
|
267
|
+
for name in (".agentic", "forge"):
|
|
268
|
+
c = root / name
|
|
269
|
+
if (c / "core").exists():
|
|
270
|
+
return c
|
|
271
|
+
return candidate
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def main():
|
|
275
|
+
try:
|
|
276
|
+
root = find_project_root()
|
|
277
|
+
except FileNotFoundError as e:
|
|
278
|
+
print(f"ERROR: {e}", file=sys.stderr)
|
|
279
|
+
sys.exit(1)
|
|
280
|
+
|
|
281
|
+
with open(root / "project.yaml") as f:
|
|
282
|
+
config = yaml.safe_load(f)
|
|
283
|
+
|
|
284
|
+
content = generate_claude_md(config)
|
|
285
|
+
output_path = root / "CLAUDE.md"
|
|
286
|
+
|
|
287
|
+
if output_path.exists() and not FORCE:
|
|
288
|
+
print(f"CLAUDE.md ya existe en {root}. Sobreescribir? [s/N] ", end="")
|
|
289
|
+
resp = input().strip().lower()
|
|
290
|
+
if resp not in ("s", "si", "sí", "y", "yes"):
|
|
291
|
+
print("Cancelado.")
|
|
292
|
+
sys.exit(0)
|
|
293
|
+
|
|
294
|
+
with open(output_path, "w") as f:
|
|
295
|
+
f.write(content)
|
|
296
|
+
|
|
297
|
+
print(f"CLAUDE.md generado en {output_path}")
|
|
298
|
+
|
|
299
|
+
forge = _find_forge_dir(root)
|
|
300
|
+
_generate_architecture_rules(root, forge, config)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
if __name__ == "__main__":
|
|
304
|
+
main()
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan
|
|
3
|
+
description: Template para planificar una feature con Codex CLI siguiendo SDD
|
|
4
|
+
usage: Copia el contenido de Prompt en tu sesión de Codex
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prompt para Codex
|
|
8
|
+
|
|
9
|
+
Quiero planificar la siguiente feature: [NOMBRE O DESCRIPCIÓN DE LA FEATURE]
|
|
10
|
+
|
|
11
|
+
Sigue estos pasos en orden:
|
|
12
|
+
|
|
13
|
+
1. Busca si existe una spec para esta feature en `docs/specs/`. Lista los archivos en ese directorio y lee cualquiera que sea relevante.
|
|
14
|
+
|
|
15
|
+
2. Si NO existe spec:
|
|
16
|
+
- Crea el archivo `docs/specs/[ID]-[nombre-kebab-case].md` usando la plantilla en `docs/specs/_template.md` (si existe) o con esta estructura:
|
|
17
|
+
```
|
|
18
|
+
# [Nombre de la Feature]
|
|
19
|
+
> Estado: DRAFT
|
|
20
|
+
> Fecha: [fecha actual]
|
|
21
|
+
|
|
22
|
+
## Contexto
|
|
23
|
+
[Por qué existe esta feature]
|
|
24
|
+
|
|
25
|
+
## Decisión
|
|
26
|
+
[Qué vamos a implementar exactamente]
|
|
27
|
+
|
|
28
|
+
## Criterios de aceptación
|
|
29
|
+
- [ ] [criterio verificable 1]
|
|
30
|
+
- [ ] [criterio verificable 2]
|
|
31
|
+
|
|
32
|
+
## Notas de implementación
|
|
33
|
+
[Vacío — se completa durante la implementación]
|
|
34
|
+
```
|
|
35
|
+
- Detente aquí. No escribas ningún código hasta que la spec esté aprobada.
|
|
36
|
+
|
|
37
|
+
3. Si la spec existe y está en estado APPROVED:
|
|
38
|
+
- Lee la spec completa.
|
|
39
|
+
- Lee el `project.yaml` en la raíz para entender el stack.
|
|
40
|
+
- Identifica los archivos que deberán modificarse.
|
|
41
|
+
- Propón el plan de implementación con este formato:
|
|
42
|
+
```
|
|
43
|
+
PLAN: [nombre de la feature]
|
|
44
|
+
|
|
45
|
+
Archivos a crear:
|
|
46
|
+
- [ruta exacta]: [propósito]
|
|
47
|
+
|
|
48
|
+
Archivos a modificar:
|
|
49
|
+
- [ruta exacta]: [qué cambia]
|
|
50
|
+
|
|
51
|
+
Orden de implementación:
|
|
52
|
+
1. [paso 1]
|
|
53
|
+
2. [paso 2]
|
|
54
|
+
|
|
55
|
+
Tests necesarios:
|
|
56
|
+
- [ruta de test]: [qué verifica]
|
|
57
|
+
```
|
|
58
|
+
- No implementes nada todavía. Espera confirmación explícita.
|
|
59
|
+
|
|
60
|
+
Restricciones:
|
|
61
|
+
- Nunca hardcodear tokens, passwords ni secrets.
|
|
62
|
+
- No crear código antes de que exista spec aprobada.
|
|
63
|
+
- Si la feature afecta autenticación, rutas de API, o manejo de PII — mencionarlo explícitamente en el plan.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review
|
|
3
|
+
description: Template para revisar código con Codex CLI
|
|
4
|
+
usage: Copia el contenido de Prompt en tu sesión de Codex
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prompt para Codex
|
|
8
|
+
|
|
9
|
+
Revisa el siguiente código o cambios: [RUTA DE ARCHIVO, RAMA, O "cambios sin commitear actuales"]
|
|
10
|
+
|
|
11
|
+
Ejecuta esta revisión en orden:
|
|
12
|
+
|
|
13
|
+
1. **Identificar el scope**
|
|
14
|
+
- Si es un archivo: lee ese archivo completo.
|
|
15
|
+
- Si es "cambios sin commitear": ejecuta `git diff` y `git diff --cached` para ver todos los cambios.
|
|
16
|
+
- Si es una rama: ejecuta `git diff main...[nombre-rama]` para ver los cambios respecto a main.
|
|
17
|
+
|
|
18
|
+
2. **Checklist de seguridad**
|
|
19
|
+
- [ ] ¿Hay tokens, passwords o secrets hardcodeados? (busca patrones como `password =`, `token =`, `api_key =`)
|
|
20
|
+
- [ ] ¿Los endpoints de API verifican autenticación?
|
|
21
|
+
- [ ] ¿Los endpoints de API verifican autorización (permisos por rol o ownership)?
|
|
22
|
+
- [ ] ¿Las queries SQL usan parámetros preparados? (nunca concatenación de strings con input del usuario)
|
|
23
|
+
- [ ] ¿Hay XSS potencial (inserción de HTML sin escapar)?
|
|
24
|
+
- [ ] ¿Los errores exponen detalles técnicos en respuestas de producción?
|
|
25
|
+
|
|
26
|
+
3. **Checklist de calidad**
|
|
27
|
+
- [ ] ¿El código tiene tests que lo verifican?
|
|
28
|
+
- [ ] ¿Hay queries N+1 o loops en caminos críticos?
|
|
29
|
+
- [ ] ¿Hay console.log / print de depuración que no deba estar?
|
|
30
|
+
- [ ] ¿Hay código muerto o duplicado?
|
|
31
|
+
- [ ] ¿El naming es claro y consistente con el resto del proyecto?
|
|
32
|
+
|
|
33
|
+
4. **Checklist de compliance** (si el proyecto maneja PII)
|
|
34
|
+
- [ ] ¿Se está guardando PII en logs?
|
|
35
|
+
- [ ] ¿Hay cambios en endpoints de derechos del titular (DSAR)?
|
|
36
|
+
- [ ] ¿Hay cambios en consentimientos o logs de auditoría?
|
|
37
|
+
|
|
38
|
+
5. **Formato del reporte**
|
|
39
|
+
Presenta los hallazgos así:
|
|
40
|
+
```
|
|
41
|
+
BLOQUEANTES (deben resolverse antes del merge):
|
|
42
|
+
- [archivo:línea] descripción del problema
|
|
43
|
+
|
|
44
|
+
ADVERTENCIAS (recomendado resolver):
|
|
45
|
+
- [archivo:línea] descripción
|
|
46
|
+
|
|
47
|
+
SUGERENCIAS (opcionales):
|
|
48
|
+
- descripción
|
|
49
|
+
|
|
50
|
+
APROBADO: Sí / No
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Si no hay bloqueantes ni advertencias, reporta simplemente: "Revisión completada — sin issues encontrados."
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: session-close
|
|
3
|
+
description: Template para cerrar una sesión de trabajo con Codex CLI
|
|
4
|
+
usage: Copia el contenido de Prompt al final de tu sesión de Codex
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prompt para Codex
|
|
8
|
+
|
|
9
|
+
Cierra la sesión de trabajo. Ejecuta estos checks en orden:
|
|
10
|
+
|
|
11
|
+
1. **Verificar estado del trabajo**
|
|
12
|
+
- Ejecuta `git status --short`.
|
|
13
|
+
- Si hay cambios sin commitear: listarlos. ¿Deben commitearse o descartarse?
|
|
14
|
+
- Ejecuta `git diff --stat HEAD` para ver el resumen de cambios en el último commit.
|
|
15
|
+
|
|
16
|
+
2. **Verificar build y tests**
|
|
17
|
+
- Lee `project.yaml` para el comando de check configurado (`scripts.check`).
|
|
18
|
+
- Si no hay comando configurado: ejecuta el check estándar del stack (tsc --noEmit para TypeScript, py_compile para Python).
|
|
19
|
+
- Reporta si pasan o fallan. Si fallan, listar los errores.
|
|
20
|
+
|
|
21
|
+
3. **Verificar specs**
|
|
22
|
+
- Lee `AGENTS.md` o `CLAUDE.md` para ver el estado de specs activas.
|
|
23
|
+
- Lista specs en `docs/specs/` con estado `APPROVED` que no estén `IMPLEMENTED`.
|
|
24
|
+
- ¿Hay specs en progreso que quedaron incompletas esta sesión? Reportarlas.
|
|
25
|
+
|
|
26
|
+
4. **Registrar progreso**
|
|
27
|
+
- ¿Qué se completó en esta sesión? Lista los archivos modificados:
|
|
28
|
+
`git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only`
|
|
29
|
+
- ¿Qué quedó pendiente?
|
|
30
|
+
- ¿Hay bloqueadores para la próxima sesión?
|
|
31
|
+
|
|
32
|
+
5. **Verificar debug statements olvidados**
|
|
33
|
+
- Ejecuta en archivos modificados: busca `console.log(`, `print(`, `debugger;`.
|
|
34
|
+
- Si hay alguno: listarlos con archivo y línea.
|
|
35
|
+
|
|
36
|
+
6. **Reporte de cierre**
|
|
37
|
+
Presenta este resumen:
|
|
38
|
+
```
|
|
39
|
+
Sesión cerrada — [fecha]
|
|
40
|
+
|
|
41
|
+
Completado:
|
|
42
|
+
- [item 1]
|
|
43
|
+
- [item 2]
|
|
44
|
+
|
|
45
|
+
Pendiente para próxima sesión:
|
|
46
|
+
- [item 1]
|
|
47
|
+
|
|
48
|
+
Bloqueadores:
|
|
49
|
+
- [item o "ninguno"]
|
|
50
|
+
|
|
51
|
+
Estado del repo: [limpio | N archivos con cambios]
|
|
52
|
+
Tests: [pasando | fallando]
|
|
53
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: session-start
|
|
3
|
+
description: Template para iniciar una sesión de trabajo con Codex CLI
|
|
4
|
+
usage: Copia el contenido de Prompt al inicio de tu sesión de Codex
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prompt para Codex
|
|
8
|
+
|
|
9
|
+
Inicia la sesión de trabajo. Ejecuta estos checks en orden y reporta el resultado:
|
|
10
|
+
|
|
11
|
+
1. **Verificar herramientas disponibles**
|
|
12
|
+
- Ejecuta `git --version` — reporta la versión o error.
|
|
13
|
+
- Ejecuta `python3 --version` — reporta la versión o error.
|
|
14
|
+
- Si alguna herramienta crítica falta, reporta el error y detente.
|
|
15
|
+
|
|
16
|
+
2. **Verificar branch actual**
|
|
17
|
+
- Ejecuta `git branch --show-current`.
|
|
18
|
+
- Si el resultado es `main` o `master`: advierte que estás en la branch protegida.
|
|
19
|
+
Sugiere: `git checkout -b feature/<tema>-$(date +%Y-%m-%d)`
|
|
20
|
+
- Si estás en una feature branch: OK.
|
|
21
|
+
|
|
22
|
+
3. **Verificar cambios sin commitear**
|
|
23
|
+
- Ejecuta `git status --short`.
|
|
24
|
+
- Si hay cambios: listarlos y advertir.
|
|
25
|
+
- Si no hay cambios: OK.
|
|
26
|
+
|
|
27
|
+
4. **Verificar project.yaml**
|
|
28
|
+
- Busca `project.yaml` en el directorio actual y directorios padre (hasta 3 niveles).
|
|
29
|
+
- Si no existe: advierte que el proyecto no está inicializado con Forge. Sugiere ejecutar el wizard.
|
|
30
|
+
- Si existe: lee los campos `project.name` y `project.mode`.
|
|
31
|
+
- Si faltan esos campos: advertir.
|
|
32
|
+
- Si están presentes: reportar nombre y modo del proyecto.
|
|
33
|
+
|
|
34
|
+
5. **Verificar variables de producción activas**
|
|
35
|
+
- Ejecuta `env | grep -iE '^(PROD_|PRODUCTION_)'`.
|
|
36
|
+
- Si hay variables de producción activas: ADVERTENCIA — verificar que es intencional trabajar con contexto de producción.
|
|
37
|
+
- Si no hay ninguna: OK.
|
|
38
|
+
|
|
39
|
+
6. **Leer AGENTS.md**
|
|
40
|
+
- Lee `AGENTS.md` en la raíz del repositorio.
|
|
41
|
+
- Confirma que lo leíste y resume el nombre del proyecto y el workflow activo.
|
|
42
|
+
|
|
43
|
+
Formato del reporte final:
|
|
44
|
+
```
|
|
45
|
+
Sesión iniciada — [nombre del proyecto]
|
|
46
|
+
Branch: [nombre]
|
|
47
|
+
Estado: [limpio | N cambios sin commitear]
|
|
48
|
+
Warnings: [lista o "ninguno"]
|
|
49
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship
|
|
3
|
+
description: Template para preparar y verificar el deploy con Codex CLI
|
|
4
|
+
usage: Copia el contenido de Prompt en tu sesión de Codex
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prompt para Codex
|
|
8
|
+
|
|
9
|
+
Prepara el proyecto para deploy en: [ENTORNO: staging | production]
|
|
10
|
+
|
|
11
|
+
Ejecuta estos checks en orden y reporta el resultado de cada uno:
|
|
12
|
+
|
|
13
|
+
1. **Verificar estado del worktree**
|
|
14
|
+
- Ejecuta `git status` — ¿hay cambios sin commitear?
|
|
15
|
+
- Ejecuta `git branch --show-current` — ¿estás en la branch correcta?
|
|
16
|
+
- Si hay cambios sin commitear, detente y reporta cuáles son.
|
|
17
|
+
|
|
18
|
+
2. **Ejecutar tests**
|
|
19
|
+
- Lee `project.yaml` para encontrar el comando de tests (`scripts.test`).
|
|
20
|
+
- Si no está configurado, ejecuta el comando estándar del stack:
|
|
21
|
+
- Node.js: `npm test` o `pnpm test`
|
|
22
|
+
- Python: `pytest`
|
|
23
|
+
- Ruby: `bundle exec rspec`
|
|
24
|
+
- Si los tests fallan, detente. No continuar con el deploy.
|
|
25
|
+
|
|
26
|
+
3. **Verificar build**
|
|
27
|
+
- Lee `project.yaml` para encontrar el comando de build (`scripts.build`).
|
|
28
|
+
- Ejecuta el build y reporta si pasa o falla.
|
|
29
|
+
- Busca errores de TypeScript: `tsc --noEmit` si es un proyecto TypeScript.
|
|
30
|
+
|
|
31
|
+
4. **Verificar variables de entorno**
|
|
32
|
+
- Lee `.env.example` si existe — lista las variables requeridas.
|
|
33
|
+
- Verifica que todas estén documentadas.
|
|
34
|
+
- Busca cualquier variable de entorno hardcodeada en el código (grep por `process.env` sin variable de entorno correspondiente en `.env.example`).
|
|
35
|
+
|
|
36
|
+
5. **Buscar debug statements**
|
|
37
|
+
- Ejecuta: `git diff main --name-only` para ver archivos cambiados.
|
|
38
|
+
- Busca `console.log(`, `print(`, `debugger;`, `var_dump(` en esos archivos.
|
|
39
|
+
- Reporta cada ocurrencia encontrada.
|
|
40
|
+
|
|
41
|
+
6. **Verificar specs implementadas**
|
|
42
|
+
- Lista los specs en `docs/specs/` con estado `APPROVED` (sin `IMPLEMENTED`).
|
|
43
|
+
- Si hay specs aprobadas sin implementar que se esperaban en este deploy, reportarlas.
|
|
44
|
+
|
|
45
|
+
7. **Confirmar proveedor de deploy**
|
|
46
|
+
- Lee `project.yaml` sección `deploy`.
|
|
47
|
+
- Reporta: URL de producción, proveedor, branch de deploy.
|
|
48
|
+
- Si el entorno es `production` y no hay evidencia de que `staging` fue validado primero, advertirlo.
|
|
49
|
+
|
|
50
|
+
Restricciones:
|
|
51
|
+
- Nunca hacer force push a main/master.
|
|
52
|
+
- No continuar si los tests fallan.
|
|
53
|
+
- Si el entorno es `production`, confirmar explícitamente antes de ejecutar cualquier comando de deploy.
|