agent-mp 0.5.27 → 0.5.29

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 (2) hide show
  1. package/dist/core/engine.js +95 -10
  2. package/package.json +1 -1
@@ -415,11 +415,15 @@ MODO SPEC — Feature cargada: "${activeFeatureId}"
415
415
  Los archivos raw YA ESTÁN en el CONTEXTO DEL PROYECTO arriba.
416
416
 
417
417
  REGLAS CRÍTICAS:
418
- 1. ANTES DE ESCRIBIR CUALQUIER COSA: leé completo cada archivo raw del contexto.
419
- 2. NO preguntes sobre información que ya está en los archivos raw. Si el lenguaje, stack, objetivo, contexto o requisitos están en los archivos, USÁ ESA INFORMACIÓN directamente.
420
- 3. Solo hacé preguntas sobre información que GENUINAMENTE falta y que no podés inferir de los archivos.
421
- 4. Si los archivos ya tienen suficiente información para entender el objetivo, NO hagas preguntas generá el spec.md directamente.
422
- 5. Cuando tengas todo claro (o si los archivos ya tienen suficiente info), generá el spec.md con este formato EXACTO:
418
+ 1. ANTES DE ESCRIBIR CUALQUIER COSA: leé completo el CONTEXTO DEL PROYECTO, incluyendo la sección "TAREA EXISTENTE" si está presente.
419
+ 2. SI EXISTE "TAREA EXISTENTE" en el contexto:
420
+ - Si hay SPEC.MD EXISTENTE: NO lo regeneres. Usalo como referencia.
421
+ - Si hay RESULTADO PREVIO: FAIL: informá al usuario qué falló y preguntá si quiere corregir eso específico.
422
+ - Si ya hay plan.json: NO generes otro spec la tarea ya está definida.
423
+ 3. NO preguntes sobre información que ya está en los archivos raw o en TAREA EXISTENTE.
424
+ 4. Solo hacé preguntas sobre información que GENUINAMENTE falta y que no podés inferir del contexto.
425
+ 5. Si los archivos ya tienen suficiente información para entender el objetivo, NO hagas preguntas — usá el spec existente.
426
+ 6. Cuando tengas todo claro (o si ya hay spec), generá el spec.md SOLO si NO existe uno previo:
423
427
 
424
428
  === SPEC.MD ===
425
429
  # Feature: ${activeFeatureId}
@@ -440,7 +444,7 @@ REGLAS CRÍTICAS:
440
444
  [consideraciones de implementación]
441
445
  === END SPEC.MD ===
442
446
 
443
- 6. Cuando el spec esté aprobado, escribí EXACTAMENTE al final: ${READY_SENTINEL}` : `
447
+ 7. Cuando el spec esté aprobado (o si ya existe), escribí EXACTAMENTE al final: ${READY_SENTINEL}` : `
444
448
  MODO TAREA LIBRE — No se especificó feature todavía.
445
449
  ${featureListBlock}
446
450
  REGLAS:
@@ -463,8 +467,10 @@ ${conversationHistory}
463
467
 
464
468
  INSTRUCCIONES GENERALES:
465
469
  - Hablá en forma NATURAL, como un compañero de equipo experimentado.
466
- - ANTES DE RESPONDER: leé todo el CONTEXTO DEL PROYECTO y los archivos raw de la feature. Si algo ya está documentado ahí, NO lo preguntes.
467
- - NO preguntés cosas que ya están respondidas en los archivos raw o en la conversación.
470
+ - ANTES DE RESPONDER: leé todo el CONTEXTO DEL PROYECTO, incluyendo "TAREA EXISTENTE" si está presente.
471
+ - Si hay una TAREA EXISTENTE con RESULTADO PREVIO: FAIL, informá al usuario qué falló y preguntá si quiere corregir eso específico.
472
+ - Si ya hay SPEC.MD o plan.json para la tarea, NO los regeneres — usá los existentes.
473
+ - NO preguntés cosas que ya están respondidas en los archivos raw, TAREA EXISTENTE o la conversación.
468
474
  - Hacé como máximo UNA pregunta por turno.
469
475
  - NO uses JSON, hablá normalmente.
