Commit Graph

6 Commits

Author SHA1 Message Date
egutierrez b92a350023 feat(0145-2,3,4): schema + launcher wiring + claude --mcp-config arg
Pieza 2 — schema (internal/config/schema.go):
- DeviceMeshConfig.ExposeViaMCP *bool: pointer para distinguir "no
  establecido" vs "false explicito". Helper ShouldExposeViaMCP() devuelve
  true cuando enabled && (nil || *true).
- ClaudeCodeCfg.MCPConfigPath y MCPServerName: poblados en runtime por
  la launcher, NUNCA por YAML.

Pieza 3 — launcher wiring (devagents/mcp_bridge.go + cmd/launcher/main.go):
- ApplyMCPBridge(cfg, logger): si DeviceMesh.ShouldExposeViaMCP() y
  provider=claude-code, resuelve binario devicemesh-mcp (junto al
  launcher), URL device_agent (env override > YAML), lista tools allowed
  (RegisterBuiltins + FilterByAllowed igual que registry_build.go), y
  escribe /tmp/<agent_id>-mcp-config.json (0600).
- Aplica overrides a cfg.LLM.Primary.ClaudeCode: MCPConfigPath,
  AllowedTools (formato mcp__<server>__<tool>), DisableTools=false
  defensivo.
- Launcher main.go llama ApplyMCPBridge inmediatamente despues de
  config.Load, ANTES de devagents.New (que es donde se construye el
  CompleteFunc del provider).

Pieza 4 — claude args (shell/llm/claudecode.go):
- buildClaudeArgs ahora emite "--mcp-config <path>" cuando
  cfg.MCPConfigPath no esta vacio.
- Guard defensivo: DisableTools=true + AllowedTools no vacio ahora
  produce solo --allowedTools (efectivamente ignora DisableTools). El
  launcher ya lo previene en ApplyMCPBridge, pero esto protege a
  callers directos.

Build limpio con goolm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:28:34 +02:00
egutierrez 1bdf9344a2 feat: streaming del subproceso claude-code con --output-format stream-json
Implementa la Fase 1 del issue 0036: soporte de streaming en tiempo real
para el provider claude-code.

- Tipos puros de streaming en pkg/llm/types.go: StreamEventKind,
  StreamEvent, StreamFunc (pure core, sin side effects)
- Refactor de shell/llm/claudecode.go: nuevo code path executeStreaming
  que usa cmd.StdoutPipe + bufio.Scanner para leer linea a linea
- Parser parseStreamLine que mapea eventos JSON del CLI (system, assistant,
  result) a StreamEvent del dominio
- buildClaudeArgs ahora selecciona --output-format stream-json cuando
  streaming esta habilitado y StreamFunc presente
- Campos Streaming y ShowToolProgress en ClaudeCodeCfg (config schema)
- Backward compatible: streaming=false (default) no cambia comportamiento
- 40 tests (20 existentes + 20 nuevos) pasan sin errores

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 22:53:41 +00:00
egutierrez 6a5cad5700 test: extraer resolveWorkDir y tests unitarios de aislamiento
Extraer la logica de resolucion de working_dir a una funcion
resolveWorkDir() separada para hacerla testeable. Tres tests cubren:
- WorkingDir vacio → crea tmpdir con prefijo claude-agent-*
- WorkingDir configurado → crea el directorio y lo usa
- WorkingDir ya existente → lo usa sin error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:47:07 +00:00
egutierrez 4f1689c13c feat: default seguro para working_dir en claude-code provider
Cuando WorkingDir esta vacio, se crea un directorio temporal aislado
en lugar de heredar el CWD del launcher (raiz del repo). Esto evita
que el subproceso claude -p tenga acceso de lectura/escritura al
codigo fuente del proyecto.

Si WorkingDir tiene valor, se asegura que el directorio exista
creandolo con MkdirAll. Se loguea WARN cuando se usa el tmpdir
para que el operador lo note y configure explicitamente.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:45:42 +00:00
egutierrez f193f8d5ea fix: matar process group completo de claude-code al cancelar
Cuando se cancela una invocación de claude-code, el proceso principal
moría pero sus hijos (subprocesos node, etc.) quedaban huérfanos
consumiendo recursos. Ahora se crea un process group (Setpgid) y se
mata el grupo entero con kill(-pgid, SIGKILL) tanto en Cancel como
después de Run(), asegurando limpieza completa.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 15:46:18 +00:00
egutierrez 4634ad104b feat: añadir claude-code como proveedor LLM via claude -p
Implementa un nuevo proveedor LLM que ejecuta 'claude -p' como subproceso,
permitiendo usar Claude Code como backend de cualquier agente Matrix.

Cambios:
- pkg/llm/types.go: nueva constante ProviderClaudeCode
- pkg/llm/router.go: routing de 'claude-code' antes de 'claude*' (Anthropic API)
- internal/config/schema.go: nuevo tipo ClaudeCodeCfg con campos para binary,
  timeout, disable_tools, allowed/disallowed tools, permission_mode, model,
  fallback_model, session_id y add_dirs
- shell/llm/claudecode.go: provider completo — buildClaudeArgs(), flattenMessages(),
  parseClaudeOutput() y filterEnv() para limpiar ANTHROPIC_API_KEY del entorno
  y que claude use su propia auth OAuth
- shell/llm/factory.go: case 'claude-code' en FromConfig(), WithFallback() ahora
  recibe fallbackCfg para sobreescribir model/max_tokens al hacer fallback
- agents/runtime.go: actualizado para pasar fallbackCfg a WithFallback()

No se tocó: los proveedores existentes (anthropic.go, openai.go), el core puro
de decision ni el listener de Matrix.
2026-03-06 22:14:28 +00:00