Commit Graph

216 Commits

Author SHA1 Message Date
egutierrez b68ced5c23 feat: integrar skills en runtime de agentes
Integrar sistema de skills en agents/runtime.go:

- Agregar skillLoader al struct Agent
- Inicializar loader y executor cuando skills.enabled = true
- Registrar skill tools en buildToolRegistry
- Respetar filtro de categorias configurado
- Aplicar timeout configurado para scripts

Las skills quedan disponibles automaticamente para agentes que
las habiliten en su config YAML.

Arquitectura: skills como extension opcional, no dependencia core.
2026-03-08 22:13:32 +00:00
egutierrez aeeb475afb feat: tools de function calling para skills
Agregar tools en tools/skilltools/ para interactuar con skills:

- skill_search: busca skills relevantes por query
- skill_load: carga instrucciones completas de una skill
- skill_read_resource: lee recursos especificos (scripts, references, templates)
- skill_run_script: ejecuta scripts de skills con argumentos

Las tools permiten al LLM descubrir, cargar y ejecutar skills
de forma progresiva (metadata → instrucciones → recursos).

Patron standard: Def (puro) + Exec (impuro).
2026-03-08 22:13:26 +00:00
egutierrez 945415112d feat: configuracion de skills en schema
Agregar SkillsCfg y SkillsToolCfg al config schema:

SkillsCfg (nivel agente):
- enabled: activar/desactivar skills
- path: directorio de skills (default: skills/)
- categories: filtro de categorias a cargar
- timeout: timeout de ejecucion de scripts

SkillsToolCfg (nivel tools):
- allowed_interpreters: allowlist de interpreters (bash, python3, etc.)

Permite configurar skills por agente de forma granular.
2026-03-08 22:13:19 +00:00
egutierrez 3638529468 feat: loader y executor de skills en shell
Agregar componentes impuros para manejo de skills en shell/skills/:

Loader (filesystem I/O):
- LoadMeta(): carga metadata de todas las skills
- LoadSkill(): carga skill completa con instrucciones
- ReadResource(): lee recursos con path traversal protection
- Parsing de SKILL.md con frontmatter YAML

Executor (script execution):
- Ejecucion segura de scripts con allowlist de interpreters
- Timeout obligatorio por script
- Inferencia de interpreter desde extension
- Proteccion contra scripts maliciosos

Incluye tests completos con tmpdir para loader y executor.

Arquitectura: impure shell, todo I/O aislado en shell/.
2026-03-08 22:13:12 +00:00
egutierrez f4690a2ba6 feat: tipos puros para sistema de skills
Agregar tipos puros en pkg/skills/ para el sistema de skills:

- SkillMeta: metadata de skills (name, description, category)
- Skill: representacion completa con instrucciones y recursos
- SkillMatch: resultado de matching con confidence score
- Match(): funcion pura de matching por keywords
- FilterByCategory(): filtrado de skills por categorias

Incluye tests unitarios completos para matching y filtrado.

Arquitectura: pure core, cero side effects en pkg/.
2026-03-08 22:13:05 +00:00
egutierrez 76d7619632 merge: issue/0018-shared-knowledge — sistema de conocimiento compartido
Sistema completo de shared knowledge que permite colaboración entre agentes:

**Implementado:**
- Config SharedKnowledge en schema.go (enabled, dir, db_path)
- WAL mode en FileStore para concurrencia entre procesos
- Tools compartidas: shared_knowledge_{search,read,write,list}
- Integración en agents/runtime.go con instanciación y registro
- Carpeta knowledges/ con README explicativo
- Documentación en prompts de agentes
- Tests completos con coexistencia privado/compartido
- .gitignore actualizado (knowledges/data/)
- Estructura actualizada en CLAUDE.md

**Arquitectura:**
- Reutiliza FileStore existente con directorio compartido
- WAL mode permite múltiples lectores + single writer
- Tools prefijadas shared_knowledge_* vs knowledge_* (privado)
- Los .md se commitean, la DB se reconstruye con Sync()