470
476
  - Sé directo y eficiente — respetá el tiempo del programador.${specInstructions}`;
@@ -981,6 +987,41 @@ REGLA: Al terminar, reporta todo lo que encontraste de forma clara y estructurad
981
987
  ctx += `--- END FEATURE ---\n`;
982
988
  }
983
989
  }
990
+ // VERIFICAR SI EXISTE TAREA PARA ESTA FEATURE — incluir estado y resultado previo
991
+ const taskDir = path.join(this.projectDir, '.agent', 'tasks', featureId);
992
+ if (await fileExists(taskDir)) {
993
+ ctx += `\n\n--- TAREA EXISTENTE: ${featureId} ---\n`;
994
+ // Leer plan.json si existe
995
+ const planPath = path.join(taskDir, 'plan.json');
996
+ if (await fileExists(planPath)) {
997
+ const plan = await readJson(planPath);
998
+ ctx += `\nPLAN EXISTENTE:\n- Descripción: ${plan.description || 'N/A'}\n- Steps: ${plan.steps?.length || 0}\n`;
999
+ }
1000
+ // Leer progress.json si existe
1001
+ const progressPath = path.join(taskDir, 'progress.json');
1002
+ if (await fileExists(progressPath)) {
1003
+ const progress = await readJson(progressPath);
1004
+ ctx += `- Estado: ${progress.status || 'unknown'}\n`;
1005
+ }
1006
+ // Leer result.md si existe — ESTO ES CRÍTICO PARA RE-INTENTOS
1007
+ const resultPath = path.join(taskDir, 'result.md');
1008
+ if (await fileExists(resultPath)) {
1009
+ const result = await readFile(resultPath);
1010
+ const verdict = result.includes('PASS') || result.includes('✅') ? 'PASS' : 'FAIL';
1011
+ ctx += `- RESULTADO PREVIO: ${verdict}\n`;
1012
+ if (verdict === 'FAIL') {
1013
+ ctx += `\n⚠️ ESTA TAREA YA FALLÓ ANTES. Razones del FAIL:\n${result.slice(0, 1500)}\n`;
1014
+ ctx += `\nIMPORTANTE: Si el usuario pide re-implementar, debés corregir ESPECÍFICAMENTE los puntos marcados como FAIL.\n`;
1015
+ }
1016
+ }
1017
+ // Leer spec.md si existe
1018
+ const specPath = path.join(this.projectDir, '.agent', 'docs', featureId, 'spec.md');
1019
+ if (await fileExists(specPath)) {
1020
+ const spec = await readFile(specPath);
1021
+ ctx += `\n--- SPEC.MD EXISTENTE (usar como referencia, NO regenerar) ---\n${spec.slice(0, 2000)}\n`;
1022
+ }
1023
+ ctx += `--- END TAREA ---\n`;
1024
+ }
984
1025
  }
985
1026
  return ctx;
986
1027
  }
@@ -1085,6 +1126,41 @@ INSTRUCCIONES:
1085
1126
  async runImplementor(taskId, plan) {
1086
1127
  const taskDir = path.join(this.projectDir, '.agent', 'tasks', taskId);
1087
1128
  log.phase(2, 'Implementacion', this.config.roles.implementor.cli, this.config.roles.implementor.model);
1129
+ // VERIFICAR SI YA EXISTE UN RESULT.MD PREVIO (para detectar re-intentos)
1130
+ const resultPath = path.join(taskDir, 'result.md');
1131
+ if (await fileExists(resultPath)) {
1132
+ const prevResult = await readFile(resultPath);
1133
+ const isFail = prevResult.toUpperCase().includes('FAIL') || prevResult.includes('❌');
1134
+ if (isFail) {
1135
+ log.warn('⚠️ Esta tarea YA fue implementada antes y el REVIEWER marcó FAIL');
1136
+ console.log('');
1137
+ console.log(chalk.yellow(' Resultado previo:'));
1138
+ console.log(chalk.dim(' ' + prevResult.split('\n').slice(0, 15).join('\n ')));
1139
+ if (prevResult.split('\n').length > 15) {
1140
+ console.log(chalk.dim(' ... (ver result.md completo para más detalles)'));
1141
+ }
1142
+ console.log('');
1143
+ // Preguntar al usuario qué hacer
1144
+ const action = await ask(' La tarea falló antes. ¿Qué querés hacer?\n (r=reintentar arreglando el error / v=ver result.md completo / c=cancelar): ', this.rl, this.fi);
1145
+ if (action.toLowerCase() === 'v') {
1146
+ console.log('');
1147
+ console.log(chalk.cyan(' === result.md completo ==='));
1148
+ console.log(chalk.white(prevResult));
1149
+ console.log(chalk.cyan(' =========================='));
1150
+ console.log('');
1151
+ const retry = await ask(' ¿Reintentar igual? (y/n): ', this.rl, this.fi);
1152
+ if (retry.toLowerCase() !== 'y') {
1153
+ log.info('Implementación cancelada por el usuario.');
1154
+ throw new Error('USER_CANCELLED_AFTER_FAIL');
1155
+ }
1156
+ }
1157
+ else if (action.toLowerCase() === 'c' || action.toLowerCase() === 'n') {
1158
+ log.info('Implementación cancelada por el usuario.');
1159
+ throw new Error('USER_CANCELLED_AFTER_FAIL');
1160
+ }
1161
+ // Si es 'r', continúa con la implementación
1162
+ }
1163
+ }
1088
1164
  const structurePath = path.join(this.projectDir, '.agent', 'rules', 'structure.md');
1089
1165
  let structureRules = '';
1090
1166
  if (await fileExists(structurePath)) {
@@ -1099,6 +1175,14 @@ INSTRUCCIONES:
1099
1175
  }
1100
1176
  const allTargetFiles = [...new Set(plan.steps.flatMap((s) => s.files || []))];
1101
1177
  const stepsText = plan.steps.map((s) => `Step ${s.num}: ${s.description}${s.files?.length ? `\n Archivos: ${s.files.join(', ')}` : ''}`).join('\n');
1178
+ // Si existe result.md previo con FAIL, incluirlo en el prompt para que el implementor sepa qué corregir
1179
+ let failContext = '';
1180
+ if (await fileExists(resultPath)) {
1181
+ const prevResult = await readFile(resultPath);
1182
+ if (prevResult.toUpperCase().includes('FAIL') || prevResult.includes('❌')) {
1183
+ failContext = `\n\n⚠️ INTENTO PREVIO FALLIDO — El reviewer marcó estos errores:\n=== RESULT.MD PREVIO ===\n${prevResult}\n======================\n\nIMPORTANTE: Debés corregir ESPECÍFICAMENTE los puntos marcados como FAIL en el result.md previo. No vuelvas a implementar lo mismo sin corregir los errores señalados.\n`;
1184
+ }
1185
+ }
1102
1186
  // The engine writes files itself — ask the LLM to generate content in parseable blocks.
1103
1187
  // This avoids depending on CLI tool-use capabilities which are unavailable in API mode.
1104
1188
  const prompt = `TAREA: ${plan.description}
