# /extract-source — Extraer funciones de un repo en sources/

Eres un agente extractor de funciones. Tu trabajo es analizar un repositorio clonado en `sources/` y extraer funciones reutilizables al registry siguiendo las reglas de `.claude/rules/sources.md`.

---

## Argumento

`$ARGUMENTS` — nombre del directorio en `sources/` (ej: `MiroFish`, `OpenViking`). Si no se proporciona, listar los directorios disponibles en `sources/` y pedir al usuario que elija.

---

## PASO 0: Validar el source

```bash
ls sources/$ARGUMENTS/
```

Si no existe, abortar. Verificar que tenga licencia compatible (MIT, Apache 2.0, BSD, ISC, MPL-2.0, Unlicense). Si es AGPL, GPL, o no tiene licencia, **advertir al usuario** y pedir confirmacion antes de continuar.

Identificar:
- **Licencia**: leer LICENSE/LICENSE.md/COPYING
- **Lenguaje principal**: detectar por archivos (*.go, *.py, *.rs, *.ts, *.js, Cargo.toml, go.mod, pyproject.toml, package.json)
- **URL del repo**: buscar en README, .git/config, o package.json

---

## PASO 1: Revisar el manifest

Leer `sources/sources.yaml` para ver si este repo ya tiene extracciones previas. Si las tiene, listarlas al usuario y preguntar si quiere continuar extrayendo mas o si quiere re-evaluar las existentes.

---

## PASO 2: Explorar el repositorio

Analizar la estructura del repo para identificar **todas las funciones candidatas** — puras e impuras. El objetivo es maximizar la extraccion de codigo util.

### Que buscar (por categoria)

**A. Funciones puras** (algoritmos, transformaciones, calculos, validaciones):
- Parsers, encoders/decoders, formatters
- Algoritmos matematicos, estadisticos, financieros
- Transformaciones de datos, filtros, mappers
- Validaciones, sanitizaciones

**B. Funciones impuras** (I/O, red, estado externo):
- Clientes HTTP/API (REST, GraphQL, WebSocket)
- Operaciones de filesystem (leer, escribir, monitorear archivos)
- Interacciones con bases de datos (queries, migraciones)
- Operaciones Docker, cloud, infraestructura
- Scraping, crawling, recoleccion de datos
- Notificaciones, envio de mensajes

**C. Pipelines** (composiciones multi-paso):
- Flujos ETL (extract-transform-load)
- Workflows de setup/deploy/provision
- Secuencias de procesamiento de datos
- Orquestaciones que componen varias funciones

**D. Tipos reutilizables** (structs, enums, interfaces):
- Modelos de dominio genericos
- Tipos de configuracion
- Interfaces/protocolos bien definidos

### Estrategia de exploracion segun lenguaje
- **Go**: `pkg/`, `internal/`, `utils/`, `lib/`, `cmd/` — funciones exportadas, handlers, clients
- **Python**: `src/`, `lib/`, `utils/`, `core/`, `api/` — funciones, clases client, decoradores
- **Rust**: `crates/`, `src/lib.rs` — funciones pub, traits implementados
- **TypeScript/JS**: `src/`, `lib/`, `utils/`, `services/` — funciones, hooks, componentes
- **Bash**: `scripts/`, `bin/`, `tools/` — funciones con firma clara

### Que ignorar
- main(), CLI entry points (pero extraer las funciones que invocan)
- Tests (pero notar cuales funciones estan bien testeadas — marcar `tested: true`)
- Funciones que dependen de tipos internos complejos **no adaptables**
- Codigo con dependencias externas pesadas que no esten en fn_registry
- Config loaders hardcodeados a un proyecto especifico

---

## PASO 3: Consultar el registry para evitar duplicados

Antes de proponer cualquier funcion, buscar en registry.db con FTS5:

```bash
# Por cada candidata, buscar similares
sqlite3 registry.db "SELECT id, kind, purity, description FROM functions WHERE id IN (SELECT id FROM functions_fts WHERE functions_fts MATCH 'name:NOMBRE* OR description:DESCRIPCION') ORDER BY name;"
```

Si ya existe algo similar, descartarla o anotar que es una mejora/variante.

---

## PASO 4: Presentar candidatas al usuario

Agrupar las candidatas por categoria y mostrar en tablas separadas:

### Funciones puras
| # | Nombre propuesto | Origen (archivo) | Lang destino | Dominio | Descripcion |
|---|---|---|---|---|---|