Issue: dev/issues/completed/0018-shared-knowledge.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:57:35 +00:00
egutierrez 44ea4a7d82 chore: cerrar issue 0018 — shared knowledge
- Mover dev/issues/0018-shared-knowledge.md a completed/
- Actualizar dev/issues/README.md: estado completado
- Sistema de conocimiento compartido completamente implementado

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:57:18 +00:00
egutierrez 504abed20f docs: actualizar .gitignore y CLAUDE.md
- Agregar knowledges/data/ a .gitignore (DB no se commitea)
- Agregar knowledges/ a estructura en CLAUDE.md
- Los .md compartidos sí se commitean
- Issue 0018: Shared Knowledge (fase 7)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:57:11 +00:00
egutierrez 0ac2afb573 docs: documentar coexistencia knowledge privado/compartido en prompts
- Separar herramientas en dos secciones
- Explicar diferencia entre knowledge privado y shared
- Guía de cuándo usar cada una
- Issue 0018: Shared Knowledge (fase 5)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:57:05 +00:00
egutierrez ba2ce3c821 docs: crear carpeta knowledges con README
- Carpeta raiz para documentos compartidos entre agentes
- README explica proposito, funcionamiento, diferencia con privado
- Ejemplo de flujo de colaboracion entre agentes
- Issue 0018: Shared Knowledge (fase 4)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:56:58 +00:00
egutierrez 8fcbcba39c feat: integrar shared knowledge store en runtime
- Agregar campo sharedKnowledgeStore al Agent struct
- Inicializar shared store si cfg.Tools.SharedKnowledge.Enabled
- Registrar shared tools en buildToolRegistry
- Cerrar shared store en Run defer
- Defaults: dir=knowledges, db=knowledges/data/knowledge.db
- Issue 0018: Shared Knowledge (fase 3)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:56:51 +00:00
egutierrez 99991c52cf feat: crear shared knowledge tools
- NewSharedKnowledgeTools genera 4 tools prefijadas shared_knowledge_*
- shared_knowledge_search/read/write/list
- Descripciones indican que es compartido entre agentes
- Tests completos con coexistencia privado/compartido
- Issue 0018: Shared Knowledge (fase 2b)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:56:45 +00:00
egutierrez 6f125d3bb7 feat: habilitar WAL mode en knowledge store para concurrencia
- Ejecutar PRAGMA journal_mode=WAL al abrir la DB
- Permite múltiples lectores + single writer concurrentes
- Mejora el rendimiento del shared knowledge compartido
- Issue 0018: Shared Knowledge (fase 2a)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:56:37 +00:00
egutierrez ad5573fbb9 feat: agregar config SharedKnowledge a schema.go
- Nuevo tipo SharedKnowledgeToolCfg con enabled, dir, db_path
- Agregar campo SharedKnowledge a ToolsCfg
- Issue 0018: Shared Knowledge (fase 1)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:56:30 +00:00
egutierrez fcf1053007 merge: issue/0017-mcp-client-tools — cliente MCP para servidores externos
Integra soporte para conectarse a servidores MCP externos y consumir sus tools. El cliente MCP permite descubrir y ejecutar tools remotas, ampliando las capacidades de los agentes sin modificar el core. Esta implementación mantiene la separación pure/impure y se integra con el sistema de tools existente.
2026-03-08 21:45:23 +00:00
egutierrez 1fccae1568 feat: añadir cliente MCP para consumir servidores externos
Implementa el cliente MCP que permite a los agentes conectarse a servidores
MCP externos y usar sus tools como si fueran tools nativas del agente.

Arquitectura implementada:
- shell/mcp/client.go: Cliente MCP con soporte stdio y SSE
- shell/mcp/manager.go: Gestor de múltiples clientes MCP
- tools/mcptools/mcp.go: Bridge que convierte MCP tools → tools.Tool
- shell/mcp/server.go: Movido desde shell/protocols/ para colocación junto al client

Cambios en config:
- MCPServerCfg extendido con campos Transport, Command, Args, Env, Headers,
  Prefix, Timeout para soportar stdio y SSE transport

Integración en runtime:
- agents/runtime.go: Inicializa MCP manager si config.Tools.MCP.Enabled
- buildToolRegistry: Registra tools MCP automáticamente con prefijos configurables
- Agent: Campo mcpManager que se cierra en shutdown

Transportes soportados:
- stdio: Lanza subproceso (ej: npx -y @anthropic/mcp-server-brave-search)
- SSE: Se conecta a servidor HTTP MCP

