---
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/<issue>-<slug>"
    WorktreePath  string            // "../wt-<run_id>" 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).