### Funciones impuras
| # | Nombre propuesto | Origen (archivo) | Lang destino | Dominio | I/O tipo | Descripcion |
|---|---|---|---|---|---|---|

(I/O tipo: HTTP, filesystem, DB, Docker, network, etc.)

### Pipelines (composiciones)
| # | Nombre propuesto | Origen (archivo) | Lang destino | Dominio | Funciones que compone | Descripcion |
|---|---|---|---|---|---|---|

### Tipos
| # | Nombre propuesto | Origen (archivo) | Lang destino | Dominio | Algebraic | Descripcion |
|---|---|---|---|---|---|---|

Para cada candidata indicar:
- Por que cumple el filtro de calidad
- Si requiere adaptacion (renombrar tipos, quitar dependencias, traducir lenguaje)
- Si es traduccion de otro lenguaje (ej: Rust → Go)
- Para impuras: cual es el `error_type` apropiado

**Esperar confirmacion del usuario** antes de extraer. El usuario puede:
- Aprobar todas (`all`)
- Seleccionar por numero (`1,3,5-8`)
- Seleccionar por categoria (`todas las puras`, `solo pipelines`)
- Pedir explorar mas areas del repo
- Descartar y terminar

---

## PASO 5: Extraer funciones aprobadas

Para cada funcion aprobada:

### 5a. Determinar destino y clasificacion

| Naturaleza | Destino | kind | purity |
|---|---|---|---|
| Algoritmo/logica pura | Go/Python `functions/{domain}/` | function | pure |
| Funcion con I/O (HTTP, DB, fs) | Go/Python `functions/{domain}/` | function | impure |
| Script/utilidad sistema | Bash `bash/functions/{domain}/` | function | impure |
| UI/componente | TypeScript `frontend/functions/{domain}/` | component | — |
| Composicion multi-paso | `functions/pipelines/` o `python/functions/pipelines/` | pipeline | impure |
| C/Rust/otro lenguaje | Traducir a Go o Python manteniendo semantica | segun caso | segun caso |

### 5b. Crear archivos

1. **Codigo** — copiar y adaptar:
   - Renombrar a snake_case
   - Usar tipos nativos en firma (no tipos internos del repo)
   - Quitar dependencias externas, usar stdlib
   - Ajustar al paquete Go destino (nombre = nombre del directorio)
   - Si es traduccion, mantener la semantica y documentar el origen

2. **Metadata .md** — crear frontmatter completo:
   - `source_repo`: URL del repo original
   - `source_license`: licencia del repo
   - `source_file`: path relativo del archivo original dentro del repo
   - Todos los campos obligatorios segun el tipo (function/pipeline/component)
   - Reglas de pureza:
     - `pure` → `returns_optional: false` + `error_type: ""`
     - `impure` → `error_type: "error_go_core"` (o equivalente Python)
     - `pipeline` → `purity: impure` + `uses_functions` con las funciones que compone

### 5c. Verificar integridad

```bash
# Indexar
./fn index

# Verificar cada funcion extraida
./fn show {id}
```

Si el indexer reporta errores, corregir antes de continuar.

---

## PASO 6: Actualizar manifest

Anadir las funciones extraidas a `sources/sources.yaml` bajo el repo correspondiente:

```yaml
- repo: https://github.com/user/project
  license: MIT
  cloned_dir: nombre_directorio
  extracted:
    - id: funcion_go_core
      source_file: pkg/utils.go
      date: YYYY-MM-DD    # fecha de hoy
```

Si el repo no existe en el manifest, crear la entrada completa.

---

## PASO 7: Resumen

Mostrar al usuario:
- Funciones extraidas exitosamente (con IDs)
- Funciones descartadas y por que
- Warnings del indexer si hubo
- Sugerencia de areas del repo que podrian explorarse en el futuro

---

## Reglas criticas

- **NUNCA extraer sin aprobacion del usuario** — siempre presentar candidatas primero
- **NUNCA ignorar el filtro de calidad** — si no cumple todos los criterios, no se extrae
- **SIEMPRE consultar registry.db** antes de proponer — evitar duplicados
- **SIEMPRE atribuir** — source_repo, source_license, source_file en el .md
- **SIEMPRE actualizar sources.yaml** — es el manifest versionado
- **Licencias no permisivas** (GPL, AGPL) requieren advertencia explicita al usuario
- **Traduccion de lenguaje** es valida — documentar el origen claramente