Las tools MCP son indistinguibles de tools nativas desde el punto de vista
del LLM. Auto-discovery via ListTools(), conversión de JSON Schema a tools.Param.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:22:33 +00:00
egutierrez 5003201dd8 fix: update permissions for 'everyone' user group to allow all actions 2026-03-08 20:59:04 +00:00
egutierrez a212c9ad7c merge: issue/0024c-security-integration — security/ YAML files wired to launcher + runtime
Conecta el sistema centralizado de grupos y permisos al launcher y runtime.
Elimina controles per-agente obsoletos. Activa feature flag. Docs actualizados.
2026-03-08 20:57:52 +00:00
egutierrez c5748212f8 chore: cerrar issue 0024c — security integration + docs
- Actualiza docs/security.md: nueva sección "Sistema de grupos centralizados"
  con estructura de los 3 YAML, acciones disponibles, campos deprecados
- Actualiza .claude/CLAUDE.md: añade security/ en la estructura del proyecto
- Mueve 0024 y 0024c a dev/issues/completed/
- Actualiza dev/issues/README.md: marca 0024, 0024a, 0024b, 0024c como completado

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:57:28 +00:00
egutierrez 8811d45fd1 feat: conectar sistema centralizado de seguridad al launcher y runtime
- Migrar admin a security/user-groups.yaml (admins group)
- agents.New() ahora acepta acl.ACL pre-resuelta como parámetro;
  elimina construcción interna desde cfg.Security.Roles
- cmd/launcher: carga shellsecurity.Load("security/") al arranque;
  si falla, WARN + política vacía (open access). Para cada agente
  llama pksecurity.ResolveACL y pasa la ACL a agents.New()
- cmd/launcher/registry.go: stores secPolicy en launchDeps para
  que reload() también resuelva ACL centralmente
- shell/matrix/listener.go: elimina invite gating y allowlist check
  basados en AllowedUsers; el control de acceso lo hace el runtime
- internal/config/schema.go: depreca campos Roles y AllowedUsers
  (backward compat, no eliminados)
