Actualiza pyproject.toml con nuevas dependencias (pdfplumber, python-docx, ebooklib, openpyxl, etc.). Actualiza sources.yaml con funciones extraídas de repos externos. Mejora reglas de extracción en sources.md. Añade comando Claude extract-source para workflow de extracción. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.8 KiB
/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
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:
# 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_typeapropiado
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
-
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
-
Metadata .md — crear frontmatter completo:
source_repo: URL del repo originalsource_license: licencia del reposource_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_functionscon las funciones que compone
5c. Verificar integridad
# 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:
- 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