@@ -1111,7 +1195,7 @@ ${allTargetFiles.length ? `ARCHIVOS A CREAR/MODIFICAR:\n${allTargetFiles.map(f =
1111
1195
 
1112
1196
  ${context ? `CONTEXTO DEL PROYECTO:\n${context.slice(0, 2000)}\n` : ''}
1113
1197
  ${archContext ? `ARQUITECTURA EXISTENTE:\n${archContext}\n` : ''}
1114
- ${structureRules ? `REGLAS DE ESTRUCTURA:\n${structureRules}\n` : ''}
1198
+ ${structureRules ? `REGLAS DE ESTRUCTURA:\n${structureRules}\n` : ''}${failContext}
1115
1199
 
1116
1200
  INSTRUCCIONES CRITICAS:
1117
1201
  1. Para CADA archivo que debes crear/modificar, usa este formato EXACTO:
@@ -1124,7 +1208,8 @@ contenido completo del archivo aqui
1124
1208
  3. Genera TODOS los archivos necesarios — uno por bloque FILE.
1125
1209
  4. Incluye el contenido completo de cada archivo (no fragmentos).
1126
1210
  5. Si un step modifica un archivo existente, incluye el archivo completo con los cambios.
1127
- 6. NO incluyas explicaciones fuera de los bloques FILE.`;
1211
+ 6. NO incluyas explicaciones fuera de los bloques FILE.
1212
+ 7. Si hay un INTENTO PREVIO FALLIDO, leé atentamente los errores del reviewer y CORREGÍ ESPECÍFICAMENTE esos puntos.`;
1128
1213
  const res = await this.runWithFallback('implementor', prompt, 'Implementacion');
1129
1214
  const text = extractCliText(res);
1130
1215
  // Parse === FILE: path === ... === END FILE === blocks written by the LLM
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-mp",
3
- "version": "0.5.27",
3
+ "version": "0.5.29",
4
4
  "description": "Deterministic multi-agent CLI orchestrator — plan, code, review",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",