- agents/*/config.yaml: elimina bloques security.roles y allowed_users
- dev/feature_flags.json: activa centralized-security-groups (enabled: true)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:56:21 +00:00
egutierrez ebd8ea3789 merge: issue/0024b-security-loader — security/ YAML files + shell/security/ loader 2026-03-08 20:32:43 +00:00
egutierrez 0102afa06e chore: cerrar issue 0024b-security-loader
Mueve el issue a completed/ y actualiza el índice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:32:23 +00:00
egutierrez 65377afde4 feat: security/ YAML files + shell/security/ loader (issue 0024b)
Crea los tres archivos YAML de configuración de seguridad centralizada en
security/ (user-groups.yaml, agent-groups.yaml, permissions.yaml) y el
loader impuro shell/security/loader.go que los lee y construye un
security.SecurityPolicy puro.

- security/user-groups.yaml: grupos de usuarios (admins, everyone)
- security/agent-groups.yaml: grupos de agentes (assistants, all)
- security/permissions.yaml: políticas de permisos por grupo de agentes
- shell/security/loader.go: Load(dir) → SecurityPolicy; usa structs YAML
  intermedios para mantener pkg/security/ libre de gopkg.in/yaml.v3
- shell/security/loader_test.go: 6 tests cubren los casos del issue
  (dir inexistente, vacío, 3 YAMLs, solo uno, malformado, wildcards)

El código se mergea con feature flag centralized-security-groups = false
(loader creado, todavía no wired al launcher — eso es 0024c).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:32:05 +00:00
egutierrez 0a1893a475 merge: issue/0024a-security-types — pkg/security/ tipos puros y resolución ACL 2026-03-08 20:20:32 +00:00
egutierrez 440a82b766 chore: cerrar issue 0024a-security-types
Mueve el issue a completed/ y actualiza el README de issues.
2026-03-08 20:20:16 +00:00
egutierrez c7531e2b4d feat: pkg/security/ — tipos puros y resolución ACL (issue 0024a)
Crea el paquete puro pkg/security/ con los tipos base del sistema
centralizado de permisos y la función ResolveACL.

Cambios:
- pkg/acl/config.go: añade FromRoles([]Role) ACL como constructor directo
- pkg/security/groups.go: UserGroup, AgentGroup
- pkg/security/policy.go: Permission, AgentPolicy, SecurityPolicy
- pkg/security/resolver.go: ResolveACL(agentID, SecurityPolicy) → acl.ACL
  * soporte wildcard de agente ("*") y de usuario ("*")
  * políticas acumulativas: unión de permisos entre grupos
  * referencia directa por agentID sin definir grupo
- pkg/security/security_test.go: 7 tests cubriendo todos los casos del issue

El paquete es pure core: cero I/O, cero side effects.
Mergeado con feature flag centralized-security-groups = false (no wired).
2026-03-08 20:20:05 +00:00
egutierrez 9c1bc8b5a6 merge: issue/0025-cron-scaffolder — catálogo cron + scaffolder + Fire() 2026-03-08 20:02:30 +00:00
egutierrez dade99b232 chore: añadir feature flag centralized-security-groups para issue 0024
Registra el flag 'centralized-security-groups' desactivado. Protege el
código del issue 0024 (sistema centralizado de grupos de usuarios y
agentes) hasta que todas las sub-issues estén completas.
2026-03-08 20:02:14 +00:00
egutierrez b6af7a0c7e refactor: fix-issue command — crear rama inline sin invocar /git-branch
Simplifica el flujo de fix-issue para crear la rama directamente con
git checkout -b en lugar de invocar /git-branch, que añadía una capa
de indirección innecesaria. Añade lógica para detectar si ya estamos
en la rama correcta y continuar sin recrearla.
2026-03-08 20:02:10 +00:00
egutierrez 73f7ebb9f5 chore: cerrar issue 0025-cron-scaffolder
Mover a completed/ y actualizar estado en README.
2026-03-08 20:01:43 +00:00
egutierrez 3318d9297c docs: añadir crons/ y dev-scripts/cron/ a la tabla de estructura de CLAUDE.md
Actualiza la tabla de estructura del proyecto para reflejar los nuevos
directorios creados en el issue 0025. Añade también README.md en
dev-scripts/cron/ con descripción de cada script y ejemplos de uso.
2026-03-08 20:01:25 +00:00
egutierrez e481cb8783 feat: catálogo crons/ + scripts dev-scripts/cron/ + Fire() en scheduler
Implementa issue 0025: catálogo central de automatizaciones cron y scaffolder.

- crons/: directorio de automatizaciones nombradas con README explicando la
  convención. Incluye dos ejemplos listos para usar:
    · good-morning (send_message, 0 9 * * *) — saludo diario
    · daily-summary (llm_prompt, 0 18 * * *)  — resumen generado por LLM

- dev-scripts/cron/new.sh: scaffolder interactivo — pregunta nombre,
  descripción, tipo de acción y cron expression; crea schedule.yaml +
  archivo de prompt vacío; imprime el bloque YAML para copiar en config.yaml.

- dev-scripts/cron/list.sh: lista todas las automatizaciones del catálogo
  con nombre, tipo, cron y descripción en formato tabular.

- dev-scripts/cron/apply.sh: añade la automatización al config.yaml del
  agente indicado usando yq si está disponible; si no, imprime el bloque
  YAML para copiar a mano (sin dependencias obligatorias).

- shell/cron/scheduler.go: exporta Fire(ctx, sc) para disparo inmediato
  de un schedule sin esperar al timer cron — útil en tests y CLI.

- shell/cron/scheduler_test.go: cuatro tests nuevos para Fire()
  (send_message inline, llm_prompt, sin output_room, sin LLM).
  TestScheduler_SkipsInvalidSchedule y TestFire_LLMPrompt_NoLLM_Skips
  reemplazados por versiones instantáneas usando Fire en lugar de
  @every 100ms + sleep, eliminando ~700ms de tiempo de test.
2026-03-08 20:01:02 +00:00
egutierrez fb2c7fdaa9 merge: issue/0005-bot-cron — cron scheduler autónomo para bots 2026-03-08 19:00:49 +00:00
egutierrez 769f648778 chore: cerrar issue 0005-bot-cron
Se mueve el issue a dev/issues/completed/ y se actualiza el índice en README.md.
El estado cambia de 'pendiente' a 'completado'.
2026-03-08 19:00:41 +00:00
egutierrez 9d1ab2d28e feat: integrar Scheduler en agents/runtime.go
Se instancia shellcron.Scheduler en agents.New() cuando cfg.Schedules tiene
entradas (scheduler queda nil en agentes sin schedules, sin overhead).

En agents.Run() se arranca el scheduler en una goroutine independiente que
termina cuando el ctx del agente es cancelado — el shutdown es limpio gracias
a cron.Stop() que devuelve un contexto que se espera.

La integración no rompe agentes existentes: el campo scheduler es nil por
defecto y todo el código nuevo está tras if a.scheduler != nil.
2026-03-08 19:00:38 +00:00
egutierrez 4dfc6cf0b9 feat: implementar shell/cron — scheduler autónomo para bots
Nuevo paquete shell/cron con dos archivos:

shell/cron/scheduler.go — Scheduler struct con método Start(ctx) que:
  - Registra todas las entradas de config.ScheduleCfg como jobs de robfig/cron
  - Omite schedules sin output_room o sin action.kind (warn en log)
  - Bloquea hasta que ctx sea cancelado, luego detiene el cron limpiamente
  - Recibe MatrixSender, CompleteFunc y *slog.Logger como dependencias (sin importar agents/)

shell/cron/actions.go — ejecutores para fase 1:
  - send_message: resuelve contenido desde Message (inline) o Template (archivo .md),
    luego llama a matrix.SendMarkdown
  - llm_prompt: resuelve prompt desde Prompt o Template, llama al LLM y envía
    la respuesta al room configurado; no-op silencioso si no hay LLM

resolveContent() prioriza texto inline sobre ruta de archivo, lo que permite
tanto mensajes cortos en YAML como prompts largos en archivos .md separados.

Fase 2 (run_tool) y fase 3 (inter-bot) quedan pendientes según el issue.
2026-03-08 19:00:32 +00:00
egutierrez 46d85109fe feat: añadir campo Message/Template/Prompt a ScheduledAction y dependencia cron
Se añaden tres campos nuevos a ScheduledAction en internal/config/schema.go:
- Message: texto inline para send_message
- Template: ruta a archivo .md para send_message o llm_prompt
- Prompt: texto inline del prompt para llm_prompt

Se agrega github.com/robfig/cron/v3 v3.0.1 como dependencia.
No hay cambios de ruptura: los campos son opcionales y el schema existente
sigue siendo compatible.
2026-03-08 19:00:18 +00:00
egutierrez 87a93e304e merge: quick/cleanup-root-binaries — eliminar binarios de raiz y limpiar .gitignore 2026-03-08 18:52:26 +00:00
egutierrez 4824db1c9c chore: eliminar binario register de la raiz del repo
El binario register habia sido commiteado por error antes de estar en .gitignore.
Se elimina del repositorio. En adelante todos los binarios se generan en bin/
mediante build.sh o Makefile, nunca en la raiz del proyecto.
2026-03-08 18:52:22 +00:00
egutierrez c32c6dcd39 chore: limpiar entradas obsoletas de .gitignore
Elimina entradas individuales /launcher, /agentctl, /dashboard, /verify
que eran restos de cuando los binarios se generaban en la raiz del repo.
Los binarios ahora solo se generan en bin/ (cubierto por la entrada bin/).
Agrega run/*.txt para ignorar archivos de texto de run-time.
2026-03-08 18:52:13 +00:00
egutierrez f92191b96c merge: quick/dashboard-reload-controls — controles Reload/Reload All en TUI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:49:05 +00:00
egutierrez f459d4e255 feat: controles de hot-reload por agente en el dashboard TUI
Añade opciones de Reload (hot-reload) separadas de Restart (reinicio
completo) en el dashboard, usando el mecanismo SIGHUP implementado en
el issue 0013.

Cambios en pkg/tui/ (capa pura):
- IntentReloadAgent: hot-reload de un agente individual via SIGHUP
- IntentReloadAll: hot-reload de todos los agentes via SIGHUP
- AgentActionOptions: añade "Reload" antes de "Restart" con descripciones
  clarificadas ("sin interrumpir los demás" vs "launcher completo")
- ServerMenuOptions (running): añade "Reload All" como primera opción
- executeAction: maneja "Reload" → IntentReloadAgent
- executeServerAction: maneja "Reload All" → IntentReloadAll
- Mensajes de estado diferenciados: "Reload OK — X recargado sin
  interrupciones" vs "Restart OK — launcher reiniciado"

Cambios en shell/tui/ (capa impura):
- reloadAgent(id): escribe run/reload.txt + SIGHUP; error si launcher
  no está corriendo (no hay fallback a full restart)
- reloadAll(): elimina reload.txt + SIGHUP; error si no está corriendo
- restartAgent(id): restaurado a su comportamiento original de
  stop+start completo del launcher

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:49:00 +00:00
egutierrez 6829de37c3 merge: issue/0013-hot-reload — hot-reload de agentes individuales via SIGHUP
Implementa recarga en caliente de un agente individual sin detener el launcher:

- Agent.Stop() + Agent.Done() para ciclo de vida individual del agente
- agentRegistry en el launcher para rastrear agentes vivos y recargarlos
- Handler de SIGHUP: lee run/reload.txt para determinar agente objetivo
- TUI: restartAgent() usa SIGHUP en lugar de kill+restart del launcher
- agentctl reload [agent-id]: nuevo subcomando de hot-reload
- Tests: bus.Unsubscribe, readReloadTarget, Agent.Stop/Done

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:44:47 +00:00
egutierrez 25f8aeafaa chore: eliminar issue 0013 de pendientes (ya movido a completed/)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:44:26 +00:00
egutierrez 4419fad754 chore: cerrar issue 0013 — hot-reload implementado
Mueve 0013-hot-reload.md a completed/ y actualiza el índice de issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:44:04 +00:00
egutierrez f95370de80 test: tests para hot-reload (bus, registry, ciclo de vida del agente)
- shell/bus/bus_test.go: tests de Subscribe/Send/Unsubscribe incluyendo
  idempotencia, canal cerrado tras unsubscribe y resubscribe posterior.

- cmd/launcher/registry_test.go: tests para readReloadTarget (archivo
  ausente, vacío, '*', agentID, whitespace).

- agents/lifecycle_test.go: tests para Agent.Stop()/Done() verificando
  que Stop() desbloquea Run y que es seguro llamarlo múltiples veces o
  con cancel nil.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:43:46 +00:00
egutierrez 8ec9f39b6d feat: agentctl reload — subcomando de hot-reload via SIGHUP
Nuevo subcomando: agentctl reload [agent-id]

- Sin argumento: elimina run/reload.txt y envía SIGHUP → todos los
  agentes se recargan.
- Con agent-id: escribe run/reload.txt con el ID y envía SIGHUP → solo
  ese agente se recarga.

Si el launcher no está corriendo, muestra error claro.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:42:38 +00:00
egutierrez 0b74513369 feat: TUI usa SIGHUP para hot-reload de agente individual
restartAgent() ahora escribe run/reload.txt con el agentID y envía
SIGHUP al launcher en lugar de matar y reiniciar el proceso completo.
Si el launcher no está corriendo, conserva el comportamiento anterior
(stop + start completo).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:42:05 +00:00
egutierrez 069f8758b1 feat: hot-reload de agentes individuales via SIGHUP
Implementa el mecanismo de hot-reload descrito en el issue 0013:

- agents/runtime.go: añade Agent.Stop() y Agent.Done() para ciclo de vida
  individual. Run() crea un contexto hijo cancelable y cierra el canal
  done al retornar.

- cmd/launcher/registry.go (nuevo): agentRegistry rastrea agentes vivos
  por ID. Métodos: register, stopAndWait, reload, reloadAll, waitAll,
  cleanupLogs. reload() sigue el flujo completo: stop→wait→unsubscribe
  →reload config→recreate→rewire bus/orch→start nueva goroutine.

- cmd/launcher/main.go: usa agentRegistry en lugar de sync.WaitGroup.
  Añade handler de SIGHUP en goroutine separada que lee run/reload.txt
  para determinar el agente objetivo (* o vacío = todos). Tras leer,
  borra run/reload.txt para no afectar el siguiente SIGHUP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:41:32 +00:00
egutierrez f25ebc7b79 merge: quick/fix-e2e-thread-sender-scope — fixtures E2E robustos con SDK 2026-03-08 18:33:49 +00:00