Files
fn_registry/dev/issues/0115-worktree-launcher-fn.md
T
egutierrez b9716a7cd6 chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1
del flow 0008 (kanban_cpp + agent_runner_api + DoD schema).

Incluye:
- dev/flows/0008-kanban-cpp-and-agent-workflows.md
- dev/issues/0112-0119*.md (7 sub-issues)
- WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:17:08 +02:00

119 lines
4.3 KiB
Markdown

---
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).