zugzbot-sdd 1.5.34 → 1.5.35
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.
|
@@ -44,7 +44,8 @@ export default tool({
|
|
|
44
44
|
category: tool.schema.string().optional().describe("Categoría del aprendizaje para el cerebro"),
|
|
45
45
|
tag: tool.schema.string().optional().describe("Tag corto del aprendizaje para el cerebro"),
|
|
46
46
|
problem: tool.schema.string().optional().describe("Problema resuelto (máx 120 caracteres)"),
|
|
47
|
-
solution: tool.schema.string().optional().describe("Solución aplicada (máx 300 caracteres)")
|
|
47
|
+
solution: tool.schema.string().optional().describe("Solución aplicada (máx 300 caracteres)"),
|
|
48
|
+
bypassPendingTasks: tool.schema.boolean().optional().default(false).describe("Ignorar/Bypassear la verificación de tareas pendientes en el lockfile si el usuario aprobó manualmente o es un flujo QA Manual")
|
|
48
49
|
},
|
|
49
50
|
async execute(args, context) {
|
|
50
51
|
const projectRoot = context.worktree || context.directory;
|
|
@@ -57,11 +58,23 @@ export default tool({
|
|
|
57
58
|
if (fs.existsSync(lockfilePath)) {
|
|
58
59
|
try {
|
|
59
60
|
const lockfile = JSON.parse(fs.readFileSync(lockfilePath, "utf-8"));
|
|
61
|
+
const isManualQa = lockfile.qa_manual === true || lockfile.manual_qa === true;
|
|
62
|
+
const shouldBypass = args.bypassPendingTasks === true || isManualQa;
|
|
60
63
|
if (lockfile.tasks && Array.isArray(lockfile.tasks) && lockfile.tasks.length > 0) {
|
|
61
64
|
const pendingTasks = lockfile.tasks.filter((t) => t.status === "pending");
|
|
62
65
|
if (pendingTasks.length > 0) {
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
if (shouldBypass) {
|
|
67
|
+
// Auto-completar tareas en caliente para dejar el lockfile limpio
|
|
68
|
+
lockfile.tasks.forEach((t) => {
|
|
69
|
+
if (t.status === "pending")
|
|
70
|
+
t.status = "completed";
|
|
71
|
+
});
|
|
72
|
+
fs.writeFileSync(lockfilePath, JSON.stringify(lockfile, null, 2), "utf-8");
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const pendingList = pendingTasks.map((t) => ` ⚠️ [${t.id}] ${t.desc}`).join("\n");
|
|
76
|
+
return `[SDD Archive Blocked] No se puede cerrar el ciclo. Hay ${pendingTasks.length} tarea(s) pendiente(s):\n${pendingList}\n\nPor favor, completa todas las tareas o fuerza el cierre con aprobación explícita del usuario.`;
|
|
77
|
+
}
|
|
65
78
|
}
|
|
66
79
|
}
|
|
67
80
|
}
|
package/package.json
CHANGED
|
@@ -43,7 +43,8 @@ export default tool({
|
|
|
43
43
|
category: tool.schema.string().optional().describe("Categoría del aprendizaje para el cerebro"),
|
|
44
44
|
tag: tool.schema.string().optional().describe("Tag corto del aprendizaje para el cerebro"),
|
|
45
45
|
problem: tool.schema.string().optional().describe("Problema resuelto (máx 120 caracteres)"),
|
|
46
|
-
solution: tool.schema.string().optional().describe("Solución aplicada (máx 300 caracteres)")
|
|
46
|
+
solution: tool.schema.string().optional().describe("Solución aplicada (máx 300 caracteres)"),
|
|
47
|
+
bypassPendingTasks: tool.schema.boolean().optional().default(false).describe("Ignorar/Bypassear la verificación de tareas pendientes en el lockfile si el usuario aprobó manualmente o es un flujo QA Manual")
|
|
47
48
|
},
|
|
48
49
|
async execute(args, context) {
|
|
49
50
|
const projectRoot = context.worktree || context.directory
|
|
@@ -58,11 +59,22 @@ export default tool({
|
|
|
58
59
|
if (fs.existsSync(lockfilePath)) {
|
|
59
60
|
try {
|
|
60
61
|
const lockfile = JSON.parse(fs.readFileSync(lockfilePath, "utf-8"))
|
|
62
|
+
const isManualQa = lockfile.qa_manual === true || lockfile.manual_qa === true
|
|
63
|
+
const shouldBypass = args.bypassPendingTasks === true || isManualQa
|
|
64
|
+
|
|
61
65
|
if (lockfile.tasks && Array.isArray(lockfile.tasks) && lockfile.tasks.length > 0) {
|
|
62
66
|
const pendingTasks = lockfile.tasks.filter((t: any) => t.status === "pending")
|
|
63
67
|
if (pendingTasks.length > 0) {
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
if (shouldBypass) {
|
|
69
|
+
// Auto-completar tareas en caliente para dejar el lockfile limpio
|
|
70
|
+
lockfile.tasks.forEach((t: any) => {
|
|
71
|
+
if (t.status === "pending") t.status = "completed"
|
|
72
|
+
})
|
|
73
|
+
fs.writeFileSync(lockfilePath, JSON.stringify(lockfile, null, 2), "utf-8")
|
|
74
|
+
} else {
|
|
75
|
+
const pendingList = pendingTasks.map((t: any) => ` ⚠️ [${t.id}] ${t.desc}`).join("\n")
|
|
76
|
+
return `[SDD Archive Blocked] No se puede cerrar el ciclo. Hay ${pendingTasks.length} tarea(s) pendiente(s):\n${pendingList}\n\nPor favor, completa todas las tareas o fuerza el cierre con aprobación explícita del usuario.`
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
}
|
|
68
80
|
} catch (e: any) {}
|