Skip to content

Commit 8016d35

Browse files
committed
fix: registrar agentes de nucleo, corregir herramientas MCP y pipeline del dashboard
- Registrar los 7 agentes de nucleo en plugin.json (antes solo opcionales) - Corregir 5 nombres de herramientas MCP fantasma en librarian.md - Auto-crear config con memoria activada en session-start.sh - Crear iteracion de sesion automatica para asociar commits - Fallback a datos globales en get_full_state() sin iteracion activa - Detectar puertos ocupados y buscar alternativas en el dashboard - Alinear comentarios de cabecera del servidor MCP con nombres reales - Bump version a 0.3.6
1 parent 5f1972a commit 8016d35

File tree

19 files changed

+183
-29
lines changed

19 files changed

+183
-29
lines changed

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
{
1010
"name": "alfred-dev",
1111
"description": "Plugin de ingeniería de software completa: 15 agentes (8 de núcleo + 7 opcionales), 59 skills, memoria persistente, dashboard web en tiempo real, quality gates y compliance europeo integrado.",
12-
"version": "0.3.5",
12+
"version": "0.3.6",
1313
"source": "./",
1414
"author": {
1515
"name": "686f6c61"

.claude-plugin/plugin.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "alfred-dev",
33
"description": "Plugin de ingeniería de software completa: 8 agentes de núcleo y 7 opcionales con personalidad propia, memoria persistente por proyecto, quality gates y flujos automatizados desde la idea hasta producción.",
4-
"version": "0.3.5",
4+
"version": "0.3.6",
55
"author": {
66
"name": "00b"
77
},
@@ -23,6 +23,13 @@
2323
"./commands/update.md"
2424
],
2525
"agents": [
26+
"./agents/product-owner.md",
27+
"./agents/architect.md",
28+
"./agents/senior-dev.md",
29+
"./agents/security-officer.md",
30+
"./agents/qa-engineer.md",
31+
"./agents/devops-engineer.md",
32+
"./agents/tech-writer.md",
2633
"./agents/optional/data-engineer.md",
2734
"./agents/optional/ux-reviewer.md",
2835
"./agents/optional/performance-engineer.md",

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ y el proyecto usa [versionado semántico](https://semver.org/lang/es/).
77

88
---
99

10+
## [0.3.6] - 2026-03-10
11+
12+
### Fixed
13+
14+
- **Agentes de nucleo registrados en plugin.json**: los 7 agentes de nucleo (product-owner, architect, senior-dev, security-officer, qa-engineer, devops-engineer, tech-writer) no estaban registrados en el manifiesto del plugin, por lo que Claude Code no podia cargar sus system prompts como subagentes. Ahora los 14 agentes (7 nucleo + 7 opcionales) estan registrados.
15+
- **Herramientas MCP fantasma en librarian**: el agente librarian referenciaba 5 herramientas MCP con nombres incorrectos (`memory_record_decision`, `memory_record_iteration`, `memory_record_event`, `memory_record_commit`, `memory_link_commit`). Corregidos a los nombres reales del servidor MCP.
16+
- **Dashboard vacio en primera sesion**: el pipeline de datos del dashboard fallaba en cascada por 3 causas: (1) la configuracion local no se creaba con memoria activada, (2) sin iteracion activa los commits no se asociaban, (3) `get_full_state()` devolvia arrays vacios sin iteracion. Corregido con auto-creacion de config, iteracion de sesion automatica y fallback a datos globales.
17+
- **Conflicto de puertos del dashboard**: si otro proyecto ya usaba los puertos 7533/7534, el dashboard no arrancaba. Ahora detecta puertos ocupados y busca alternativas automaticamente.
18+
- **Comentarios de cabecera del servidor MCP**: los nombres de herramientas en el docstring del modulo no coincidian con los registrados. Alineados.
19+
1020
## [0.3.5] - 2026-03-10
1121

1222
### Changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Los agentes con modelo `opus` realizan tareas que requieren razonamiento complej
106106

107107
### Agentes opcionales (7)
108108

109-
Agentes predefinidos que el usuario activa segun las necesidades de su proyecto con `/alfred config`. Se sugieren automaticamente en funcion del stack detectado. Desde v0.3.5, Alfred tambien propone agentes opcionales de forma dinamica al arrancar cada flujo, analizando la descripcion de la tarea con keywords contextuales y combinandolas con las senales del proyecto. La seleccion dinamica es efimera (solo para esa sesion) y no modifica la configuracion persistente. Mas detalles en la [documentacion de configuracion](docs/configuration.md#composicion-dinamica-de-equipo).
109+
Agentes predefinidos que el usuario activa segun las necesidades de su proyecto con `/alfred config`. Se sugieren automaticamente en funcion del stack detectado. Desde v0.3.6, Alfred tambien propone agentes opcionales de forma dinamica al arrancar cada flujo, analizando la descripcion de la tarea con keywords contextuales y combinandolas con las senales del proyecto. La seleccion dinamica es efimera (solo para esa sesion) y no modifica la configuracion persistente. Mas detalles en la [documentacion de configuracion](docs/configuration.md#composicion-dinamica-de-equipo).
110110

111111
| Agente | Rol | Cuando es util |
112112
|--------|-----|----------------|
@@ -242,7 +242,7 @@ Funcionalidades principales:
242242

243243
> **Fase Alpha** -- Funcionalidad en desarrollo activo. La interfaz y el protocolo pueden cambiar entre versiones menores.
244244
245-
A partir de v0.3.0, Alfred Dev incluye un dashboard web que muestra el estado completo del proyecto en tiempo real sin intervenir en el terminal de Claude Code. La v0.3.1 refuerza la estabilidad del servidor (lectura robusta de frames WebSocket, cabeceras de seguridad HTTP, soporte movil) y anade inyeccion dinamica de version y puerto. La v0.3.5 corrige la nomenclatura de comandos en la web y actualiza las estadisticas. Se lanza con `/alfred gui` y se abre automaticamente en el navegador.
245+
A partir de v0.3.0, Alfred Dev incluye un dashboard web que muestra el estado completo del proyecto en tiempo real sin intervenir en el terminal de Claude Code. La v0.3.1 refuerza la estabilidad del servidor (lectura robusta de frames WebSocket, cabeceras de seguridad HTTP, soporte movil) y anade inyeccion dinamica de version y puerto. La v0.3.6 corrige la nomenclatura de comandos en la web y actualiza las estadisticas. Se lanza con `/alfred gui` y se abre automaticamente en el navegador.
246246

247247
El dashboard actua como fuente de verdad externa: persiste toda la informacion de la sesion independientemente de la compactacion de contexto de Claude Code. Si la conversacion se compacta y se pierde contexto, el dashboard sigue mostrando el historial completo.
248248

agents/optional/librarian.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,11 @@ Las herramientas de consulta que El Bibliotecario ha utilizado desde su origen.
101101
| `memory_get_iteration` | Obtener el detalle completo de una iteración por su ID. |
102102
| `memory_get_timeline` | Recuperar la línea temporal de eventos de una iteración o período. |
103103
| `memory_stats` | Contadores generales de la memoria: decisiones, iteraciones, commits, eventos. |
104-
| `memory_record_decision` | Registrar una nueva decisión con contexto, alternativas y justificación. |
105-
| `memory_record_iteration` | Registrar una nueva iteración con su comando, descripción y fase. |
106-
| `memory_record_event` | Registrar un evento en la cronología del proyecto. |
107-
| `memory_record_commit` | Registrar un commit con su SHA, mensaje y ficheros afectados. |
108-
| `memory_link_commit` | Vincular un commit con una decisión existente. |
104+
| `memory_log_decision` | Registrar una nueva decisión con contexto, alternativas y justificación. |
105+
| `memory_manage_iteration` | Registrar o gestionar una iteración con su comando, descripción y fase. |
106+
| `memory_log_event` | Registrar un evento en la cronología del proyecto. |
107+
| `memory_log_commit` | Registrar un commit con su SHA, mensaje y ficheros afectados. |
108+
| `memory_link_decisions` | Vincular dos decisiones relacionadas entre sí. |
109109

110110
### Bloque de gestión (5 herramientas nuevas)
111111

docs/architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ La capa core contiene la logica de negocio pura del plugin, escrita en Python. E
6868

6969
La capa se compone de tres modulos:
7070

71-
- **`orchestrator.py`** -- Maquina de estados que define 5 flujos de trabajo (feature, fix, spike, ship, audit), cada uno con sus fases secuenciales y quality gates. El orquestador gestiona la creacion de sesiones, la evaluacion de gates y el avance entre fases. El estado se persiste en un fichero JSON plano (`.claude/alfred-dev-state.json`). Desde v0.3.5, la funcion `run_flow()` acepta un parametro opcional `equipo_sesion` que permite inyectar un equipo efimero de agentes opcionales generado por la composicion dinamica (ver [configuration.md](configuration.md#composicion-dinamica-de-equipo)).
71+
- **`orchestrator.py`** -- Maquina de estados que define 5 flujos de trabajo (feature, fix, spike, ship, audit), cada uno con sus fases secuenciales y quality gates. El orquestador gestiona la creacion de sesiones, la evaluacion de gates y el avance entre fases. El estado se persiste en un fichero JSON plano (`.claude/alfred-dev-state.json`). Desde v0.3.6, la funcion `run_flow()` acepta un parametro opcional `equipo_sesion` que permite inyectar un equipo efimero de agentes opcionales generado por la composicion dinamica (ver [configuration.md](configuration.md#composicion-dinamica-de-equipo)).
7272

73-
- **`config_loader.py`** -- Cargador de configuracion que lee las preferencias del usuario desde un fichero `.local.md` con frontmatter YAML y detecta automaticamente el stack tecnologico del proyecto (runtime, lenguaje, framework, ORM, test runner, bundler). Incluye un parser YAML basico como fallback para entornos sin PyYAML. Desde v0.3.5, el modulo incorpora la funcion `match_task_keywords()` y la constante `TASK_KEYWORDS` para la composicion dinamica de equipo: puntuan agentes opcionales segun la descripcion de la tarea del usuario combinada con senales del proyecto y la configuracion activa.
73+
- **`config_loader.py`** -- Cargador de configuracion que lee las preferencias del usuario desde un fichero `.local.md` con frontmatter YAML y detecta automaticamente el stack tecnologico del proyecto (runtime, lenguaje, framework, ORM, test runner, bundler). Incluye un parser YAML basico como fallback para entornos sin PyYAML. Desde v0.3.6, el modulo incorpora la funcion `match_task_keywords()` y la constante `TASK_KEYWORDS` para la composicion dinamica de equipo: puntuan agentes opcionales segun la descripcion de la tarea del usuario combinada con senales del proyecto y la configuracion activa.
7474

7575
- **`personality.py`** -- Motor de personalidad que define la identidad, voz y frases caracteristicas de cada agente. El tono se adapta a un nivel de sarcasmo configurable (1 = profesional, 5 = acido). Con niveles altos se anaden frases mordaces al repertorio de cada agente.
7676

gui/dashboard.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@
316316
<button class="mobile-toggle" id="mobile-toggle" aria-label="Menu de navegacion">
317317
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><line x1="3" y1="5" x2="15" y2="5"/><line x1="3" y1="9" x2="15" y2="9"/><line x1="3" y1="13" x2="15" y2="13"/></svg>
318318
</button>
319-
<div class="header-logo">Alfred <span>Dev</span> <span class="header-version" style="color:var(--text-dim);font-size:11px;font-weight:400;">v0.3.5</span></div>
319+
<div class="header-logo">Alfred <span>Dev</span> <span class="header-version" style="color:var(--text-dim);font-size:11px;font-weight:400;">v0.3.6</span></div>
320320
<div class="header-sep"></div>
321321
<div class="header-project">
322322
Proyecto: <strong id="header-project-name"></strong>
@@ -519,7 +519,7 @@
519519
<span>Ultima actividad: <span id="footer-activity"></span></span>
520520
<div class="footer-sep"></div>
521521
<span>WS puerto <span id="footer-ws-port" style="font-family:var(--font-mono);color:var(--text-muted);">7534</span></span>
522-
<span class="footer-right">Alfred Dev v0.3.5</span>
522+
<span class="footer-right">Alfred Dev v0.3.6</span>
523523
</footer>
524524

525525
</div>

gui/server.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,23 @@ def get_full_state(self) -> Dict[str, Any]:
227227
(active["id"],),
228228
).fetchall()
229229
commits = [dict(r) for r in rows]
230+
else:
231+
# Sin iteración activa: devolver los últimos datos globales
232+
# para que el dashboard no esté vacío.
233+
rows = conn.execute(
234+
"SELECT * FROM decisions ORDER BY id DESC LIMIT 50"
235+
).fetchall()
236+
decisions = [dict(r) for r in rows]
237+
238+
rows = conn.execute(
239+
"SELECT * FROM events ORDER BY id DESC LIMIT 100"
240+
).fetchall()
241+
events = [dict(r) for r in rows]
242+
243+
rows = conn.execute(
244+
"SELECT * FROM commits ORDER BY id DESC LIMIT 50"
245+
).fetchall()
246+
commits = [dict(r) for r in rows]
230247

231248
# Marcados: no dependen de la iteracion
232249
rows = conn.execute(
@@ -645,10 +662,20 @@ def run(self) -> None:
645662
servidor WebSocket y el watcher se ejecutan en el bucle asyncio
646663
del hilo principal.
647664
"""
648-
# Seleccionar puertos disponibles si se pidio auto-deteccion
649-
if self._http_port == 0:
650-
self._http_port = find_available_port(_DEFAULT_HTTP_PORT)
651-
if self._ws_port == 0:
665+
# Verificar que los puertos están disponibles. Si el puerto solicitado
666+
# está ocupado (otra instancia del dashboard u otro servicio), se busca
667+
# automáticamente uno libre. Esto permite tener varios proyectos con
668+
# dashboards activos simultáneamente sin conflictos.
669+
try:
670+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
671+
s.bind(("127.0.0.1", self._http_port))
672+
except OSError:
673+
self._http_port = find_available_port(self._http_port + 1)
674+
675+
try:
676+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
677+
s.bind(("127.0.0.1", self._ws_port))
678+
except OSError:
652679
self._ws_port = find_available_port(self._http_port + 1)
653680

654681
print(f"Alfred Dev Dashboard")

hooks/session-start.sh

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,96 @@ db.close()
157157
" "$MEMORY_DB" "$PLUGIN_ROOT" 2>/dev/null || echo "[Alfred Dev] Aviso: no se pudo crear la BD de memoria" >&2
158158
fi
159159

160+
# --- Asegurar que la memoria está habilitada por defecto ---
161+
#
162+
# Si el fichero de configuración local no existe, se crea con la memoria
163+
# activada para que los hooks de captura registren datos desde la primera
164+
# sesión y el dashboard tenga contenido real desde el minuto 1.
165+
166+
LOCAL_CONFIG="${PROJECT_DIR}/.claude/alfred-dev.local.md"
167+
168+
if [[ ! -f "$LOCAL_CONFIG" ]]; then
169+
# Crear con memoria habilitada por defecto
170+
cat > "$LOCAL_CONFIG" <<'LOCALCFG'
171+
---
172+
memoria:
173+
enabled: true
174+
capture_decisions: true
175+
capture_commits: true
176+
retention_days: 365
177+
---
178+
179+
# Configuración local de Alfred Dev
180+
181+
Este fichero se genera automáticamente en la primera sesión.
182+
Puedes personalizarlo con `/alfred-dev:config`.
183+
LOCALCFG
184+
else
185+
# El fichero existe: verificar que la memoria está habilitada.
186+
# Se usa Python para un parsing fiable del frontmatter YAML en vez de
187+
# sed (cuya sintaxis varía entre BSD/macOS y GNU/Linux).
188+
PYTHONPATH="${PLUGIN_ROOT}" python3 -c "
189+
import re, sys
190+
191+
config_path = sys.argv[1]
192+
with open(config_path, 'r', encoding='utf-8') as f:
193+
content = f.read()
194+
195+
# Comprobar si ya tiene memoria habilitada (mismo regex que memory-capture.py)
196+
pattern = r'memoria:\s*\n(?:\s*#[^\n]*\n|\s*\w+:[^\n]*\n)*?\s*enabled:\s*true'
197+
if re.search(pattern, content):
198+
sys.exit(0) # Ya habilitada, no hacer nada
199+
200+
# Inyectar la seccion de memoria en el frontmatter
201+
memoria_block = '''memoria:
202+
enabled: true
203+
capture_decisions: true
204+
capture_commits: true
205+
retention_days: 365'''
206+
207+
if content.startswith('---'):
208+
# Tiene frontmatter: insertar tras el primer ---
209+
idx = content.index('---') + 3
210+
content = content[:idx] + '\n' + memoria_block + content[idx:]
211+
else:
212+
# Sin frontmatter: envolver con --- e insertar al principio
213+
content = '---\n' + memoria_block + '\n---\n\n' + content
214+
215+
with open(config_path, 'w', encoding='utf-8') as f:
216+
f.write(content)
217+
" "$LOCAL_CONFIG" 2>/dev/null || true
218+
fi
219+
220+
# --- Asegurar iteración activa para el dashboard ---
221+
#
222+
# Si la BD existe pero no hay iteración activa, se crea una de tipo "session"
223+
# para que los commits y eventos capturados durante el trabajo normal se
224+
# asocien a algo y el dashboard tenga contenido desde el primer uso.
225+
# Si el usuario inicia un flujo (/alfred-dev:feature, etc.), la iteración
226+
# "session" se completará y se creará una nueva del flujo correspondiente.
227+
228+
if [[ -f "$MEMORY_DB" ]]; then
229+
PYTHONPATH="${PLUGIN_ROOT}" python3 -c "
230+
import sys
231+
sys.path.insert(0, sys.argv[2])
232+
from core.memory import MemoryDB
233+
234+
db = MemoryDB(sys.argv[1])
235+
active = db.get_active_iteration()
236+
if active is None:
237+
iteration_id = db.start_iteration(
238+
command='session',
239+
description='Sesion de trabajo general',
240+
)
241+
db.log_event(
242+
event_type='session_started',
243+
payload={'source': 'session-start.sh'},
244+
iteration_id=iteration_id,
245+
)
246+
db.close()
247+
" "$MEMORY_DB" "$PLUGIN_ROOT" 2>/dev/null || true
248+
fi
249+
160250
# --- Memoria persistente del proyecto ---
161251

162252
# Si el proyecto tiene memoria (.claude/alfred-memory.db), se extrae

install.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ $ErrorActionPreference = 'Stop'
1919

2020
$Repo = "686f6c61/alfred-dev"
2121
$PluginName = "alfred-dev"
22-
$Version = "0.3.5"
22+
$Version = "0.3.6"
2323

2424
# -- Funciones auxiliares ---------------------------------------------------
2525

0 commit comments

Comments
 (0)