claudeboard 3.1.0 → 3.1.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.
- package/package.json +4 -1
- package/src/orchestrator.js +142 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudeboard",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Visual orchestrator for Claude Code agent teams",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claudeboard": "bin/cli.js"
|
|
@@ -32,5 +32,8 @@
|
|
|
32
32
|
"express": "^4.18.2",
|
|
33
33
|
"open": "^10.1.0",
|
|
34
34
|
"ws": "^8.16.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"supabase": "^2.78.1"
|
|
35
38
|
}
|
|
36
39
|
}
|
package/src/orchestrator.js
CHANGED
|
@@ -755,10 +755,149 @@ function runQA() {
|
|
|
755
755
|
spawnQAAgent(getTasks());
|
|
756
756
|
}
|
|
757
757
|
|
|
758
|
-
// Upload PRD
|
|
758
|
+
// Upload PRD: uses a dedicated planner agent (bypasses the 10k conversational limit)
|
|
759
759
|
function uploadPRD(content) {
|
|
760
|
-
|
|
761
|
-
|
|
760
|
+
spawnPRDPlannerAgent(content);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// Dedicated PRD planner agent — decomposes a full PRD into granular tasks
|
|
764
|
+
function spawnPRDPlannerAgent(rawContent) {
|
|
765
|
+
// Save the full PRD to disk first
|
|
766
|
+
try { savePRD(rawContent); } catch { /* non-fatal */ }
|
|
767
|
+
if (broadcast) broadcast({ type: 'prd:generated' });
|
|
768
|
+
if (broadcast) broadcast({ type: 'orchestrator:thinking' });
|
|
769
|
+
|
|
770
|
+
const projectPath = getProjectPath();
|
|
771
|
+
let plannerBuffer = '';
|
|
772
|
+
let tasksParsed = false;
|
|
773
|
+
|
|
774
|
+
// Collect project context to help Claude understand the tech stack
|
|
775
|
+
let projectCtx = '';
|
|
776
|
+
try {
|
|
777
|
+
const ctx = scanProject(projectPath);
|
|
778
|
+
if (ctx) {
|
|
779
|
+
const lines = [];
|
|
780
|
+
if (ctx.techStack.length) lines.push(`Stack detectado: ${ctx.techStack.join(', ')}`);
|
|
781
|
+
if (ctx.pkgDescription) lines.push(`Descripción: ${ctx.pkgDescription}`);
|
|
782
|
+
if (ctx.fileTree) lines.push(`Árbol de archivos:\n${ctx.fileTree.slice(0, 1500)}`);
|
|
783
|
+
if (ctx.existingPrd) lines.push(`PRD anterior:\n${ctx.existingPrd.slice(0, 500)}`);
|
|
784
|
+
projectCtx = lines.length ? `\n\nContexto del proyecto:\n${lines.join('\n')}` : '';
|
|
785
|
+
}
|
|
786
|
+
} catch { /* ignore */ }
|
|
787
|
+
|
|
788
|
+
// Cap PRD at 180 KB — well above any realistic PRD
|
|
789
|
+
const prdContent = rawContent.slice(0, 180 * 1024);
|
|
790
|
+
|
|
791
|
+
const prompt = `Sos el arquitecto de software de ClaudeBoard. Tu único trabajo es leer el PRD completo y descomponerlo en TODAS las tareas atómicas necesarias para construir el proyecto de cero a producción.${projectCtx}
|
|
792
|
+
|
|
793
|
+
━━━ REGLAS DE GRANULARIDAD ━━━
|
|
794
|
+
• Cada tarea = 1 unidad de trabajo concreto que un agente puede completar solo (1 endpoint, 1 tabla, 1 componente, 1 página, 1 integración, etc.)
|
|
795
|
+
• Tamaño justo: ni mega-tareas ("hacer todo el backend") ni micro-tareas triviales de 2 líneas
|
|
796
|
+
• Para un proyecto mediano esperás 30–60 tareas. Para uno grande, 60–150 tareas. No te limites.
|
|
797
|
+
• Cada tarea debe poder ejecutarse de forma independiente con el contexto del handoff del agente anterior
|
|
798
|
+
|
|
799
|
+
━━━ ORDEN DE CONSTRUCCIÓN (seguir esta secuencia) ━━━
|
|
800
|
+
1. Setup del proyecto (estructura, configs, variables de entorno, dependencias)
|
|
801
|
+
2. Base de datos (cada tabla/schema/migración es una tarea separada)
|
|
802
|
+
3. Autenticación y permisos
|
|
803
|
+
4. Backend — APIs y lógica de negocio (un endpoint o módulo por tarea)
|
|
804
|
+
5. Integraciones externas (pagos, emails, storage, webhooks, etc.)
|
|
805
|
+
6. Frontend — layout, componentes base y sistema de diseño
|
|
806
|
+
7. Frontend — páginas y features (una por tarea)
|
|
807
|
+
8. Lógica de tiempo real / subscripciones si aplica
|
|
808
|
+
9. Testing y validación
|
|
809
|
+
10. Deploy, CI/CD y variables de producción
|
|
810
|
+
|
|
811
|
+
━━━ FORMATO EXACTO (sin texto antes ni después del bloque) ━━━
|
|
812
|
+
<TASKS>
|
|
813
|
+
<TASK>
|
|
814
|
+
title: [verbo + módulo concreto — ej: "Crear tabla profiles con RLS en Supabase"]
|
|
815
|
+
description: [qué crear o modificar exactamente, qué archivos tocar, qué debe funcionar al terminar — todo en una sola línea]
|
|
816
|
+
successCriteria: [cómo verificar que está hecho — en una sola línea]
|
|
817
|
+
priority: high|medium|low
|
|
818
|
+
</TASK>
|
|
819
|
+
</TASKS>
|
|
820
|
+
|
|
821
|
+
━━━ PRD COMPLETO A PLANIFICAR ━━━
|
|
822
|
+
${prdContent}`;
|
|
823
|
+
|
|
824
|
+
const proc = spawnClaude(prompt, projectPath);
|
|
825
|
+
|
|
826
|
+
proc.stdout.on('data', (data) => {
|
|
827
|
+
const chunk = data.toString('utf-8');
|
|
828
|
+
plannerBuffer += chunk;
|
|
829
|
+
// Stream progress to chat so the user sees something happening
|
|
830
|
+
if (broadcast) broadcast({ type: 'orchestrator:chunk', chunk });
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
proc.stderr.on('data', () => { /* swallow */ });
|
|
834
|
+
|
|
835
|
+
proc.on('close', () => {
|
|
836
|
+
if (!tasksParsed) {
|
|
837
|
+
tasksParsed = true;
|
|
838
|
+
const created = parsePlannerTasks(plannerBuffer);
|
|
839
|
+
if (broadcast) broadcast({ type: 'orchestrator:done' });
|
|
840
|
+
if (created.length > 0) {
|
|
841
|
+
if (broadcast) broadcast({
|
|
842
|
+
type: 'orchestrator:chunk',
|
|
843
|
+
chunk: `\n\n✅ **PRD procesado:** ${created.length} tareas creadas en el board. Los agentes arrancan ahora.`,
|
|
844
|
+
});
|
|
845
|
+
} else {
|
|
846
|
+
if (broadcast) broadcast({
|
|
847
|
+
type: 'orchestrator:chunk',
|
|
848
|
+
chunk: '\n\n⚠️ No se pudieron extraer tareas del PRD. Intentá pegarlo en el chat directamente.',
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
proc.on('error', (err) => {
|
|
855
|
+
console.error('[prd-planner] spawn error:', err.message);
|
|
856
|
+
if (broadcast) broadcast({ type: 'orchestrator:error', message: 'Error al procesar el PRD. ¿Está el CLI de Claude instalado?' });
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// Parse tasks from planner output and enqueue them
|
|
861
|
+
function parsePlannerTasks(buffer) {
|
|
862
|
+
let taskDefs = [];
|
|
863
|
+
|
|
864
|
+
const taskBlocks = [...buffer.matchAll(/<TASK>([\s\S]*?)<\/TASK>/g)];
|
|
865
|
+
if (taskBlocks.length > 0) {
|
|
866
|
+
taskDefs = taskBlocks.map(m => {
|
|
867
|
+
const block = m[1];
|
|
868
|
+
const get = (key) => {
|
|
869
|
+
const match = block.match(new RegExp(`^${key}:\\s*(.+)$`, 'mi'));
|
|
870
|
+
return match ? match[1].trim() : '';
|
|
871
|
+
};
|
|
872
|
+
return {
|
|
873
|
+
title: get('title'),
|
|
874
|
+
description: get('description'),
|
|
875
|
+
successCriteria: get('successCriteria'),
|
|
876
|
+
priority: get('priority') || 'medium',
|
|
877
|
+
};
|
|
878
|
+
}).filter(t => t.title);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if (taskDefs.length === 0) return [];
|
|
882
|
+
|
|
883
|
+
const created = taskDefs.map(t => createTask(t));
|
|
884
|
+
if (broadcast) broadcast({ type: 'tasks:created', tasks: created });
|
|
885
|
+
notify('tasks:created', { taskTitle: null, status: 'created' });
|
|
886
|
+
qaAgentRan = false;
|
|
887
|
+
|
|
888
|
+
// Check if any task requires Supabase credentials
|
|
889
|
+
const needsSupabase = taskDefs.some(isSupabaseTask);
|
|
890
|
+
if (needsSupabase && !awaitingSupabaseCreds) {
|
|
891
|
+
awaitingSupabaseCreds = true;
|
|
892
|
+
if (broadcast) broadcast({
|
|
893
|
+
type: 'supabase:preflight',
|
|
894
|
+
taskTitles: created.map(t => t.title),
|
|
895
|
+
});
|
|
896
|
+
} else {
|
|
897
|
+
processQueue();
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
return created;
|
|
762
901
|
}
|
|
763
902
|
|
|
764
903
|
// Called when the user submits Supabase credentials from the modal
|