--- id: "0115" title: "Funcion agent_launch_worktree: crear worktree + spawn claude headless" status: pendiente type: feature domain: - agents - workflows - registry-quality scope: registry priority: alta depends: - "0113" blocks: [] related: - "0008" - "0069" created: 2026-05-18 updated: 2026-05-18 tags: [agents, worktree, claude, registry-gap, go] flow: "0008" --- # 0115 — Funcion `agent_launch_worktree` ## Problema `agent_runner_api` (0113) tiene que: (1) crear worktree, (2) spawn `claude --headless`, (3) tail stderr para capturar status, (4) cleanup en abort. Esa logica ya esta inline en: - `.claude/skills/parallel-fix-issues/` (bash) - `fn-orquestador` agent (issue 0069) - futura `agent_runner_api` >2x repeticion -> promover a funcion del registry (regla `delegation.md`). ## Decision Funcion Go nueva `agent_launch_worktree_go_infra` (impure) en `functions/infra/`. API: ```go package infra type WorktreeLaunchConfig struct { RepoRoot string // path al main repo Branch string // "auto/-" WorktreePath string // "../wt-" o absoluto Prompt string // prompt para claude -p LogPath string // donde escribir stderr+stdout Env map[string]string // PATH, HOME, etc. SkipPerms bool // pasa --dangerously-skip-permissions ResetIfExists bool // si branch ya existe, reset --hard a master } type WorktreeLaunchResult struct { PID int Branch string WorktreePath string LogPath string StartedAt int64 Error string // vacio si OK } func AgentLaunchWorktree(cfg WorktreeLaunchConfig) WorktreeLaunchResult ``` Comportamiento: 1. `cd RepoRoot`. 2. Si `ResetIfExists` y branch existe: `git branch -D Branch` + `git worktree remove --force WorktreePath` (best-effort). 3. `git worktree add WorktreePath -b Branch master`. 4. `cmd := exec.Command("claude", args...)` con stdin del Prompt, stderr+stdout a `LogPath`. 5. `cmd.Start()` (no Wait — async). 6. Devuelve PID + path log. Funcion hermana `agent_cleanup_worktree_go_infra`: ```go func AgentCleanupWorktree(repoRoot, branch, worktreePath string, pid int) error ``` Kill PID + remove worktree + delete branch. ## Capability group `agents` Crear `docs/capabilities/agents.md` listando: - `agent_launch_worktree_go_infra` - `agent_cleanup_worktree_go_infra` - (futuro 0117) `dod_evidence_panel_cpp_viz` - (futuro 0118) `agent_runs_timeline_cpp_viz` - (futuro) `dod_validate_evidence_go_infra` Tag `agents` aplicado a las funciones. `fn doctor capabilities` valida. ## Criterios de aceptacion - [ ] `functions/infra/agent_launch_worktree.{go,md}` registrado. - [ ] `functions/infra/agent_cleanup_worktree.{go,md}` idem. - [ ] `params_schema` y `output` completos en frontmatter. - [ ] `.md` cumple contrato self-doc (`## Ejemplo` con args reales, `## Cuando usarla`, `## Gotchas`). - [ ] Tests `*_test.go` con repo temp + branch dummy + comando echo (sin claude real en CI). - [ ] `agent_runner_api` (0113) usa estas funciones — `uses_functions` declarado en `app.md`. - [ ] `parallel-fix-issues` skill actualizada para invocar la funcion (no reescribir inline). O issue separado si scope. - [ ] Tag `agents` aplicado a ambas funciones. - [ ] `docs/capabilities/agents.md` creado con tabla + ejemplo canonico end-to-end. - [ ] `fn doctor capabilities` lista grupo `agents` sin drift. - [ ] `fn doctor uses-functions` limpio en consumers. ## Gotchas - `git worktree add` con branch existente FALLA. `ResetIfExists=true` cubre el caso reanudar de `fn-orquestador`. - Worktrees comparten `.git/hooks/`. Documentar en `## Gotchas` del `.md`. - `claude --headless` no acepta TTY. `cmd.Stdin = strings.NewReader(prompt)`. NO usar `cmd.StdinPipe()` sin cerrar. - Subprocess vive horas. NO esperar Wait sincrono — devolver PID y dejar al caller monitorear. - Path absoluto vs relativo: si `WorktreePath` es relativo, se resuelve respecto a `RepoRoot`. Documentar. - `Env` debe incluir `PATH` que contenga `claude` binary. Service systemd-user no hereda PATH interactivo por defecto. ## Out of scope - Logica TBD merge (vive en `agent_runner_api/handlers.go`). - Watchdog/timeout (vive en `agent_runner_api`). - Telemetria de run (vive en `agent_runs` table).