openprompt-lang 1.3.0 → 1.4.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/bin/cli.js +2 -0
- package/docs/00-ARCHITECTURE/OPL-BOOST-MULTI-AGENT.md +406 -0
- package/docs/02-STANDARDS/AGENTS.template.md +89 -0
- package/docs/02-STANDARDS/ticket-driven-development.md +99 -0
- package/docs/04-TICKETS/BOOST-001-profile-registry.md +66 -0
- package/docs/04-TICKETS/BOOST-002-context-compression.md +58 -0
- package/docs/04-TICKETS/BOOST-003-template-hydration.md +69 -0
- package/docs/04-TICKETS/BOOST-004-fewshot-engine.md +58 -0
- package/docs/04-TICKETS/BOOST-005-agent-pool.md +69 -0
- package/docs/04-TICKETS/BOOST-006-specialized-agents.md +53 -0
- package/docs/04-TICKETS/BOOST-007-validation-loop.md +56 -0
- package/docs/04-TICKETS/BOOST-008-orchestrator.md +71 -0
- package/docs/04-TICKETS/BOOST-009-cache-system.md +56 -0
- package/docs/04-TICKETS/BOOST-010-cli-mcp.md +67 -0
- package/docs/04-TICKETS/BOOST-011-self-learning.md +50 -0
- package/docs/04-TICKETS/BOOST-012-prompt-preamble.md +109 -0
- package/docs/04-TICKETS/BOOST-013-hydrator-duplicate-code.md +132 -0
- package/docs/04-TICKETS/BOOST-014-multiagent-missing-parts.md +87 -0
- package/docs/04-TICKETS/BOOST-015-skeleton-type-missing.md +76 -0
- package/docs/04-TICKETS/BOOST-016-output-path-duplicate.md +68 -0
- package/docs/04-TICKETS/INDEX.md +89 -0
- package/docs/04-TICKETS/_archive/BOOST-005-micro-tasking.md +67 -0
- package/docs/04-TICKETS/_archive/BOOST-006-validation-loop.md +66 -0
- package/docs/04-TICKETS/_archive/BOOST-007-progressive-pipeline.md +69 -0
- package/docs/04-TICKETS/_archive/BOOST-008-cli-mcp-integration.md +74 -0
- package/docs/AI_CONTEXT.md +16 -0
- package/package.json +3 -2
- package/src/boost/agent-pool.js +442 -0
- package/src/boost/agents/index.js +79 -0
- package/src/boost/cache.js +241 -0
- package/src/boost/context-compressor.js +354 -0
- package/src/boost/fewshot-retriever.js +332 -0
- package/src/boost/hardware-detector.js +486 -0
- package/src/boost/hydrator.js +398 -0
- package/src/boost/index.js +60 -0
- package/src/boost/orchestrator.js +615 -0
- package/src/boost/preamble.js +217 -0
- package/src/boost/profile-registry.js +264 -0
- package/src/boost/self-learn.js +247 -0
- package/src/boost/skeletons/component.skeleton.js +24 -0
- package/src/boost/skeletons/hook.skeleton.js +27 -0
- package/src/boost/skeletons/index.js +67 -0
- package/src/boost/skeletons/page.skeleton.js +22 -0
- package/src/boost/skeletons/service.skeleton.js +20 -0
- package/src/boost/skeletons/store.skeleton.js +18 -0
- package/src/boost/skeletons/type.skeleton.js +11 -0
- package/src/boost/task-dispatcher.js +142 -0
- package/src/boost/validation-loop.js +495 -0
- package/src/cli/commands-boost.js +394 -0
- package/src/mcp-refactor/handlers/boost.js +295 -0
- package/src/mcp-refactor/router.js +19 -0
- package/src/mcp-refactor/tools.js +113 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# BOOST-012 — Universal Workflow Preamble (System Prompt Injection)
|
|
2
|
+
|
|
3
|
+
> **Nota:** Este ticket surge de una idea durante la sesión de implementación de Boost.
|
|
4
|
+
> La idea es independiente del módulo Boost pero se integra naturalmente con él.
|
|
5
|
+
|
|
6
|
+
## Metadatos
|
|
7
|
+
|
|
8
|
+
| Campo | Valor |
|
|
9
|
+
|-------|-------|
|
|
10
|
+
| **ID** | BOOST-012 |
|
|
11
|
+
| **Título** | Universal Workflow Preamble — System Prompt Injector |
|
|
12
|
+
| **Épica** | OPL Workflow Enforcement |
|
|
13
|
+
| **Prioridad** | Media |
|
|
14
|
+
| **Estado** | ✅ Completado |
|
|
15
|
+
| **Depende de** | — |
|
|
16
|
+
| **Archivos** | `src/workflow/preamble.js`, `prompt-lang.json`, `AGENTS.md` |
|
|
17
|
+
|
|
18
|
+
## Descripción
|
|
19
|
+
|
|
20
|
+
Crear un mecanismo que inyecte un **mensaje de sistema** al inicio de cada interacción con la IA, forzando que siga el workflow OPL sin depender de MCP tools.
|
|
21
|
+
|
|
22
|
+
El problema: actualmente el enforcement MCP solo funciona cuando la IA se conecta mediante el servidor MCP (OpenCode, Cursor). Si alguien usa la IA desde otro cliente (o si MCP no está disponible), no hay garantía de que siga el workflow.
|
|
23
|
+
|
|
24
|
+
La solución: un **preamble universal** que se antepone a cada solicitud del usuario, instruyendo a la IA sobre el workflow obligatorio.
|
|
25
|
+
|
|
26
|
+
## Idea Central
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
[Solicitud del usuario]
|
|
30
|
+
↓
|
|
31
|
+
[OPL Preamble Injector] ← se antepone automáticamente
|
|
32
|
+
├── "Debes seguir este workflow obligatorio antes de responder..."
|
|
33
|
+
├── "1. workflow_select → 2. ticket_create → 3. check_gates → ..."
|
|
34
|
+
├── "Reglas: no implementar sin ticket, no cerrar sin docs..."
|
|
35
|
+
└── [Solicitud original del usuario]
|
|
36
|
+
↓
|
|
37
|
+
[IA recibe el mensaje completo]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Criterios de Aceptación
|
|
41
|
+
|
|
42
|
+
### CA-1: Preamble configurable
|
|
43
|
+
- [ ] Archivo `src/workflow/preamble.js` con el mensaje de sistema
|
|
44
|
+
- [ ] El preamble se puede personalizar en `prompt-lang.json` → `preamble.enabled`, `preamble.text`
|
|
45
|
+
- [ ] Por defecto incluye: workflow steps, reglas críticas, prohibiciones
|
|
46
|
+
|
|
47
|
+
### CA-2: Modos de inyección
|
|
48
|
+
- [ ] **Modo automático**: se inyecta en cada solicitud hecha a través de OPL
|
|
49
|
+
- [ ] **Modo archivo**: se escribe en un archivo que el AI client lee (ej. `.opencode/preamble.md`)
|
|
50
|
+
- [ ] **Modo hook**: se integra con el sistema de templates para que todo `ai-gen` lo incluya
|
|
51
|
+
|
|
52
|
+
### CA-3: Contenido del preamble
|
|
53
|
+
- [ ] Flujo obligatorio: workflow select → ticket create → check gates → plan → implement → validate → docs → close
|
|
54
|
+
- [ ] Prohibiciones: no implementar sin ticket, no cerrar sin docs, no mutar sin analyze_blast_radius
|
|
55
|
+
- [ ] Referencia a comandos OPL útiles
|
|
56
|
+
- [ ] Máximo 300 palabras (no satura el contexto)
|
|
57
|
+
- [ ] Debe ser markdown válido
|
|
58
|
+
|
|
59
|
+
### CA-4: Integración con MCP
|
|
60
|
+
- [ ] El preamble se envía como `systemPrompt` en el MCP server
|
|
61
|
+
- [ ] Se incluye en `OPL_analyze_project` como parte del output
|
|
62
|
+
- [ ] Se puede consultar con `OPL_workflow_preamble`
|
|
63
|
+
|
|
64
|
+
### CA-5: Tests
|
|
65
|
+
- [ ] Test que el preamble no excede 300 palabras
|
|
66
|
+
- [ ] Test que las reglas críticas están presentes
|
|
67
|
+
- [ ] Test de inyección en prompt
|
|
68
|
+
|
|
69
|
+
## Archivos a crear/modificar
|
|
70
|
+
|
|
71
|
+
| Archivo | Acción |
|
|
72
|
+
|---------|--------|
|
|
73
|
+
| `src/workflow/preamble.js` | ➕ Crear |
|
|
74
|
+
| `prompt-lang.json` | ✏️ Modificar (sección preamble) |
|
|
75
|
+
| `AGENTS.md` | ✏️ Modificar (referencia al preamble) |
|
|
76
|
+
|
|
77
|
+
## Ejemplo de Preamble (borrador)
|
|
78
|
+
|
|
79
|
+
```markdown
|
|
80
|
+
## ⚠️ OPL Workflow Obligatorio
|
|
81
|
+
|
|
82
|
+
Antes de implementar cualquier cosa, DEBES seguir este orden:
|
|
83
|
+
|
|
84
|
+
1. `opl workflow select <descripción>` — Seleccionar workflow
|
|
85
|
+
2. `opl ticket create` — Crear ticket (sin ticket no hay código)
|
|
86
|
+
3. `opl check gates` — Verificar prerrequisitos
|
|
87
|
+
4. `work_context_plan` — Planificar (features/refactors)
|
|
88
|
+
5. Implementar con anotaciones OPL primero
|
|
89
|
+
6. `npx openprompt-lang validate` — Validar
|
|
90
|
+
7. Actualizar documentación
|
|
91
|
+
8. `work_context_close` — Cerrar sesión
|
|
92
|
+
|
|
93
|
+
### ⛔ Prohibido
|
|
94
|
+
- Implementar sin ticket
|
|
95
|
+
- Cerrar sin documentación
|
|
96
|
+
- Mutar código sin analyze_blast_radius
|
|
97
|
+
- Modificar *.template.* archivos
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Notas técnicas
|
|
101
|
+
|
|
102
|
+
- No debe ser un archivo más que la IA tenga que leer — debe ser INYECTADO activamente
|
|
103
|
+
- Se puede implementar como un wrapper que envuelve la solicitud del usuario
|
|
104
|
+
- Para OpenCode: se puede configurar como `systemPrompt` en `opencode.json`
|
|
105
|
+
- El preamble idealmente se regenera dinámicamente según el estado actual del proyecto (tickets abiertos, perfil activo, etc.)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
*Idea original: durante sesión de implementación de OPL Boost, mayo 2026*
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# BOOST-013 — Hydrator duplica código generado por LLM
|
|
2
|
+
|
|
3
|
+
## Metadatos
|
|
4
|
+
|
|
5
|
+
| Campo | Valor |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| **ID** | BOOST-013 |
|
|
8
|
+
| **Título** | Hydrator duplica código cuando LLM genera output sin @kind |
|
|
9
|
+
| **Épica** | Módulo OPL Boost |
|
|
10
|
+
| **Prioridad** | Alta |
|
|
11
|
+
| **Severidad** | Bug |
|
|
12
|
+
| **Estado** | ✅ Resuelto |
|
|
13
|
+
| **Archivos** | `src/boost/orchestrator.js`, `src/boost/hydrator.js` |
|
|
14
|
+
|
|
15
|
+
## Descripción
|
|
16
|
+
|
|
17
|
+
Cuando el LLM (Ollama) genera código completo que **no contiene** `@kind()`, el hydrator lo envuelve dentro de un skeleton template, resultando en código duplicado. El archivo final contiene:
|
|
18
|
+
|
|
19
|
+
1. El skeleton template con placeholders sin reemplazar
|
|
20
|
+
2. El código crudo del LLM dentro del placeholder `PLACEHOLDER_LOGIC`
|
|
21
|
+
3. Una función `Generated()` que envuelve el código nuevamente
|
|
22
|
+
|
|
23
|
+
### Ejemplo del output duplicado
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// Skeleton template for @kind(hook)
|
|
27
|
+
// Markers: , , , ```typescript
|
|
28
|
+
import { useState } from 'react'; // <-- código del LLM empieza
|
|
29
|
+
|
|
30
|
+
type CartItem = { ... };
|
|
31
|
+
// ... 58 líneas de código funcional ...
|
|
32
|
+
|
|
33
|
+
export default useCart; // <-- código del LLM termina
|
|
34
|
+
```, default // <-- markers del skeleton
|
|
35
|
+
// @use(kind, contract, limit)
|
|
36
|
+
// @kind(hook)
|
|
37
|
+
// @contract(in: unknown -> out: unknown @error: Error)
|
|
38
|
+
|
|
39
|
+
export function Generated() { // <-- wrapper del skeleton
|
|
40
|
+
```typescript // <-- marker literal
|
|
41
|
+
import { useState } from 'react'; // <-- código del LLM DUPLICADO
|
|
42
|
+
// ... mismo código重复 ...
|
|
43
|
+
```
|
|
44
|
+
}
|
|
45
|
+
export default Generated // <-- export del skeleton
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Causa Raíz
|
|
49
|
+
|
|
50
|
+
En `orchestrator.js`, línea 260-292 (`stageHydrate`):
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
function stageHydrate(kind, code, profile) {
|
|
54
|
+
if (/@kind\(/.test(code)) {
|
|
55
|
+
return { ... code, hydrated: false } // ✅ Si ya tiene @kind, pasa directo
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ❌ Si no tiene @kind, intenta hidratar
|
|
59
|
+
const hydrated = hydrate(kind, {
|
|
60
|
+
imports: "",
|
|
61
|
+
types: "",
|
|
62
|
+
logic: code, // <-- Todo el código del LLM va como "logic"
|
|
63
|
+
name: "Generated",
|
|
64
|
+
...
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
El hydrator interpola `logic` dentro del skeleton, pero como el LLM ya generó código completo (imports, types, exports), el resultado es un archivo con el código del LLM **más** el skeleton wrapper.
|
|
70
|
+
|
|
71
|
+
## Solución Propuesta
|
|
72
|
+
|
|
73
|
+
### Opción A: Smart detection (recomendada)
|
|
74
|
+
Detectar si el código del LLM ya es un archivo completo (tiene imports y exports) y en ese caso:
|
|
75
|
+
1. Agregar anotaciones OPL al inicio del archivo
|
|
76
|
+
2. NO envolverlo en skeleton
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
function stageHydrate(kind, code, profile) {
|
|
80
|
+
if (/@kind\(/.test(code)) {
|
|
81
|
+
return { code, hydrated: false }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// NEW: Detectar código completo del LLM
|
|
85
|
+
const hasImports = /^import\s/m.test(code)
|
|
86
|
+
const hasExport = /^export\s/m.test(code)
|
|
87
|
+
|
|
88
|
+
if (hasImports && hasExport) {
|
|
89
|
+
// Código completo del LLM — solo agregar anotaciones
|
|
90
|
+
const annotations = generateOPLAnnotations(kind, code)
|
|
91
|
+
return {
|
|
92
|
+
code: annotations + "\n\n" + code,
|
|
93
|
+
hydrated: false,
|
|
94
|
+
reason: "llm-complete-injection"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Código parcial — hidratar con skeleton
|
|
99
|
+
const hydrated = hydrate(kind, { logic: code, name: "Generated", ... })
|
|
100
|
+
return { code: hydrated.code, hydrated: true }
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Opción B: Mejorar prompt del LLM
|
|
105
|
+
Incluir en el system prompt del agente que la salida DEBE incluir `@kind()` para que el hydrator lo detecte y pase directo.
|
|
106
|
+
|
|
107
|
+
### Opción C (combinada): A + B
|
|
108
|
+
Mejorar el prompt + smart detection como fallback.
|
|
109
|
+
|
|
110
|
+
## Pasos para Reproducir
|
|
111
|
+
|
|
112
|
+
1. Ejecutar: `opl boost generate "hook useCart para carrito de compras" --kind hook`
|
|
113
|
+
2. El LLM genera código completo sin @kind
|
|
114
|
+
3. El hydrator envuelve en skeleton → código duplicado
|
|
115
|
+
|
|
116
|
+
## Impacto
|
|
117
|
+
|
|
118
|
+
- Archivos generados tienen ~2x más líneas de las necesarias
|
|
119
|
+
- Código duplicado dentro de código funcional
|
|
120
|
+
- Markers del skeleton (`\`\`\`typescript`, `default`) aparecen como texto literal
|
|
121
|
+
- La validación pasa (quickValidate es leniente) pero el código no es utilizable directamente
|
|
122
|
+
|
|
123
|
+
## @learn-error
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
// @learn-error id=BOOST-HYDRATE-001
|
|
127
|
+
// input='Hydrator envuelve código completo del LLM en skeleton, creando duplicación'
|
|
128
|
+
// expected='Código completo del LLM se usa directamente con anotaciones OPL inyectadas al inicio'
|
|
129
|
+
// actual='Código del LLM aparece 2 veces: una dentro del skeleton y otra como contenido del placeholder'
|
|
130
|
+
// fix='Implementar smart detection en stageHydrate: si el código tiene imports+exports, inyectar solo anotaciones OPL sin skeleton'
|
|
131
|
+
// category=boost
|
|
132
|
+
```
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# BOOST-014 — Multi-agent mode falla con "Partes requeridas faltantes"
|
|
2
|
+
|
|
3
|
+
## Metadatos
|
|
4
|
+
|
|
5
|
+
| Campo | Valor |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| **ID** | BOOST-014 |
|
|
8
|
+
| **Título** | Multi-agent mode falla al hidratar resultados del DAG |
|
|
9
|
+
| **Épica** | Módulo OPL Boost |
|
|
10
|
+
| **Prioridad** | Media |
|
|
11
|
+
| **Severidad** | Bug |
|
|
12
|
+
| **Estado** | ✅ Resuelto |
|
|
13
|
+
| **Archivos** | `src/boost/orchestrator.js`, `src/boost/hydrator.js` |
|
|
14
|
+
|
|
15
|
+
## Descripción
|
|
16
|
+
|
|
17
|
+
Al ejecutar `opl boost generate` con `--multi-agent`, el pipeline falla con error:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
✘ Error inesperado: Partes requeridas faltantes para "hook": name
|
|
21
|
+
✘ Error inesperado: Partes requeridas faltantes para "store": name
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
El modo multi-agent ejecuta agentes especializados (types, state, logic, cleaner, validate) para cada nodo del DAG, pero los resultados no se mapean correctamente a las partes requeridas por el hydrator.
|
|
25
|
+
|
|
26
|
+
## Causa Raíz
|
|
27
|
+
|
|
28
|
+
En `orchestrator.js`, la función `stageGenerateMultiAgent` (línea 179-243):
|
|
29
|
+
|
|
30
|
+
1. Ejecuta agentes en paralelo para los nodos sin dependencias
|
|
31
|
+
2. Ejecuta agentes en secuencia para los nodos con dependencias
|
|
32
|
+
3. Los resultados se almacenan como `{ types: "código...", state: "código...", logic: "código..." }`
|
|
33
|
+
4. Se pasa a `hydrateFromAgentResults(kind, results)` que mapea `results.types` → `PLACEHOLDER_TYPES`, etc.
|
|
34
|
+
|
|
35
|
+
Pero el hydrator requiere `name` como parte obligatoria para hook, component, service, store — y ningún agente genera explícitamente el `name`.
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
// hydrator.js líneas 36-48
|
|
39
|
+
const PLACEHOLDER_MAP = {
|
|
40
|
+
hook: {
|
|
41
|
+
required: ["name"], // ← Falla aquí
|
|
42
|
+
placeholders: { ... }
|
|
43
|
+
},
|
|
44
|
+
...
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Solución Propuesta
|
|
49
|
+
|
|
50
|
+
### Opción A: Extraer name del prompt de entrada
|
|
51
|
+
Antes de pasar al hydrator, extraer el nombre del identificador de la tarea:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
function extractNameFromTask(task) {
|
|
55
|
+
// "hook useProducts para ..." → "useProducts"
|
|
56
|
+
// "service ProductService para ..." → "ProductService"
|
|
57
|
+
const match = task.match(/\b(use[A-Z]\w+|[A-Z]\w*Service|[A-Z]\w*Store|[A-Z]\w*Page)/)
|
|
58
|
+
return match ? match[1] : "Generated"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Opción B: Agente "name" en el DAG
|
|
63
|
+
Añadir un paso de pre-procesamiento que extraiga el nombre del componente antes de los agentes.
|
|
64
|
+
|
|
65
|
+
### Opción C: Hacer name opcional en hydrator
|
|
66
|
+
Si no se provee `name`, usar "Generated" como default sin error.
|
|
67
|
+
|
|
68
|
+
## Pasos para Reproducir
|
|
69
|
+
|
|
70
|
+
1. Ejecutar: `opl boost generate "hook useAuth para autenticación" --kind hook --multi-agent`
|
|
71
|
+
2. Error: `Partes requeridas faltantes para "hook": name`
|
|
72
|
+
|
|
73
|
+
## Impacto
|
|
74
|
+
|
|
75
|
+
- Modo `--multi-agent` es completamente no funcional
|
|
76
|
+
- No se puede usar el pipeline multi-agente para ningún @kind
|
|
77
|
+
|
|
78
|
+
## @learn-error
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
// @learn-error id=BOOST-MULTIAGENT-001
|
|
82
|
+
// input='Ejecutar boost generate --multi-agent para cualquier @kind'
|
|
83
|
+
// expected='Código generado por múltiples agentes especializados'
|
|
84
|
+
// actual='Error: Partes requeridas faltantes para "kind": name'
|
|
85
|
+
// fix='Extraer name del prompt de entrada antes de hidratar, o hacer name opcional con default "Generated"'
|
|
86
|
+
// category=boost
|
|
87
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# BOOST-015 — Skeleton "type" no soportado
|
|
2
|
+
|
|
3
|
+
## Metadatos
|
|
4
|
+
|
|
5
|
+
| Campo | Valor |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| **ID** | BOOST-015 |
|
|
8
|
+
| **Título** | Skeleton @kind(type) no soportado — solo 5 kinds |
|
|
9
|
+
| **Épica** | Módulo OPL Boost |
|
|
10
|
+
| **Prioridad** | Baja |
|
|
11
|
+
| **Severidad** | Feature |
|
|
12
|
+
| **Estado** | ✅ Resuelto |
|
|
13
|
+
| **Archivos** | `src/boost/skeletons/index.js`, `src/boost/hydrator.js`, `src/boost/task-dispatcher.js` |
|
|
14
|
+
|
|
15
|
+
## Descripción
|
|
16
|
+
|
|
17
|
+
Al ejecutar `opl boost generate "tipos TypeScript para ecommerce..." --kind type`, el sistema responde:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
✘ Error inesperado: Skeleton desconocido: "type". Tipos: hook, component, page, service, store
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Solo existen 5 skeletons: hook, component, page, service, store. Pero OPL define `@kind(type)` como un tipo válido en sus reglas de anotaciones (con `@limit(lines: sin límite)`).
|
|
24
|
+
|
|
25
|
+
## Causa Raíz
|
|
26
|
+
|
|
27
|
+
`skeletons/index.js` solo registra 5 tipos:
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const skeletons = {
|
|
31
|
+
hook: () => import("./hook.skeleton.js").then(m => m.default),
|
|
32
|
+
component: () => import("./component.skeleton.js").then(m => m.default),
|
|
33
|
+
page: () => import("./page.skeleton.js").then(m => m.default),
|
|
34
|
+
service: () => import("./service.skeleton.js").then(m => m.default),
|
|
35
|
+
store: () => import("./store.skeleton.js").then(m => m.default),
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Y `task-dispatcher.js` no tiene `type` en `detectKind()`.
|
|
40
|
+
|
|
41
|
+
## Solución Propuesta
|
|
42
|
+
|
|
43
|
+
### Crear type.skeleton.js
|
|
44
|
+
Skeleton para archivos de tipos TypeScript:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// @use(kind, limit)
|
|
48
|
+
// @kind(type)
|
|
49
|
+
// @limit(lines: 100)
|
|
50
|
+
|
|
51
|
+
{{PLACEHOLDER_IMPORTS}}
|
|
52
|
+
|
|
53
|
+
{{PLACEHOLDER_TYPES}}
|
|
54
|
+
|
|
55
|
+
{{PLACEHOLDER_EXPORTS}}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Agregar a detectKind
|
|
59
|
+
```javascript
|
|
60
|
+
if (/\b(type|interface|types|typings|dtype)\b/.test(lower)) return "type"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Registrar en skeletons/index.js
|
|
64
|
+
```javascript
|
|
65
|
+
type: () => import("./type.skeleton.js").then(m => m.default),
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Pasos para Reproducir
|
|
69
|
+
|
|
70
|
+
1. `opl boost generate "tipos TypeScript para Product, CartItem, ApiResponse" --kind type`
|
|
71
|
+
2. Error: `Skeleton desconocido: "type"`
|
|
72
|
+
|
|
73
|
+
## Impacto
|
|
74
|
+
|
|
75
|
+
- No se pueden generar archivos de tipos con Boost
|
|
76
|
+
- Workaround: generar manualmente o usar `--kind service` como aproximación
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# BOOST-016 — --output con ruta relativa crea estructura duplicada
|
|
2
|
+
|
|
3
|
+
## Metadatos
|
|
4
|
+
|
|
5
|
+
| Campo | Valor |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| **ID** | BOOST-016 |
|
|
8
|
+
| **Título** | Flag --output con ruta relativa crea directorios duplicados |
|
|
9
|
+
| **Épica** | Módulo OPL Boost |
|
|
10
|
+
| **Prioridad** | Baja |
|
|
11
|
+
| **Severidad** | Bug |
|
|
12
|
+
| **Estado** | ✅ Resuelto |
|
|
13
|
+
| **Archivos** | `src/boost/orchestrator.js`, `src/cli/commands-boost.js` |
|
|
14
|
+
|
|
15
|
+
## Descripción
|
|
16
|
+
|
|
17
|
+
Al ejecutar `opl boost generate "descripcion" --output /ruta/absoluta/archivo.ts`, se crea una estructura de directorios duplicada dentro del directorio de trabajo en lugar de usar la ruta directamente.
|
|
18
|
+
|
|
19
|
+
### Ejemplo
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd /home/nodead/Escritorio/TestOPLBoost
|
|
23
|
+
opl boost generate "hook useCart" --output /home/nodead/Escritorio/TestOPLBoost/useCart.ts
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Resultado: el archivo se crea en:
|
|
27
|
+
```
|
|
28
|
+
/home/nodead/Escritorio/TestOPLBoost/home/nodead/Escritorio/TestOPLBoost/useCart.ts
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
En lugar de:
|
|
32
|
+
```
|
|
33
|
+
/home/nodead/Escritorio/TestOPLBoost/useCart.ts
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Causa Raíz
|
|
37
|
+
|
|
38
|
+
En `orchestrator.js`, línea 417:
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
const outputPath = join(process.cwd(), opts.output)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Si `opts.output` ya es una ruta absoluta, `path.join(cwd, '/absolute/path')` en algunos entornos puede comportarse inesperadamente. Además, `path.join` con una ruta absoluta debería mantener la ruta absoluta, pero el comportamiento real muestra que crea una estructura anidada.
|
|
45
|
+
|
|
46
|
+
El problema real es que `join(process.cwd(), '/home/nodead/...')` en Node.js ignora el primer argumento cuando el segundo es absoluto... PERO si hay un pre-procesamiento del path en commands-boost.js, podría estar causando la duplicación.
|
|
47
|
+
|
|
48
|
+
## Solución Propuesta
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
// orchestrator.js línea 417
|
|
52
|
+
const outputPath = path.isAbsolute(opts.output)
|
|
53
|
+
? opts.output
|
|
54
|
+
: join(process.cwd(), opts.output)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Y en `commands-boost.js`, no transformar la ruta de output.
|
|
58
|
+
|
|
59
|
+
## Pasos para Reproducir
|
|
60
|
+
|
|
61
|
+
1. `cd /home/user/project`
|
|
62
|
+
2. `opl boost generate "hook useCart" --output /home/user/project/src/hooks/useCart.ts`
|
|
63
|
+
3. Archivo se crea en `/home/user/project/home/user/project/src/hooks/useCart.ts`
|
|
64
|
+
|
|
65
|
+
## Impacto
|
|
66
|
+
|
|
67
|
+
- Archivos se guardan en ubicaciones incorrectas
|
|
68
|
+
- Workaround: usar rutas relativas (`--output src/hooks/useCart.ts`)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Índice de Tickets — Módulo OPL Boost
|
|
2
|
+
|
|
3
|
+
> **Épica**: Sistema multi-agente para potenciar modelos pequeños de IA
|
|
4
|
+
> **Arquitectura**: MoA (Mixture of Agents) — modelos colaborando como núcleos de CPU
|
|
5
|
+
> **Versión objetivo**: OPL 1.4.0
|
|
6
|
+
> **Documento de diseño**: `docs/00-ARCHITECTURE/OPL-BOOST-MULTI-AGENT.md`
|
|
7
|
+
> **Código fuente**: `src/boost/`
|
|
8
|
+
|
|
9
|
+
## Tickets
|
|
10
|
+
|
|
11
|
+
| ID | Título | Prioridad | Estado | Depende de |
|
|
12
|
+
|----|--------|-----------|--------|------------|
|
|
13
|
+
| [BOOST-001](./BOOST-001-profile-registry.md) | Profile Registry + Config Base | Alta | ✅ Completado | — |
|
|
14
|
+
| [BOOST-002](./BOOST-002-context-compression.md) | Context Compressor + AI Cleaner | Alta | ✅ Completado | BOOST-001 |
|
|
15
|
+
| [BOOST-003](./BOOST-003-template-hydration.md) | Template Hydration System | Alta | ✅ Completado | BOOST-001 |
|
|
16
|
+
| [BOOST-004](./BOOST-004-fewshot-engine.md) | Few-Shot Example Engine | Media | ✅ Completado | BOOST-001 |
|
|
17
|
+
| [BOOST-005](./BOOST-005-agent-pool.md) | Agent Pool + Ollama Connector | Alta | ✅ Completado | BOOST-001 |
|
|
18
|
+
| [BOOST-006](./BOOST-006-specialized-agents.md) | Agentes Especializados | Alta | ✅ Completado | BOOST-005 |
|
|
19
|
+
| [BOOST-007](./BOOST-007-validation-loop.md) | Validation Loop + Agent Validate | Alta | ✅ Completado | BOOST-006 |
|
|
20
|
+
| [BOOST-008](./BOOST-008-orchestrator.md) | Orchestrator (pipeline unificado) | Alta | ✅ Completado | BOOST-007 |
|
|
21
|
+
| [BOOST-009](./BOOST-009-cache-system.md) | Cache System | Media | ✅ Completado | BOOST-008 |
|
|
22
|
+
| [BOOST-010](./BOOST-010-cli-mcp.md) | CLI + MCP Integration | Media | ✅ Completado | BOOST-009 |
|
|
23
|
+
| [BOOST-011](./BOOST-011-self-learning.md) | Auto-aprendizaje entre sesiones | Baja | ✅ Completado | BOOST-010 |
|
|
24
|
+
| [BOOST-012](./BOOST-012-prompt-preamble.md) | Universal Workflow Preamble | Media | ✅ Completado | — |
|
|
25
|
+
| [BOOST-013](./BOOST-013-hydrator-duplicate-code.md) | Hydrator duplica código del LLM | Alta | ✅ Resuelto | BOOST-003 |
|
|
26
|
+
| [BOOST-014](./BOOST-014-multiagent-missing-parts.md) | Multi-agent falla con partes faltantes | Media | ✅ Resuelto | BOOST-008 |
|
|
27
|
+
| [BOOST-015](./BOOST-015-skeleton-type-missing.md) | Skeleton @kind(type) no soportado | Baja | ✅ Resuelto | BOOST-003 |
|
|
28
|
+
| [BOOST-016](./BOOST-016-output-path-duplicate.md) | --output con ruta absoluta duplica directorios | Baja | ✅ Resuelto | BOOST-010 |
|
|
29
|
+
|
|
30
|
+
## Resumen
|
|
31
|
+
|
|
32
|
+
| Estado | Cantidad |
|
|
33
|
+
|--------|----------|
|
|
34
|
+
| ✅ Completado | 12 |
|
|
35
|
+
| ✅ Resuelto | 4 |
|
|
36
|
+
|
|
37
|
+
## Archivos implementados
|
|
38
|
+
|
|
39
|
+
| Archivo | Ticket | Líneas | Descripción |
|
|
40
|
+
|---------|--------|--------|-------------|
|
|
41
|
+
| `src/boost/profile-registry.js` | BOOST-001 | 264 | Perfiles, detección, API |
|
|
42
|
+
| `src/boost/hardware-detector.js` | BOOST-001* | 490 | Detección HW, setup, monitoreo |
|
|
43
|
+
| `src/boost/agent-pool.js` | BOOST-005 | 446 | Pool, Ollama, cola FIFO |
|
|
44
|
+
| `src/boost/agents/index.js` | BOOST-006 | 79 | Registro de 5 agentes |
|
|
45
|
+
| `src/boost/context-compressor.js` | BOOST-002 | 358 | Compresión determinística |
|
|
46
|
+
| `src/boost/hydrator.js` | BOOST-003 | ~300 | Hidratación skeletons + anotaciones |
|
|
47
|
+
| `src/boost/skeletons/*.js` | BOOST-003 | ~110 | 5 skeletons por @kind |
|
|
48
|
+
| `src/boost/fewshot-retriever.js` | BOOST-004 | ~250 | Búsqueda por relevancia |
|
|
49
|
+
| `src/boost/validation-loop.js` | BOOST-007 | ~300 | Feedback loop + validación |
|
|
50
|
+
| `src/boost/task-dispatcher.js` | BOOST-008 | ~135 | DAG planner |
|
|
51
|
+
| `src/boost/orchestrator.js` | BOOST-008 | ~350 | Pipeline single-pass + multi-agent |
|
|
52
|
+
| `src/boost/cache.js` | BOOST-009 | ~245 | Caché en disco con TTL |
|
|
53
|
+
| `src/boost/self-learn.js` | BOOST-011 | ~200 | Métricas y auto-perfilado |
|
|
54
|
+
| `src/boost/preamble.js` | BOOST-012 | ~150 | Preamble de workflow |
|
|
55
|
+
| `src/boost/index.js` | BOOST-008 | ~60 | API pública unificada |
|
|
56
|
+
| `src/cli/commands-boost.js` | BOOST-010 | ~400 | 6 comandos CLI |
|
|
57
|
+
| `src/mcp-refactor/handlers/boost.js` | BOOST-010 | ~250 | 5 tools MCP |
|
|
58
|
+
|
|
59
|
+
**Total: ~3,700 líneas de código implementadas**
|
|
60
|
+
|
|
61
|
+
## Comandos CLI disponibles
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
opl boost check → Diagnóstico del perfil activo + estado del sistema
|
|
65
|
+
opl boost profile [name] → Ver/forzar perfil (small/medium/large/auto)
|
|
66
|
+
opl boost setup → Detectar hardware + configurar Boost
|
|
67
|
+
opl boost generate <desc> → Generar código con pipeline completo
|
|
68
|
+
opl boost microtask <task> → Descomponer tarea en DAG de micro-tareas
|
|
69
|
+
opl boost cache [action] → Gestionar caché (stats, clear, clean)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Tools MCP disponibles
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
OPL_Boost_generate → Genera código usando el pipeline completo
|
|
76
|
+
OPL_Boost_compress → Comprime contexto según perfil y tarea
|
|
77
|
+
OPL_Boost_profile → Muestra perfil Boost + estado del sistema
|
|
78
|
+
OPL_Boost_plan → Planifica DAG de micro-tareas
|
|
79
|
+
OPL_Boost_validate → Valida código generado con feedback
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Notas
|
|
83
|
+
|
|
84
|
+
- Todos los tickets completados ✅
|
|
85
|
+
- La arquitectura es MoA (Mixture of Agents) — ver `docs/00-ARCHITECTURE/OPL-BOOST-MULTI-AGENT.md`
|
|
86
|
+
- El pipeline funciona en dos modos: single-pass (default) y multi-agent (opt-in con `--multi-agent`)
|
|
87
|
+
- BOOST-012 (preamble) es un sistema independiente que se puede usar sin el resto de Boost
|
|
88
|
+
- Tickets antiguos (micro-tasking lineal) archivados en `_archive/`
|
|
89
|
+
- **v1.3.0**: Testing con Ollama reveló 4 bugs (BOOST-013 a BOOST-016) — hydrator duplica código, multi-agent falla, skeleton type falta, output path duplica
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# BOOST-005 — Micro-Tasking Engine
|
|
2
|
+
|
|
3
|
+
## Metadatos
|
|
4
|
+
|
|
5
|
+
| Campo | Valor |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| **ID** | BOOST-005 |
|
|
8
|
+
| **Título** | Micro-Tasking Engine |
|
|
9
|
+
| **Épica** | Módulo OPL Boost |
|
|
10
|
+
| **Prioridad** | Alta |
|
|
11
|
+
| **Estado** | 🔴 Pendiente |
|
|
12
|
+
| **Depende de** | BOOST-003, BOOST-004 |
|
|
13
|
+
| **Archivos** | `src/boost/micro-tasker.js` |
|
|
14
|
+
|
|
15
|
+
## Descripción
|
|
16
|
+
|
|
17
|
+
Motor que descompone tareas complejas de generación de código en micro-tareas secuenciales. Cada micro-tarea es una instrucción simple que un modelo pequeño puede seguir sin saturarse. El orquestador ejecuta las micro-tareas en cadena y el ensamblador une los resultados parciales en el archivo final.
|
|
18
|
+
|
|
19
|
+
## Criterios de Aceptación
|
|
20
|
+
|
|
21
|
+
### CA-1: Planificador de micro-tareas
|
|
22
|
+
- [ ] `plan(task, kind)` → devuelve array de micro-tareas con: id, instrucción, formato esperado, validator
|
|
23
|
+
- [ ] Para un hook: ["Define tipos/interface", "Define estado y efectos", "Implementa lógica", "Exporta"]
|
|
24
|
+
- [ ] Para un componente: ["Define props", "Define variantes cva", "Implementa JSX", "Exporta"]
|
|
25
|
+
- [ ] Para un page: ["Define imports y tipos", "Implementa layout", "Conecta datos", "Exporta"]
|
|
26
|
+
|
|
27
|
+
### CA-2: Orquestador secuencial
|
|
28
|
+
- [ ] `execute(task, kind, profile)` → ejecuta micro-tareas una por una
|
|
29
|
+
- [ ] Cada micro-tarea se ejecuta con contexto mínimo (solo instrucción actual + resultado anterior)
|
|
30
|
+
- [ ] Hay un shared state entre micro-tareas para mantener coherencia
|
|
31
|
+
- [ ] Si una micro-tarea falla, el orquestador puede reintentarla (según perfil)
|
|
32
|
+
|
|
33
|
+
### CA-3: Ensamblador
|
|
34
|
+
- [ ] `assemble(partialResults, kind)` → combina resultados parciales en archivo final
|
|
35
|
+
- [ ] Usa el hydrator (BOOST-003) para generar el código final con anotaciones
|
|
36
|
+
- [ ] Si hay conflictos entre resultados parciales, resuelve con heurísticas (último valor gana)
|
|
37
|
+
|
|
38
|
+
### CA-4: CLI microtask
|
|
39
|
+
- [ ] `opl boost microtask "crea hook useAuth"` → muestra el plan de micro-tareas sin ejecutar
|
|
40
|
+
- [ ] `opl boost microtask "crea hook useAuth" --execute` → ejecuta el plan
|
|
41
|
+
- [ ] Opción `--verbose` muestra cada paso y su resultado
|
|
42
|
+
- [ ] Opción `--plan-only` solo muestra el plan (alias de sin flag)
|
|
43
|
+
|
|
44
|
+
### CA-5: Integración con generate
|
|
45
|
+
- [ ] Cuando `opl boost generate` se ejecuta con perfil small, usa micro-tasking automáticamente
|
|
46
|
+
- [ ] Cuando el perfil es medium, decide según complejidad de la tarea
|
|
47
|
+
- [ ] Cuando el perfil es large, no usa micro-tasking
|
|
48
|
+
|
|
49
|
+
### CA-6: Tests
|
|
50
|
+
- [ ] Test de planificación para cada @kind que soporta
|
|
51
|
+
- [ ] Test de orquestación con respuestas mock
|
|
52
|
+
- [ ] Test de ensamblado con resultados parciales
|
|
53
|
+
- [ ] Test de fallo de micro-tarea y reintento
|
|
54
|
+
|
|
55
|
+
## Archivos a crear/modificar
|
|
56
|
+
|
|
57
|
+
| Archivo | Acción |
|
|
58
|
+
|---------|--------|
|
|
59
|
+
| `src/boost/micro-tasker.js` | ➕ Crear |
|
|
60
|
+
|
|
61
|
+
## Notas técnicas
|
|
62
|
+
|
|
63
|
+
- El orquestador es el componente más complejo del módulo Boost
|
|
64
|
+
- El shared state es un simple objeto JSON que se pasa entre micro-tareas
|
|
65
|
+
- Cada micro-tarea tiene un `validator` opcional que verifica el output antes de pasar a la siguiente
|
|
66
|
+
- Los validators pueden ser: validate OPL, typecheck básico, o función custom
|
|
67
|
+
- El orquestador debe ser extensible para soportar nuevos tipos de micro-tareas
|