sdd-es 2.0.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/.claude/settings.json +51 -0
- package/.claude-plugin/marketplace.json +31 -0
- package/.claude-plugin/plugin.json +97 -0
- package/README.md +332 -0
- package/agents/arquitecto.md +148 -0
- package/agents/asesor-datos.md +163 -0
- package/agents/critico.md +142 -0
- package/agents/desarrollador-backend.md +242 -0
- package/agents/desarrollador-frontend.md +120 -0
- package/agents/disenador-api.md +108 -0
- package/agents/documentador.md +177 -0
- package/agents/investigador.md +174 -0
- package/agents/operaciones.md +105 -0
- package/agents/revisor.md +153 -0
- package/agents/seguridad.md +216 -0
- package/agents/tester.md +286 -0
- package/claude-hooks/post-write-conventions.js +412 -0
- package/claude-hooks/pre-tool-guard.js +159 -0
- package/cli/index.js +401 -0
- package/commands/sdd.aclarar.md +200 -0
- package/commands/sdd.analizar.md +241 -0
- package/commands/sdd.ayuda.md +227 -0
- package/commands/sdd.canary.md +60 -0
- package/commands/sdd.checklist.md +174 -0
- package/commands/sdd.comprimir.md +166 -0
- package/commands/sdd.configurar.md +195 -0
- package/commands/sdd.constitucion.md +343 -0
- package/commands/sdd.crear-app.md +168 -0
- package/commands/sdd.crear-mcp.md +174 -0
- package/commands/sdd.descubrir.md +269 -0
- package/commands/sdd.desplegar.md +155 -0
- package/commands/sdd.especificar.md +302 -0
- package/commands/sdd.estado.md +124 -0
- package/commands/sdd.glosario.md +108 -0
- package/commands/sdd.implementar.md +377 -0
- package/commands/sdd.importar.md +91 -0
- package/commands/sdd.mapear.md +120 -0
- package/commands/sdd.md +119 -0
- package/commands/sdd.planificar.md +372 -0
- package/commands/sdd.qa.md +108 -0
- package/commands/sdd.release.md +253 -0
- package/commands/sdd.retro.md +82 -0
- package/commands/sdd.snapshot.md +122 -0
- package/commands/sdd.tareas.md +300 -0
- package/commands/sdd.verificar.md +239 -0
- package/configuracion-ejemplo/hooks-ejemplo/antes_cada_tarea.sh +18 -0
- package/configuracion-ejemplo/hooks-ejemplo/antes_implementar.sh +45 -0
- package/configuracion-ejemplo/hooks-ejemplo/despues_especificar.sh +14 -0
- package/configuracion-ejemplo/hooks-ejemplo/despues_implementar.sh +36 -0
- package/configuracion-ejemplo/hooks-ejemplo/despues_planificar.sh +19 -0
- package/configuracion-ejemplo/hooks-ejemplo/guardia-seguridad.sh +367 -0
- package/configuracion-ejemplo/sdd.config.yaml +310 -0
- package/docs/AGENTES.md +74 -0
- package/docs/COMPRESION.md +155 -0
- package/docs/EJEMPLO-PRACTICA.md +383 -0
- package/docs/EJEMPLOS.md +212 -0
- package/docs/FABRICA.md +185 -0
- package/docs/FILOSOFIA.md +61 -0
- package/docs/FLUJO.md +149 -0
- package/docs/INICIO-RAPIDO.md +116 -0
- package/docs/MAPAS.md +113 -0
- package/docs/MODELOS.md +103 -0
- package/docs/PERSONALIZACION.md +152 -0
- package/instalar.ps1 +39 -0
- package/instalar.sh +22 -0
- package/mcp-figma/README.md +158 -0
- package/mcp-figma/package.json +7 -0
- package/mcp-figma/src/component-generator.js +162 -0
- package/mcp-figma/src/design-system-analyzer.js +247 -0
- package/mcp-figma/src/figma-client.js +75 -0
- package/mcp-figma/src/index.js +114 -0
- package/mcp-figma/src/mcp.js +97 -0
- package/mcp-figma/src/style-mapper.js +85 -0
- package/package.json +50 -0
- package/plantillas/analisis.md +57 -0
- package/plantillas/checklist-especificacion.md +66 -0
- package/plantillas/constitucion.md +104 -0
- package/plantillas/decision-arquitectura.md +39 -0
- package/plantillas/dependencias-mapa.md +89 -0
- package/plantillas/especificacion.md +108 -0
- package/plantillas/estructura-mapa.md +40 -0
- package/plantillas/glosario.md +22 -0
- package/plantillas/index-especificaciones.md +15 -0
- package/plantillas/mcp-server.md +147 -0
- package/plantillas/plan.md +152 -0
- package/plantillas/simbolos-mapa.md +57 -0
- package/plantillas/snapshot.md +54 -0
- package/plantillas/tareas.md +72 -0
- package/presets/enterprise.yaml +69 -0
- package/presets/lean.yaml +63 -0
- package/presets/startup.yaml +67 -0
- package/skills/compresion-tokens.md +264 -0
- package/skills/constitucion-constraint.md +78 -0
- package/skills/deteccion-stack.md +175 -0
- package/skills/enrutador-agentes.md +69 -0
- package/skills/gestion-estado.md +114 -0
- package/skills/indexador.md +199 -0
- package/skills/modo-guiado/SKILL.md +78 -0
- package/skills/orquestacion-ptc/SKILL.md +96 -0
- package/skills/validacion-spec.md +52 -0
- package/skills/verificador-implementacion.md +71 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Implementación mínima del protocolo MCP sobre stdio (JSON-RPC 2.0)
|
|
3
|
+
// Sin dependencias externas — solo Node.js built-ins
|
|
4
|
+
|
|
5
|
+
import { createInterface } from "readline";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {{ name:string, description:string, inputSchema:object, annotations?:object }} ToolDefinition
|
|
9
|
+
* @typedef {(args: Record<string,any>) => Promise<object>} ToolHandler
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {{ name:string, version:string }} serverInfo
|
|
14
|
+
*/
|
|
15
|
+
export function createServer({ name, version }) {
|
|
16
|
+
/** @type {ToolDefinition[]} */
|
|
17
|
+
const tools = [];
|
|
18
|
+
/** @type {Record<string, ToolHandler>} */
|
|
19
|
+
const handlers = {};
|
|
20
|
+
|
|
21
|
+
const rl = createInterface({ input: process.stdin, terminal: false });
|
|
22
|
+
|
|
23
|
+
/** @param {object} obj */
|
|
24
|
+
function send(obj) {
|
|
25
|
+
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {any} id
|
|
30
|
+
* @param {object} result
|
|
31
|
+
*/
|
|
32
|
+
function reply(id, result) {
|
|
33
|
+
send({ jsonrpc: "2.0", id, result });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {any} id
|
|
38
|
+
* @param {number} code
|
|
39
|
+
* @param {string} message
|
|
40
|
+
*/
|
|
41
|
+
function replyError(id, code, message) {
|
|
42
|
+
send({ jsonrpc: "2.0", id, error: { code, message } });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
rl.on("line", async (line) => {
|
|
46
|
+
/** @type {{ id:any, method:string, params:any }} */
|
|
47
|
+
let msg;
|
|
48
|
+
try { msg = JSON.parse(line); } catch { return; }
|
|
49
|
+
|
|
50
|
+
const { id, method, params } = msg;
|
|
51
|
+
|
|
52
|
+
if (method === "initialize") {
|
|
53
|
+
reply(id, {
|
|
54
|
+
protocolVersion: "2024-11-05",
|
|
55
|
+
serverInfo: { name, version },
|
|
56
|
+
capabilities: { tools: {} },
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (method === "notifications/initialized") return;
|
|
62
|
+
if (method === "ping") { reply(id, {}); return; }
|
|
63
|
+
|
|
64
|
+
if (method === "tools/list") {
|
|
65
|
+
reply(id, { tools });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (method === "tools/call") {
|
|
70
|
+
const handler = handlers[params?.name];
|
|
71
|
+
if (!handler) { replyError(id, -32601, `Tool not found: ${params?.name}`); return; }
|
|
72
|
+
try {
|
|
73
|
+
const result = await handler(params?.arguments ?? {});
|
|
74
|
+
reply(id, result);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
reply(id, {
|
|
77
|
+
content: [{ type: "text", text: JSON.stringify({ ok: false, error: /** @type {Error} */ (err).message }) }],
|
|
78
|
+
isError: true,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (id !== undefined) replyError(id, -32601, `Method not found: ${method}`);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
/**
|
|
89
|
+
* @param {ToolDefinition} definition
|
|
90
|
+
* @param {ToolHandler} handler
|
|
91
|
+
*/
|
|
92
|
+
tool(definition, handler) {
|
|
93
|
+
tools.push(definition);
|
|
94
|
+
handlers[definition.name] = handler;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { extractColorFromFill } from "./figma-client.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {{ figmaName: string, figmaValue: string, localToken: string|null, localValue: string, matchType: "exact"|"approximate"|"new", confidence: number }} ColorMapping
|
|
6
|
+
* @typedef {{ type: string, color?: { r:number, g:number, b:number, a?:number } }} Fill
|
|
7
|
+
* @typedef {{ name: string, fills: Fill[] }} FillItem
|
|
8
|
+
* @typedef {{ name: string, style: { fontSize?: number } }} TextItem
|
|
9
|
+
* @typedef {{ colors: Record<string,string>, typography: { fontSizes: Record<string,string> } }} DesignProfile
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @param {string} hex */
|
|
13
|
+
function hexToRgb(hex) {
|
|
14
|
+
const clean = hex.replace("#", "");
|
|
15
|
+
if (clean.length !== 6) return null;
|
|
16
|
+
return [parseInt(clean.slice(0,2),16), parseInt(clean.slice(2,4),16), parseInt(clean.slice(4,6),16)];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @param {string} a @param {string} b */
|
|
20
|
+
function colorDistance(a, b) {
|
|
21
|
+
const ra = hexToRgb(a), rb = hexToRgb(b);
|
|
22
|
+
if (!ra || !rb) return Infinity;
|
|
23
|
+
return Math.sqrt((ra[0]-rb[0])**2 + (ra[1]-rb[1])**2 + (ra[2]-rb[2])**2);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {FillItem[]} fillItems
|
|
28
|
+
* @param {DesignProfile} profile
|
|
29
|
+
* @returns {ColorMapping[]}
|
|
30
|
+
*/
|
|
31
|
+
function mapColors(fillItems, profile) {
|
|
32
|
+
const localEntries = Object.entries(profile.colors);
|
|
33
|
+
return fillItems.map(({ name, fills }) => {
|
|
34
|
+
const figmaHex = fills.map(extractColorFromFill).find(Boolean) ?? null;
|
|
35
|
+
if (!figmaHex) return { figmaName: name, figmaValue: "desconocido", localToken: null, localValue: "desconocido", matchType: "new", confidence: 0 };
|
|
36
|
+
|
|
37
|
+
const exact = localEntries.find(([,v]) => v.toLowerCase() === figmaHex.toLowerCase());
|
|
38
|
+
if (exact) return { figmaName: name, figmaValue: figmaHex, localToken: exact[0], localValue: exact[1], matchType: "exact", confidence: 1 };
|
|
39
|
+
|
|
40
|
+
let best = null, bestDist = Infinity;
|
|
41
|
+
for (const [token, value] of localEntries) {
|
|
42
|
+
const dist = colorDistance(figmaHex, value);
|
|
43
|
+
if (dist < bestDist) { bestDist = dist; best = [token, value]; }
|
|
44
|
+
}
|
|
45
|
+
if (best && bestDist < 30) return { figmaName: name, figmaValue: figmaHex, localToken: best[0], localValue: best[1], matchType: "approximate", confidence: Math.max(0, 1 - bestDist/30) };
|
|
46
|
+
|
|
47
|
+
return { figmaName: name, figmaValue: figmaHex, localToken: null, localValue: figmaHex, matchType: "new", confidence: 0 };
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {TextItem[]} textItems
|
|
53
|
+
* @param {DesignProfile} profile
|
|
54
|
+
* @returns {ColorMapping[]}
|
|
55
|
+
*/
|
|
56
|
+
function mapTypography(textItems, profile) {
|
|
57
|
+
return textItems.map(({ name, style }) => {
|
|
58
|
+
const figmaSize = style.fontSize ? `${style.fontSize}px` : null;
|
|
59
|
+
if (!figmaSize) return { figmaName: name, figmaValue: "desconocido", localToken: null, localValue: "desconocido", matchType: "new", confidence: 0 };
|
|
60
|
+
const match = Object.entries(profile.typography.fontSizes).find(([,v]) => v === figmaSize);
|
|
61
|
+
if (match) return { figmaName: name, figmaValue: figmaSize, localToken: match[0], localValue: match[1], matchType: "exact", confidence: 1 };
|
|
62
|
+
return { figmaName: name, figmaValue: figmaSize, localToken: null, localValue: figmaSize, matchType: "new", confidence: 0 };
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {ColorMapping[]} colorMappings
|
|
68
|
+
* @param {ColorMapping[]} typographyMappings
|
|
69
|
+
*/
|
|
70
|
+
function buildMappingReport(colorMappings, typographyMappings) {
|
|
71
|
+
const all = [...colorMappings, ...typographyMappings];
|
|
72
|
+
const unmapped = [
|
|
73
|
+
...colorMappings.filter(m => m.matchType === "new").map(m => `color: ${m.figmaName} (${m.figmaValue})`),
|
|
74
|
+
...typographyMappings.filter(m => m.matchType === "new").map(m => `tipografía: ${m.figmaName} (${m.figmaValue})`),
|
|
75
|
+
];
|
|
76
|
+
const total = all.length;
|
|
77
|
+
let recommendation = "";
|
|
78
|
+
if (total === 0) recommendation = "No hay estilos en Figma para mapear.";
|
|
79
|
+
else if (unmapped.length === 0) recommendation = "✅ Todos los estilos de Figma coinciden con tokens existentes.";
|
|
80
|
+
else if (unmapped.length <= 3) recommendation = `⚠️ ${unmapped.length} estilo(s) nuevo(s) sin equivalente en el proyecto.`;
|
|
81
|
+
else recommendation = `❌ ${unmapped.length} estilos sin equivalente — considera sincronizar el design system con Figma.`;
|
|
82
|
+
return { colors: colorMappings, typography: typographyMappings, unmapped, recommendation };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { mapColors, mapTypography, buildMappingReport };
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sdd-es",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Spec-Driven Development en español para Claude Code. Fábrica de software: de la idea al despliegue, agnóstica al stack. Instalador multiplataforma.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sdd-es": "cli/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node --test tests/*.test.js",
|
|
11
|
+
"test:verbose": "node --test --reporter=spec tests/*.test.js",
|
|
12
|
+
"init": "node cli/index.js init",
|
|
13
|
+
"doctor": "node cli/index.js doctor"
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18.0.0"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"cli/",
|
|
20
|
+
"commands/",
|
|
21
|
+
"agents/",
|
|
22
|
+
"skills/",
|
|
23
|
+
"plantillas/",
|
|
24
|
+
"presets/",
|
|
25
|
+
"claude-hooks/",
|
|
26
|
+
"configuracion-ejemplo/",
|
|
27
|
+
"docs/",
|
|
28
|
+
"mcp-figma/",
|
|
29
|
+
".claude-plugin/",
|
|
30
|
+
".claude/settings.json",
|
|
31
|
+
"instalar.sh",
|
|
32
|
+
"instalar.ps1",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"keywords": [
|
|
36
|
+
"claude-code",
|
|
37
|
+
"spec-driven-development",
|
|
38
|
+
"sdd",
|
|
39
|
+
"español",
|
|
40
|
+
"agentes",
|
|
41
|
+
"mcp",
|
|
42
|
+
"plugin"
|
|
43
|
+
],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"homepage": "https://github.com/carlos060798/sdd-lite",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/carlos060798/sdd-lite.git"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec_id: [SPEC_ID]
|
|
3
|
+
fecha_analisis: [FECHA]
|
|
4
|
+
veredicto: APROBADO # APROBADO | OBSERVACIONES | BLOQUEADO
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Análisis de Consistencia: [SPEC_ID]
|
|
8
|
+
|
|
9
|
+
## Veredicto: **[VEREDICTO]**
|
|
10
|
+
|
|
11
|
+
[Resumen ejecutivo, 1-2 frases]
|
|
12
|
+
|
|
13
|
+
## Hallazgos
|
|
14
|
+
|
|
15
|
+
### 🔴 Bloqueantes
|
|
16
|
+
#### B1 — [Título]
|
|
17
|
+
- **Dimensión:** [Constitución/Plan/Tareas/etc.]
|
|
18
|
+
- **Descripción:** [qué inconsistencia]
|
|
19
|
+
- **Ubicación:** [archivo:sección]
|
|
20
|
+
- **Impacto si se ignora:** [consecuencia]
|
|
21
|
+
- **Acción sugerida:** [qué hacer]
|
|
22
|
+
|
|
23
|
+
### 🟡 Observaciones
|
|
24
|
+
[mismo formato]
|
|
25
|
+
|
|
26
|
+
### 🟢 Buenas señales
|
|
27
|
+
[áreas correctas]
|
|
28
|
+
|
|
29
|
+
## Matriz de Cobertura: CAs → Tareas
|
|
30
|
+
|
|
31
|
+
| CA | Descripción | Tareas | Estado |
|
|
32
|
+
|----|-------------|--------|--------|
|
|
33
|
+
| CA-001-01 | [texto] | T001, T005 | ✅ |
|
|
34
|
+
|
|
35
|
+
## Matriz de Cobertura: Riesgos → Mitigaciones
|
|
36
|
+
|
|
37
|
+
| Riesgo | Prob × Imp | Mitigación | Estado |
|
|
38
|
+
|--------|-----------|-----------|--------|
|
|
39
|
+
| R1 | A × A | T004 | ✅ |
|
|
40
|
+
|
|
41
|
+
## Cumplimiento de Constitución
|
|
42
|
+
|
|
43
|
+
| Principio | Plan | Tareas | Notas |
|
|
44
|
+
|-----------|------|--------|-------|
|
|
45
|
+
| Principio I | ✅ | ✅ | — |
|
|
46
|
+
|
|
47
|
+
## Distribución de Agentes
|
|
48
|
+
|
|
49
|
+
| Agente | Tareas | % |
|
|
50
|
+
|--------|--------|---|
|
|
51
|
+
| arquitecto | [N] | [%] |
|
|
52
|
+
|
|
53
|
+
## Recomendaciones
|
|
54
|
+
1. [Acción priorizada]
|
|
55
|
+
|
|
56
|
+
## Siguiente comando sugerido
|
|
57
|
+
`/sdd.[comando]`
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Checklist de Calidad: [SPEC_ID]
|
|
2
|
+
|
|
3
|
+
> Fecha: [FECHA] | Veredicto: [APROBADA | NECESITA_REVISION | RECHAZADA]
|
|
4
|
+
|
|
5
|
+
## Puntuación
|
|
6
|
+
- Total: [N] ítems | Pasados: [N] | Fallidos: [N] | Parciales: [N]
|
|
7
|
+
- Cobertura: [%]
|
|
8
|
+
|
|
9
|
+
## A. Calidad de Contenido
|
|
10
|
+
- [✅/❌/⚠️] A1: Sin detalles de implementación
|
|
11
|
+
- [ ] A2: Foco en valor para usuario
|
|
12
|
+
- [ ] A3: Legible por no-técnico
|
|
13
|
+
- [ ] A4: Secciones obligatorias completadas
|
|
14
|
+
- [ ] A5: Frontmatter bien formado
|
|
15
|
+
|
|
16
|
+
## B. Completitud de Requisitos
|
|
17
|
+
- [ ] B1: Sin [NECESITA_ACLARACION] críticos
|
|
18
|
+
- [ ] B2: Requisitos testeables
|
|
19
|
+
- [ ] B3: Sin ambigüedad
|
|
20
|
+
- [ ] B4: Dado/Cuando/Entonces formal
|
|
21
|
+
- [ ] B5: Escenarios completos
|
|
22
|
+
- [ ] B6: Fuera de alcance definido
|
|
23
|
+
- [ ] B7: Dependencias identificadas
|
|
24
|
+
- [ ] B8: Asunciones explícitas
|
|
25
|
+
|
|
26
|
+
## C. Calidad de CAs
|
|
27
|
+
- [ ] C1: IDs únicos
|
|
28
|
+
- [ ] C2: Atómicos
|
|
29
|
+
- [ ] C3: Observables externamente
|
|
30
|
+
- [ ] C4: Prioridad asignada
|
|
31
|
+
- [ ] C5: Convertible a test
|
|
32
|
+
|
|
33
|
+
## D. Cobertura de Escenarios
|
|
34
|
+
- [ ] D1: Caso feliz
|
|
35
|
+
- [ ] D2: Caso de error
|
|
36
|
+
- [ ] D3: Caso borde
|
|
37
|
+
- [ ] D4: Concurrencia (si aplica)
|
|
38
|
+
- [ ] D5: Datos extremos
|
|
39
|
+
- [ ] D6: Fallos de dependencias
|
|
40
|
+
|
|
41
|
+
## E. Cumplimiento de Constitución
|
|
42
|
+
- [ ] E1: Restricciones respetadas
|
|
43
|
+
- [ ] E2: Estándares de calidad
|
|
44
|
+
- [ ] E3: Sin conflictos con principios
|
|
45
|
+
- [ ] E4: Versión registrada
|
|
46
|
+
|
|
47
|
+
## F. Dominio
|
|
48
|
+
- [ ] F1: Términos nuevos listados
|
|
49
|
+
- [ ] F2: Consistencia con glosario
|
|
50
|
+
- [ ] F3: Sin sinónimos confusos
|
|
51
|
+
|
|
52
|
+
## G. Trazabilidad
|
|
53
|
+
- [ ] G1: CAs vinculados a historias
|
|
54
|
+
- [ ] G2: RFs vinculados a objetivo
|
|
55
|
+
- [ ] G3: Enlaces a recursos externos
|
|
56
|
+
|
|
57
|
+
## H. Métricas
|
|
58
|
+
- [ ] H1: Criterios medibles
|
|
59
|
+
- [ ] H2: Alcanzables
|
|
60
|
+
- [ ] H3: Verificables post-lanzamiento
|
|
61
|
+
|
|
62
|
+
## Hallazgos críticos
|
|
63
|
+
[Ítems FALLIDOS que bloquean]
|
|
64
|
+
|
|
65
|
+
## Recomendaciones
|
|
66
|
+
[Lista accionable]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
INFORME DE IMPACTO DE SINCRONIZACIÓN
|
|
3
|
+
====================================
|
|
4
|
+
Cambio de versión: [VERSION_ANTERIOR] → [VERSION_NUEVA]
|
|
5
|
+
Tipo de cambio: [MAYOR | MENOR | PARCHE]
|
|
6
|
+
|
|
7
|
+
Principios modificados:
|
|
8
|
+
- [Lista de cambios]
|
|
9
|
+
|
|
10
|
+
Plantillas que requieren actualización:
|
|
11
|
+
- plantillas/especificacion.md [✅ alineada | ⚠ pendiente]
|
|
12
|
+
- plantillas/plan.md [✅ | ⚠]
|
|
13
|
+
- plantillas/tareas.md [✅ | ⚠]
|
|
14
|
+
- commands/*.md [✅ | ⚠]
|
|
15
|
+
|
|
16
|
+
TODOs diferidos:
|
|
17
|
+
- [Lista]
|
|
18
|
+
-->
|
|
19
|
+
|
|
20
|
+
# Constitución del Proyecto: [NOMBRE_PROYECTO]
|
|
21
|
+
|
|
22
|
+
> **Versión:** [X.Y.Z] | **Ratificada:** [FECHA_RATIFICACION] | **Última enmienda:** [FECHA_HOY]
|
|
23
|
+
|
|
24
|
+
## Propósito y Misión
|
|
25
|
+
|
|
26
|
+
[Descripción del propósito del proyecto en 2-3 frases. Qué problema resuelve y para quién.]
|
|
27
|
+
|
|
28
|
+
## Stack Técnico
|
|
29
|
+
|
|
30
|
+
| Aspecto | Valor |
|
|
31
|
+
|---------|-------|
|
|
32
|
+
| Lenguaje principal | [LENGUAJE] |
|
|
33
|
+
| Framework | [FRAMEWORK o "ninguno"] |
|
|
34
|
+
| Almacenamiento | [BASE_DATOS o "por definir"] |
|
|
35
|
+
| Tests | [FRAMEWORK_TESTS] |
|
|
36
|
+
| Build/Bundler | [HERRAMIENTA] |
|
|
37
|
+
| Despliegue | [DESTINO] |
|
|
38
|
+
|
|
39
|
+
> Cualquier cambio de stack requiere un ADR en `.sdd/arquitectura/`.
|
|
40
|
+
|
|
41
|
+
## Principios Fundamentales
|
|
42
|
+
|
|
43
|
+
### Principio I: [NOMBRE_PRINCIPIO_1]
|
|
44
|
+
|
|
45
|
+
[Descripción declarativa. Usa MUST/MUST NOT/SHOULD/MAY (DEBE/NO DEBE/DEBERÍA/PUEDE) explícitamente.]
|
|
46
|
+
|
|
47
|
+
**Razón:** [Por qué este principio existe]
|
|
48
|
+
|
|
49
|
+
### Principio II: [NOMBRE_PRINCIPIO_2]
|
|
50
|
+
|
|
51
|
+
[Descripción]
|
|
52
|
+
|
|
53
|
+
**Razón:** [Por qué]
|
|
54
|
+
|
|
55
|
+
### Principio III: [NOMBRE_PRINCIPIO_3]
|
|
56
|
+
|
|
57
|
+
[Descripción]
|
|
58
|
+
|
|
59
|
+
**Razón:** [Por qué]
|
|
60
|
+
|
|
61
|
+
## Estándares de Calidad
|
|
62
|
+
|
|
63
|
+
- **Tests:** cobertura mínima [X]%. Tests obligatorios para [áreas].
|
|
64
|
+
- **Linting:** [HERRAMIENTA] con configuración estricta. Sin warnings en CI.
|
|
65
|
+
- **Tipos:** [Estricto/Opcional]. [Detalles del type-checker].
|
|
66
|
+
- **Formato:** [HERRAMIENTA]. Aplicado automáticamente.
|
|
67
|
+
- **Revisión:** cada cambio pasa por el agente `revisor` antes de marcar tareas como completas.
|
|
68
|
+
|
|
69
|
+
## Restricciones Arquitectónicas
|
|
70
|
+
|
|
71
|
+
[Lista de cosas que NUNCA hay que hacer:]
|
|
72
|
+
|
|
73
|
+
- NO agregar dependencias nuevas sin ADR
|
|
74
|
+
- NO romper la API pública sin bump de versión MAYOR
|
|
75
|
+
- NO mezclar lógica de presentación con dominio
|
|
76
|
+
- [...]
|
|
77
|
+
|
|
78
|
+
## Convenciones
|
|
79
|
+
|
|
80
|
+
### Nomenclatura
|
|
81
|
+
- Archivos: [convención]
|
|
82
|
+
- Variables: [convención]
|
|
83
|
+
- Constantes: [convención]
|
|
84
|
+
- Tipos/Clases: [convención]
|
|
85
|
+
|
|
86
|
+
### Estructura
|
|
87
|
+
[Cómo se organizan los directorios y módulos]
|
|
88
|
+
|
|
89
|
+
## Proceso de Cambios (Flujo SDD-ES)
|
|
90
|
+
|
|
91
|
+
1. Todo cambio empieza con `/sdd.especificar`
|
|
92
|
+
2. La spec se clarifica con `/sdd.aclarar` si hay ambigüedad
|
|
93
|
+
3. El plan técnico se aprueba con `/sdd.planificar aprobar`
|
|
94
|
+
4. Las tareas se generan con `/sdd.tareas`
|
|
95
|
+
5. La consistencia se valida con `/sdd.analizar`
|
|
96
|
+
6. La implementación se ejecuta con `/sdd.implementar`
|
|
97
|
+
7. El cumplimiento se verifica con `/sdd.verificar`
|
|
98
|
+
|
|
99
|
+
## Gobernanza
|
|
100
|
+
|
|
101
|
+
- Esta constitución sigue versionado semántico (MAYOR.MENOR.PARCHE)
|
|
102
|
+
- Cualquier cambio se registra en el "Informe de Impacto de Sincronización" arriba
|
|
103
|
+
- Las enmiendas requieren actualizar las plantillas y comandos afectados
|
|
104
|
+
- Las decisiones técnicas no triviales se documentan como ADR en `.sdd/arquitectura/`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ADR-[NN]: [Título de la decisión]
|
|
2
|
+
|
|
3
|
+
> Estado: aceptada # propuesta | aceptada | obsoleta | reemplazada-por-ADR-XX
|
|
4
|
+
> Fecha: [FECHA]
|
|
5
|
+
> Spec relacionada: [SPEC_ID]
|
|
6
|
+
> Autor: [agente o humano]
|
|
7
|
+
|
|
8
|
+
## Contexto
|
|
9
|
+
|
|
10
|
+
[Qué problema enfrentamos. Qué circunstancias hicieron necesaria la decisión.]
|
|
11
|
+
|
|
12
|
+
## Decisión
|
|
13
|
+
|
|
14
|
+
[Qué decidimos hacer, en una frase clara y declarativa.]
|
|
15
|
+
|
|
16
|
+
## Alternativas consideradas
|
|
17
|
+
|
|
18
|
+
- **A. [Opción 1]**: rechazada porque [razón]
|
|
19
|
+
- **B. [Opción 2]**: rechazada porque [razón]
|
|
20
|
+
- **C. [Opción elegida]**: aceptada porque [razón]
|
|
21
|
+
|
|
22
|
+
## Consecuencias
|
|
23
|
+
|
|
24
|
+
### Positivas
|
|
25
|
+
- [Consecuencia]
|
|
26
|
+
|
|
27
|
+
### Negativas
|
|
28
|
+
- [Consecuencia]
|
|
29
|
+
|
|
30
|
+
### Neutrales
|
|
31
|
+
- [Consecuencia]
|
|
32
|
+
|
|
33
|
+
## Cuándo revisitar
|
|
34
|
+
|
|
35
|
+
[Condición específica que invalidaría esta decisión]
|
|
36
|
+
|
|
37
|
+
## Referencias
|
|
38
|
+
|
|
39
|
+
- [Issue, doc, paper]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
generado_por: /sdd.mapear
|
|
3
|
+
fecha: [FECHA]
|
|
4
|
+
proyecto: [NOMBRE_PROYECTO]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Mapa de Dependencias
|
|
8
|
+
|
|
9
|
+
Grafo de imports entre archivos. Muestra quién depende de quién y detecta acoplamientos.
|
|
10
|
+
|
|
11
|
+
Generado automáticamente por `/sdd.mapear`.
|
|
12
|
+
|
|
13
|
+
## Convención
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
archivo-a.ts
|
|
17
|
+
↳ depende: [lista de archivos que importa]
|
|
18
|
+
↳ usado por: [lista de archivos que lo importan]
|
|
19
|
+
↳ importado por: [N] archivos
|
|
20
|
+
|
|
21
|
+
[línea en blanco]
|
|
22
|
+
|
|
23
|
+
archivo-b.ts
|
|
24
|
+
↳ depende: ...
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Grafo
|
|
28
|
+
|
|
29
|
+
[DEPENDENCIAS AQUÍ]
|
|
30
|
+
|
|
31
|
+
Ejemplo:
|
|
32
|
+
|
|
33
|
+
```markdown
|
|
34
|
+
auth/login.service.ts
|
|
35
|
+
↳ depende: users/user.repo.ts, shared/logger.ts, auth/session.repo.ts
|
|
36
|
+
↳ usado por: auth/auth.controller.ts
|
|
37
|
+
↳ importado por: 1 archivo
|
|
38
|
+
|
|
39
|
+
auth/magic-link.service.ts
|
|
40
|
+
↳ depende: users/user.repo.ts, shared/email.service.ts
|
|
41
|
+
↳ usado por: auth/auth.controller.ts
|
|
42
|
+
↳ importado por: 1 archivo
|
|
43
|
+
|
|
44
|
+
users/user.service.ts
|
|
45
|
+
↳ depende: users/user.repo.ts, shared/logger.ts
|
|
46
|
+
↳ usado por: users/user.controller.ts, auth/login.service.ts
|
|
47
|
+
↳ importado por: 2 archivos
|
|
48
|
+
|
|
49
|
+
shared/logger.ts
|
|
50
|
+
↳ depende: [ninguno — es utilidad]
|
|
51
|
+
↳ usado por: 47 archivos (alto, esperado para logger)
|
|
52
|
+
↳ importado por: 47 archivos
|
|
53
|
+
|
|
54
|
+
shared/errors.ts
|
|
55
|
+
↳ depende: [ninguno — solo tipos]
|
|
56
|
+
↳ usado por: 23 archivos
|
|
57
|
+
↳ importado por: 23 archivos
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Análisis
|
|
61
|
+
|
|
62
|
+
### Acoplamientos detectados
|
|
63
|
+
|
|
64
|
+
| Archivo | Usos | Criticidad | Notas |
|
|
65
|
+
|---------|------|-----------|-------|
|
|
66
|
+
| shared/logger.ts | 47 | Normal | Expected — logger global |
|
|
67
|
+
| shared/errors.ts | 23 | Normal | Expected — tipos de error |
|
|
68
|
+
| users/user.repo.ts | 8 | Medio | Revisión futura: abstraer? |
|
|
69
|
+
|
|
70
|
+
### Ciclos detectados
|
|
71
|
+
|
|
72
|
+
✅ Ninguno — grafo acíclico
|
|
73
|
+
|
|
74
|
+
(Si hay ciclos: REVISAR. Son problemas de arquitectura.)
|
|
75
|
+
|
|
76
|
+
## Cómo usarlo
|
|
77
|
+
|
|
78
|
+
### Al implementar un cambio
|
|
79
|
+
|
|
80
|
+
1. Editas `users/user.repo.ts`
|
|
81
|
+
2. Consultas este mapa: "¿quién usa user.repo.ts?"
|
|
82
|
+
3. Respuesta: 8 archivos lo importan
|
|
83
|
+
4. Revisas si tu cambio los rompe
|
|
84
|
+
|
|
85
|
+
### Al planificar refactor
|
|
86
|
+
|
|
87
|
+
1. Ves que auth/ depende mucho de users/
|
|
88
|
+
2. Consideras abstraer interfaz
|
|
89
|
+
3. Revisas si la abstracción mejora el grafo
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: [ID]
|
|
3
|
+
titulo: "[TITULO_HUMANO]"
|
|
4
|
+
tamano: pequeño # micro | pequeño | mediano | grande
|
|
5
|
+
estado: borrador # borrador | en_revision | aprobada | en_implementacion | completada
|
|
6
|
+
creada: [FECHA]
|
|
7
|
+
actualizada: [FECHA]
|
|
8
|
+
autor: humano # humano | importado
|
|
9
|
+
constitucion_version: [X.Y.Z]
|
|
10
|
+
etiquetas: []
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Especificación: [TITULO]
|
|
14
|
+
|
|
15
|
+
## 1. Contexto y Motivación
|
|
16
|
+
|
|
17
|
+
[2-4 frases. POR QUÉ se necesita esto. Qué problema resuelve. Motivación de negocio o usuario, NO técnica.]
|
|
18
|
+
|
|
19
|
+
## 2. Objetivo
|
|
20
|
+
|
|
21
|
+
[QUÉ debe lograr cuando esté terminado. 1-3 frases declarativas. Sin detalles de implementación.]
|
|
22
|
+
|
|
23
|
+
## 3. Usuarios y Actores
|
|
24
|
+
|
|
25
|
+
| Actor | Rol | Necesidad principal |
|
|
26
|
+
|-------|-----|---------------------|
|
|
27
|
+
| [Actor 1] | [rol] | [qué quiere lograr] |
|
|
28
|
+
|
|
29
|
+
## 4. Historias de Usuario
|
|
30
|
+
|
|
31
|
+
### HU-001: [Título corto]
|
|
32
|
+
**Como** [tipo de usuario]
|
|
33
|
+
**Quiero** [acción/capacidad]
|
|
34
|
+
**Para** [beneficio/valor]
|
|
35
|
+
|
|
36
|
+
**Criterios de aceptación:**
|
|
37
|
+
- [ ] **CA-001-01**: [criterio testeable] (P1)
|
|
38
|
+
- [ ] **CA-001-02**: [criterio testeable] (P1)
|
|
39
|
+
- [ ] **CA-001-03**: [criterio testeable] (P2)
|
|
40
|
+
|
|
41
|
+
## 5. Escenarios de Uso
|
|
42
|
+
|
|
43
|
+
### Escenario 1: Caso feliz
|
|
44
|
+
**Dado** [estado inicial]
|
|
45
|
+
**Cuando** [acción del actor]
|
|
46
|
+
**Entonces** [resultado esperado]
|
|
47
|
+
|
|
48
|
+
### Escenario 2: Caso de error
|
|
49
|
+
**Dado** [precondición]
|
|
50
|
+
**Cuando** [acción incorrecta]
|
|
51
|
+
**Entonces** [manejo de error esperado]
|
|
52
|
+
|
|
53
|
+
### Escenario 3: Caso borde
|
|
54
|
+
**Dado** [precondición borde]
|
|
55
|
+
**Cuando** [acción]
|
|
56
|
+
**Entonces** [comportamiento esperado]
|
|
57
|
+
|
|
58
|
+
## 6. Requisitos Funcionales
|
|
59
|
+
|
|
60
|
+
- **RF-001**: El sistema DEBE [acción específica]
|
|
61
|
+
- **RF-002**: El sistema DEBE [acción específica]
|
|
62
|
+
- **RF-003**: El sistema NO DEBE [acción prohibida]
|
|
63
|
+
|
|
64
|
+
## 7. Requisitos No Funcionales
|
|
65
|
+
|
|
66
|
+
| Categoría | Requisito | Métrica |
|
|
67
|
+
|-----------|-----------|---------|
|
|
68
|
+
| Rendimiento | [requisito] | [métrica] |
|
|
69
|
+
| Seguridad | [requisito] | [criterio] |
|
|
70
|
+
| Disponibilidad | [requisito] | [SLO] |
|
|
71
|
+
| Accesibilidad | [requisito] | [estándar] |
|
|
72
|
+
|
|
73
|
+
## 8. Fuera de Alcance (Exclusiones Explícitas)
|
|
74
|
+
|
|
75
|
+
- ❌ [Cosa que NO se hará]
|
|
76
|
+
- ❌ [Cosa que NO se hará]
|
|
77
|
+
|
|
78
|
+
## 9. Dependencias y Asunciones
|
|
79
|
+
|
|
80
|
+
### Dependencias
|
|
81
|
+
- [Otra spec, feature, servicio externo]
|
|
82
|
+
|
|
83
|
+
### Asunciones
|
|
84
|
+
- [Lo que se asume]
|
|
85
|
+
- [NECESITA_ACLARACION]: [si hay algo asumido sin certeza]
|
|
86
|
+
|
|
87
|
+
## 10. Términos del Dominio
|
|
88
|
+
|
|
89
|
+
- **[Término]**: [definición]
|
|
90
|
+
|
|
91
|
+
## 11. Preguntas Abiertas
|
|
92
|
+
|
|
93
|
+
- [ ] [NECESITA_ACLARACION]: [pregunta crítica]
|
|
94
|
+
- [ ] [POR_DECIDIR]: [decisión pospuesta]
|
|
95
|
+
|
|
96
|
+
## 12. Criterios de Éxito Medibles
|
|
97
|
+
|
|
98
|
+
- [Métrica 1 con número]
|
|
99
|
+
- [Métrica 2 con número]
|
|
100
|
+
|
|
101
|
+
## 13. Referencias
|
|
102
|
+
|
|
103
|
+
- [Issue, mockup, doc relacionado]
|
|
104
|
+
|
|
105
|
+
## 14. Historial de Aclaraciones
|
|
106
|
+
|
|
107
|
+
| # | Categoría | Pregunta | Decisión | Fecha |
|
|
108
|
+
|---|-----------|----------|----------|-------|
|