diff --git a/.claude/skills/auto-create/SKILL.md b/.claude/skills/auto-create/SKILL.md deleted file mode 100644 index 471db22..0000000 --- a/.claude/skills/auto-create/SKILL.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: auto-create -description: Crea un issue nuevo e integra automáticamente SIN pedir confirmación -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit ---- - -# auto-create - -Crea un issue nuevo y lo integra automáticamente **sin pedir confirmación**. - -## Sintaxis - -```bash -/auto-create -``` - -## Diferencia con /create-issue - -Este comando NO pausa para confirmación. Solicita datos pero integra automáticamente. - -## Flujo - -### 1-7. Crear issue (igual que /create-issue) - -1. Determinar número -2. Solicitar inputs (titulo, descripción) -3. Generar slug -4. Evaluar tamaño -5. Crear desde template -6. Feature flag (si aplica) -7. Actualizar índice - -**Sin confirmación** - continuar directamente. - -### 8. Integración automática - -```bash -git checkout master -git pull --rebase -git checkout -b quick/create-issue- - -# Commit -git add dev/issues/*.md dev/issues/README.md -git commit -m "docs: crear issue -" - -# Si multi-issue, commit de feature flag -git add dev/feature_flags.json -git commit -m "feat: agregar feature flag " - -# Tests (si aplican) -go test -tags goolm ./... - -# Merge -git checkout master -git merge --no-ff quick/create-issue- -git push -git branch -d quick/create-issue- -``` - -### 9. Mostrar resultado - -``` -Issue - creado e integrado automáticamente - -Para implementar: - /fix-issue -``` - -## Convenciones - -- Sin confirmación -- Mismo formato que /create-issue -- Trunk-based con rama quick/ diff --git a/.claude/skills/auto-fix/SKILL.md b/.claude/skills/auto-fix/SKILL.md deleted file mode 100644 index 21480ad..0000000 --- a/.claude/skills/auto-fix/SKILL.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: auto-fix -description: Implementa un issue completo automáticamente SIN pedir confirmación -argument-hint: -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit, TodoWrite ---- - -# auto-fix - -Implementa un issue completo automáticamente **sin pedir confirmación** antes de integrar. - -## Sintaxis - -```bash -/auto-fix -/auto-fix - -``` - -## Diferencia con /fix-issue - -Este comando NO pausa para confirmación. Ejecuta todo el flujo automáticamente. - -**Usar cuando:** estés completamente seguro de que el issue puede implementarse automáticamente. - -## Flujo - -### 1-8. Implementar (igual que /fix-issue) - -1. Resolver issue objetivo -2. Leer issue completo -3. Crear rama `issue/-` -4. Planificar con TodoWrite -5. Implementar completo -6. Tests obligatorios -7. Feature flags (si aplica) -8. Cerrar issue - -**Sin confirmación** - continuar directamente. - -### 9. Integración automática - -```bash -git checkout master -git pull --rebase -go test -tags goolm ./... # verificación final -git merge --no-ff issue/- -m "merge: issue/-" -git push -git branch -d issue/- -``` - -### 10. Mostrar resultado - -``` -Issue completado e integrado automáticamente - -Commits integrados: N -Tests: pasando -Issue: movido a completed/ - -NOTA: Integración automática sin confirmación. -``` - -## Convenciones - -- Sin confirmación (diferencia clave) -- Misma calidad que /fix-issue -- STOP si tests fallan - -## Reglas - -- NO pedir confirmación -- MISMA calidad que /fix-issue -- STOP si tests fallan (no integrar código roto) diff --git a/.claude/skills/cleanup-worktrees/SKILL.md b/.claude/skills/cleanup-worktrees/SKILL.md deleted file mode 100644 index e339a79..0000000 --- a/.claude/skills/cleanup-worktrees/SKILL.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: cleanup-worktrees -description: Limpia worktrees y ramas locales después de merge -argument-hint: | --all -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read ---- - -# cleanup-worktrees - -Elimina worktrees y sus ramas locales asociadas después de haber sido mergeadas. - -## Sintaxis - -```bash -/cleanup-worktrees # Limpiar worktree específico -/cleanup-worktrees --all # Limpiar todos -``` - -## Flujo - -### 1. Validar argumentos - -- Número de issue (4 dígitos): limpiar ese worktree -- `--all`: limpiar todos en `worktrees/` - -### 2. Determinar worktrees a limpiar - -```bash -# Para issue específica -WORKTREE_PATH="worktrees/issue-$ISSUE_NUM" - -# Para --all -find worktrees -maxdepth 1 -type d -name "issue-*" -``` - -### 3. Confirmar con usuario - -``` -Se eliminarán: - - worktrees/issue-0003 (rama: quick/fix-issue-0003) - -¿Continuar? (y/N): -``` - -### 4. Limpiar cada worktree - -Para cada uno: -1. Verificar si rama fue mergeada -2. Si NO mergeada: advertir y preguntar -3. Eliminar worktree: `git worktree remove --force` -4. Eliminar rama: `git branch -D ` - -### 5. Reportar resultado - -``` -Limpieza completada - -Worktrees restantes: - (ninguno) -``` - -## Convenciones - -- Nomenclatura worktrees: `worktrees/issue-NNNN` -- Nomenclatura ramas: `quick/fix-issue-NNNN` -- Confirmación interactiva siempre - -## Reglas - -- SIEMPRE verificar merge antes de eliminar -- NUNCA eliminar sin confirmación -- SIEMPRE usar --force en worktree remove diff --git a/.claude/skills/create-agent/SKILL.md b/.claude/skills/create-agent/SKILL.md deleted file mode 100644 index 87f62e0..0000000 --- a/.claude/skills/create-agent/SKILL.md +++ /dev/null @@ -1,439 +0,0 @@ ---- -name: create-agent -description: Crea un nuevo agente especializado en .claude/agents/ con su SKILL.md y estructura completa -argument-hint: [nombre] -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit, AskUserQuestion ---- - -# create-agent - -Crea un nuevo agente especializado en `.claude/agents/` con archivo `SKILL.md` obligatorio siguiendo la estructura oficial de Claude Code. - -## Sintaxis - -```bash -/create-agent [nombre] -/create-agent api-client -/create-agent cloud-deploy -``` - -## Precondiciones - -- [ ] Carpeta `.claude/agents/` existe -- [ ] No existe agente con el mismo nombre -- [ ] Nombre cumple convenciones (minúsculas, guiones) - -## Flujo - -### 1. Validar nombre - -- Solo minúsculas, números y guiones -- No nombres reservados (help, clear, exit) -- Máximo 64 caracteres - -```bash -ls -d .claude/agents/*/ 2>/dev/null | xargs -n1 basename | grep -E "^${nombre}$" -``` - -Si existe, STOP. - -### 2. Solicitar inputs usando AskUserQuestion - -Usar `AskUserQuestion` para obtener: - -#### Input 1: Información básica -- **nombre**: minúsculas y guiones (ej: `api-client`) -- **descripcion**: qué hace el agente y cuándo invocarlo (1-2 frases claras) - -#### Input 2: Configuración técnica -- **model**: Modelo Claude a usar - - `sonnet` (default): Balance costo/capacidad - - `opus`: Tareas complejas que requieren máximo razonamiento - - `haiku`: Tareas simples y rápidas - -- **tools**: Herramientas necesarias (separadas por coma) - - Default: `Read, Write, Bash, Glob, Grep, Edit` - - Opcionales: `WebFetch, WebSearch, NotebookEdit` - -#### Input 3: Configuración de proyecto -- **gestiona_repo**: ¿Gestiona un repositorio local? - - `si`: Crear carpeta en `~/.local_agentes/` - - `no`: Solo definición de agente - -- **usa_mcp**: ¿Usa MCP servers? (gitea, sqlite, etc) - - `si`: Solicitar configuración de MCP - - `no`: Omitir mcpServers - -#### Input 4: MCP Servers (si usa_mcp = si) -Preguntar qué MCP servers necesita: -- `gitea`: Gestión de repositorios Gitea -- `sqlite`: Bases de datos SQLite -- `filesystem`: Sistema de archivos -- `otro`: Configuración personalizada - -#### Input 5: Documentación -- **rol**: Rol del agente (ej: "Eres un experto en...") -- **capacidades**: Lista de capacidades principales -- **flujo_trabajo**: Descripción del flujo de trabajo típico -- **ejemplos_uso**: Ejemplos de cuándo invocar al agente - -### 3. Crear carpeta del agente - -```bash -mkdir -p .claude/agents/${nombre} -``` - -### 4. Crear carpeta local (si gestiona_repo = si) - -```bash -mkdir -p ~/.local_agentes/${nombre} -``` - -### 5. Generar frontmatter YAML - -Estructura base: -```yaml ---- -name: ${nombre} -description: ${descripcion} -model: ${model} -tools: ${tools} -mcpServers: # Solo si usa_mcp = si - - ${mcp_config} ---- -``` - -### 6. Generar SKILL.md completo - -Template oficial de agente: - -```markdown ---- -name: ${nombre} -description: ${descripcion} -model: ${model} -tools: ${tools} -${mcp_servers_section} ---- - -# Agente ${nombre} - -${rol} - -## Tu entorno - -${descripcion_entorno} - -## Capacidades principales - -${capacidades} - -## Flujo de trabajo - -${flujo_trabajo} - -## Templates disponibles - -${templates_codigo} - -## Integración con otros agentes - -${integracion} - -## Ejemplos de uso - -${ejemplos_uso} - -## Comandos útiles - -${comandos} - -## Notas y convenciones - -${notas} -``` - -### 7. Templates de MCP Servers - -#### Gitea MCP -```yaml -mcpServers: - - gitea: - type: stdio - command: gitea-mcp - args: - - -t - - stdio - - --host - - "${GITEA_URL}" - - --token - - "${GITEA_TOKEN}" -``` - -#### SQLite MCP -```yaml -mcpServers: - - sqlite: - type: stdio - command: sqlite-mcp - args: - - --db - - "${DB_PATH}" -``` - -#### Filesystem MCP -```yaml -mcpServers: - - filesystem: - type: stdio - command: mcp-server-filesystem - args: - - --allowed-directories - - "${ALLOWED_DIR}" -``` - -### 8. Mostrar y confirmar - -``` -Agente creado: ${nombre} -Ubicación: .claude/agents/${nombre}/SKILL.md -${carpeta_local ? "Carpeta local: ~/.local_agentes/" + nombre : ""} - -Configuración: -- Model: ${model} -- Tools: ${tools} -- MCP: ${usa_mcp ? "Sí" : "No"} -- Repositorio local: ${gestiona_repo ? "Sí" : "No"} - -¿Te parece bien? -- Si correcto: commit e integrar automáticamente -- Si ajustes: edita manualmente antes de integrar -``` - -### 9. Crear README.md en carpeta local (si gestiona_repo = si) - -```bash -cat > ~/.local_agentes/${nombre}/README.md <-.md` - -**Issue grande:** crear SOLO sub-issues `a-`, `b-`, etc. - -### 5. Crear desde template - -Usar template en `${CLAUDE_SKILL_DIR}/issue.md` y rellenar todas las secciones: -- Metadata, Objetivo, Contexto -- Arquitectura, Patrón pure/impure -- Tareas, Ejemplo de uso -- Criterios de aceptación - -### 6. Feature flag (solo multi-issue) - -Actualizar `dev/feature_flags.json`: -```json -{ - "": { - "enabled": false, - "issue": "", - "description": "..." - } -} -``` - -### 7. Actualizar índice - -En `dev/issues/README.md` agregar fila(s). - -### 8. Mostrar y confirmar - -``` -Issue creado: - - -¿Te parece bien? -- Si es correcto: commit y push automáticamente -- Si necesitas ajustes: edita manualmente -``` - -### 9. Ejecutar /git-push automáticamente - -Si confirma, crear rama `quick/create-issue-` y ejecutar flujo git. - -## Convenciones - -- Numeración continua sin saltos -- Estado inicial: pendiente -- Issues cortos (horas por rama) -- Sub-issues autocontenidos diff --git a/.claude/skills/create-issue/issue.md b/.claude/skills/create-issue/issue.md deleted file mode 100644 index 2132851..0000000 --- a/.claude/skills/create-issue/issue.md +++ /dev/null @@ -1,128 +0,0 @@ -# NNNN — [Título de la Issue] - -## Metadata - -| Campo | Valor | -|-------|-------| -| **ID** | NNNN | -| **Estado** | 🟡 pendiente / 🔵 en progreso / ✅ completado / 🔴 bloqueado | -| **Prioridad** | alta / media / baja | -| **Tipo** | feature / bugfix / refactor / docs / infrastructure | - -## Dependencias - - - -| ID | Título | Estado | Requerido | -|----|--------|--------|-----------| -| 0001 | Actualizar nombre del módulo | ✅ | Sí | -| 0002 | Implementar core/ | ✅ | Sí | - -**Bloqueada por:** `#0001, #0002` - -**Desbloquea:** `#0006, #0007` - -> **⚠️ VALIDACIÓN AUTOMÁTICA**: Esta issue no puede iniciarse hasta que todas las dependencias estén en estado `✅ completado`. - ---- - -## Objetivo - -[Descripción concisa de qué se quiere lograr en 1-3 oraciones] - -## Contexto - -- [Punto de contexto 1] -- [Punto de contexto 2] -- [Referencias a otras issues o decisiones previas] - -## Arquitectura - -``` -[Estructura de archivos afectados] -dir/ -├── file1.go — Descripción -├── file2.go — NEW: Nuevo archivo -└── file3.go — MODIFY: Modificación -``` - -### Patrón pure core / impure shell - -- `core/` — [Qué funciones puras se agregan] -- `shell/` — [Qué operaciones I/O se implementan] -- `app/` — [Cómo se orquesta] - -## Tareas - -### Fase 1: [Nombre de fase] - -- [ ] **1.1** [Descripción detallada de tarea] -- [ ] **1.2** [Otra tarea] - -### Fase 2: [Otra fase] - -- [ ] **2.1** [Tarea] -- [ ] **2.2** [Tarea] - -### Fase N: Cleanup y docs - -- [ ] Actualizar `README.md` con cambios relevantes -- [ ] Actualizar `CLAUDE.md` si hay cambios arquitectónicos -- [ ] Ejecutar `go mod tidy` -- [ ] Ejecutar `go test ./...` -- [ ] Actualizar issue en `dev/issues/README.md` - ---- - -## Ejemplo de uso - -```bash -# Comandos de ejemplo -comando ejemplo arg1 arg2 - -# Output esperado: -# ✓ Success message -``` - -```go -// Código de ejemplo si aplica -package example - -func Example() {} -``` - -## Decisiones de diseño - -- **Decisión 1**: Razón y trade-offs -- **Decisión 2**: Alternativas consideradas y por qué se eligió esta - -## Prerequisitos - -- Issue #NNNN completado -- Herramienta X instalada -- Configuración Y realizada - -## Riesgos - -- **Riesgo 1**: Descripción del riesgo. **Mitigación**: Cómo se mitigará -- **Riesgo 2**: Otro riesgo. **Mitigación**: Plan de mitigación - -## Criterios de aceptación - -- [ ] Todos los tests pasan -- [ ] Feature flag agregado en `feature_flags.json` -- [ ] Documentación actualizada -- [ ] Code review aprobado -- [ ] Deployable a main - ---- - -## Notas de implementación - -[Notas que surjan durante la implementación, decisiones tomadas, problemas encontrados] - -## Referencias - -- [Link a documentación relevante] -- [Link a PRs relacionados] -- [Link a discusiones] diff --git a/.claude/skills/create-repo/SKILL.md b/.claude/skills/create-repo/SKILL.md deleted file mode 100644 index c23e36b..0000000 --- a/.claude/skills/create-repo/SKILL.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -name: create-repo -description: Crea un nuevo subrepo en workspaces/ con estructura core/shell/app -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write ---- - -# create-repo - -Crea un nuevo workspace (subrepo) con estructura estándar, repo en Gitea, y registro en BD. - -## Prerequisitos - -- Variables: `GITEA_URL` y `GITEA_TOKEN` -- Feature flag `workspace_commands` habilitado - -## Flujo interactivo - -### 1. Solicitar inputs - -1. **Nombre**: URL-safe (lowercase, alfanumérico, guiones) -2. **Descripción**: texto libre -3. **Tipo**: go, data, etl, api -4. **¿Privado?**: s/n (default: n) - -### 2. Mostrar resumen y confirmar - -``` -Resumen: - Nombre: my-etl-pipeline - Path local: ./workspaces/my-etl-pipeline - Gitea: https://gitea.../my-etl-pipeline - Tipo: etl - Privado: no - -¿Crear repositorio? (s/n): -``` - -### 3. Ejecutar creación - -Usa `app.CreateWorkspaceCommand(config, params)`: -1. Validar nombre -2. Verificar que no existe -3. Crear estructura core/shell/app/ -4. Escribir templates (go.mod, main.go, etc.) -5. git init + configurar usuario -6. Crear repo en Gitea -7. Push inicial -8. Registrar en SQLite - -**Rollback automático** si falla cualquier paso. - -### 4. Mostrar resultado - -``` -Workspace creado: ./workspaces/my-etl-pipeline - -Para trabajar: - cd workspaces/my-etl-pipeline -``` - -## Validación de nombre - -- Solo letras, números y guiones -- No empezar/terminar con guión -- 2-100 caracteres - -## Troubleshooting - -- "nombre inválido": usar solo lowercase, alfanumérico, guiones -- "ya existe": verificar `ls workspaces/` o usar otro nombre -- "error Gitea": verificar GITEA_TOKEN diff --git a/.claude/skills/fix-issue/SKILL.md b/.claude/skills/fix-issue/SKILL.md deleted file mode 100644 index 63ac54c..0000000 --- a/.claude/skills/fix-issue/SKILL.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -name: fix-issue -description: Implementa un issue completo de punta a punta con confirmación -argument-hint: -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit, TodoWrite ---- - -# fix-issue - -Ejecuta el flujo completo de implementación/cierre de un issue: crear rama, implementar, testear, cerrar, confirmar, integrar. - -## Sintaxis - -```bash -/fix-issue -/fix-issue - -``` - -## Precondiciones - -- [ ] Directorio `dev/issues/` existe -- [ ] Directorio `dev/issues/completed/` existe -- [ ] Tests configurados -- [ ] Working tree limpio - -## Flujo - -### 1. Resolver issue objetivo - -```bash -ls dev/issues/-*.md -``` - -- Si no existe: STOP "Issue no encontrado" -- Si ya completado: STOP "Issue ya completado" - -### 2. Leer issue completo - -Extraer: objetivo, tareas, arquitectura, patrón pure/impure, tests. - -### 3. Crear rama de trabajo - -```bash -git checkout master -git pull --rebase -git checkout -b issue/- -``` - -### 4. Planificar con TodoWrite - -Crear plan basado en tareas del issue. - -### 5. Implementar completo - -Para cada tarea: -1. Implementar siguiendo patrón pure core / impure shell -2. Compilar frecuentemente: `go build -tags goolm ./...` -3. Crear commits atómicos durante implementación - -### 6. Tests obligatorios - -```bash -go test -tags goolm ./... -``` - -- Pasan: continuar -- Fallan: STOP y corregir - -### 7. Feature flags (si aplica) - -Actualizar `dev/feature_flags.json` si es multi-issue. - -### 8. Cerrar issue - -```bash -mv dev/issues/-.md dev/issues/completed/ -``` - -Actualizar índice en README.md. - -### 9. Mostrar resumen y confirmar - -``` -Issue completado - -Resumen: -- N archivos modificados -- N commits realizados -- Tests: pasando - -¿Integrar a master? -``` - -### 10. Ejecutar /git-push - -Si confirma, ejecutar flujo de integración. - -## Convenciones - -- Implementar TODAS las tareas -- Commits atómicos durante implementación -- Tests obligatorios -- Pure core / impure shell - -## Reglas - -- NO saltear tareas -- NO commits WIP -- SIEMPRE tests antes de cerrar -- Confirmación obligatoria antes de integrar diff --git a/.claude/skills/git-branch/SKILL.md b/.claude/skills/git-branch/SKILL.md deleted file mode 100644 index a6ebec6..0000000 --- a/.claude/skills/git-branch/SKILL.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -name: git-branch -description: Crea una rama de trabajo (issue/* o quick/*). Nunca trabajar directamente en master. -argument-hint: -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read ---- - -# git-branch - -Crea una rama de trabajo siguiendo trunk-based development. **Nunca trabajar directamente en master.** - -## Sintaxis - -```bash -/git-branch issue -/git-branch quick -``` - -## Ejemplos - -```bash -/git-branch issue 0013 hot-reload # Crea issue/0013-hot-reload -/git-branch quick fix-typo-readme # Crea quick/fix-typo-readme -``` - -## Precondiciones - -- [ ] Repositorio git válido -- [ ] Branch master existe -- [ ] Working tree limpio (sin cambios pendientes) - -## Flujo - -### 1. Verificar estado del repositorio - -```bash -git branch --show-current -git status --short -``` - -**Si no estamos en master:** `git checkout master` - -**Si hay cambios sin commitear:** STOP y avisar al usuario: -``` -Hay cambios sin commitear. Opciones: -1. Commitear: git add . && git commit -m "mensaje" -2. Stash: git stash -3. Descartar: git reset --hard (peligroso) -``` - -### 2. Actualizar master desde remoto - -```bash -git pull --rebase -``` - -### 3. Crear rama según tipo - -**Para issues:** -```bash -git checkout -b issue/- -``` - -**Para cambios rápidos:** -```bash -git checkout -b quick/ -``` - -### 4. Confirmar creación - -```bash -git branch --show-current -``` - -Informar: -``` -Rama `` creada desde master actualizado - -Cuando termines: - /git-push -``` - -## Convenciones - -- **Formato issue**: `issue/-` (4 dígitos) -- **Formato quick**: `quick/` -- **Ramas cortas**: horas, no días -- **No pushear ramas**: integrar via merge a master -- **No underscores**: solo guiones - -## Reglas - -- NUNCA trabajar directamente en master -- SIEMPRE verificar working tree limpio -- SIEMPRE actualizar master antes de crear rama diff --git a/.claude/skills/git-push/SKILL.md b/.claude/skills/git-push/SKILL.md deleted file mode 100644 index 548fba1..0000000 --- a/.claude/skills/git-push/SKILL.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: git-push -description: Integra cambios a master y publica. Soporta ramas issue/* y quick/*. -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit ---- - -# git-push - -Integra cambios a master y publica al remoto. Detecta automáticamente la rama actual. - -## Sintaxis - -```bash -/git-push -``` - -## Flujo - -### 1. Verificar rama actual y estado - -```bash -git branch --show-current -git status --short -``` - -**Caso A: En rama issue/* o quick/*** - Continuar al paso 2 - -**Caso B: En master con cambios** - Crear rama quick automáticamente: -- Analizar archivos modificados para generar slug -- `git checkout -b quick/` - -**Caso C: En master sin cambios** - STOP: "No hay nada que publicar" - -### 2. Crear commits por bloque lógico - -```bash -git status --short -git diff --stat -``` - -Agrupar cambios por tipo y crear commits atómicos: - -```bash -git add -git commit -m ": " -m "" -``` - -**Tipos:** feat, fix, refactor, docs, chore, test - -**Reglas de commits:** -- No WIP -- No mezclar tipos -- Descripción larga obligatoria en español - -### 3. Ejecutar tests - -```bash -go test -tags goolm ./... -``` - -- Tests pasan: continuar -- Tests fallan: STOP y corregir -- No hay tests: informar y continuar - -### 4. Merge a master - -```bash -git checkout master -git pull --rebase -git merge --no-ff -m "merge: " -``` - -### 5. Push a remoto - -```bash -git push -``` - -### 6. Limpiar rama local - -```bash -git branch -d -``` - -### 7. Verificación final - -```bash -git log --oneline -3 -``` - -``` -Rama `` integrada a master y publicada - -Commits creados: -- -- merge: - -Rama local eliminada. -``` - -## Convenciones - -- Commits atómicos -- Tests obligatorios antes de merge -- Merge --no-ff siempre -- Push inmediato - -## Reglas - -- NO commits WIP -- NO mezclar tipos en un commit -- NO saltear tests -- NO push --force a master -- SIEMPRE usar --no-ff diff --git a/.claude/skills/git-recovery/SKILL.md b/.claude/skills/git-recovery/SKILL.md deleted file mode 100644 index a28c4a1..0000000 --- a/.claude/skills/git-recovery/SKILL.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -name: git-recovery -description: Recupera el repositorio de estados inconsistentes (worktrees huérfanos, branches bloqueados) -argument-hint: [--aggressive] -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read ---- - -# git-recovery - -Recupera el repositorio de estados inconsistentes causados por worktrees huérfanos, branches bloqueados o conflictos git. - -## Sintaxis - -```bash -/git-recovery # Recuperación estándar -/git-recovery --aggressive # Limpieza agresiva -``` - -## Cuándo usar - -- Errores "exit status 128" al crear worktrees -- Git reporta "worktree already exists" -- Branches que no se pueden eliminar -- Worktrees huérfanos en `git worktree list` - -## Flujo - -### 1. Diagnóstico inicial - -```bash -git branch --show-current -git status --porcelain -``` - -### 2. Análisis de problemas - -```bash -git worktree list -git branch --list -git remote -v -``` - -### 3. Limpieza de worktrees huérfanos - -```bash -git worktree prune -v -``` - -Si existe directorio `worktrees/`: -- Verificar cada worktree contra `git worktree list` -- Eliminar directorios huérfanos - -### 4. Verificar branches bloqueados - -Para cada branch issue/* o quick/*: -- Si está mergeada: `git branch -d ` -- Si NO está mergeada: advertir - -### 5. Sincronizar con remoto - -```bash -git checkout master -git fetch origin -git pull --rebase origin master -``` - -### 6. Modo agresivo (solo con --aggressive) - -```bash -git remote prune origin -v -git fsck --full -git gc --prune=now -rm -f .git/index.lock # si existe -``` - -### 7. Verificación final - -```bash -git status -git worktree list -git branch --list -``` - -## Patrones de error que activan recovery - -- `exit status 128` -- `worktree .* already exists` -- `reference is not a tree` -- `cannot lock ref` -- `index.lock` - -## Convenciones - -- No destructivo por defecto -- Modo agresivo solo con flag explícito -- Siempre sincroniza con remoto -- Preserva cambios locales - -## Reglas - -- NUNCA git reset --hard sin --aggressive -- NUNCA eliminar branches no mergeadas automáticamente -- SIEMPRE sincronizar con remoto después de limpieza diff --git a/.claude/skills/import-repo/SKILL.md b/.claude/skills/import-repo/SKILL.md deleted file mode 100644 index 6f3b603..0000000 --- a/.claude/skills/import-repo/SKILL.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -name: import-repo -description: Importa repositorios existentes al sistema Dataforge desde URL remota o local -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write ---- - -# import-repo - -Importa repositorios existentes: desde GitHub/GitLab/Gitea, o adoptando un repo local. - -## Prerequisitos - -- Variables: `GITEA_URL` y `GITEA_TOKEN` -- Feature flag `workspace_commands` habilitado - -## Modos - -### Desde URL remota - -1. Crear repo vacío en Gitea -2. Clonar origen con `git clone --mirror` -3. Push a Gitea con `git push --mirror` -4. Clonar en `workspaces/` -5. Registrar en BD - -### Adoptar repo local - -1. Verificar que existe `.git` -2. Crear repo vacío en Gitea -3. Añadir remote `gitea` -4. Push de branches y tags -5. Registrar en BD - -## Flujo interactivo - -### 1. Solicitar fuente - -``` -Fuente del repositorio: - - URL remota (ej: https://github.com/user/repo) - - Nombre local en workspaces/ (ej: legacy-tool) -``` - -### 2. Detectar modo y analizar - -Usa `core.DetectImportMode(source)` - -### 3. Solicitar nombre de destino - -``` -Nombre en Gitea (Enter para usar 'nombre-sugerido'): -``` - -### 4. Verificar que no existe en Gitea - -### 5. Opciones adicionales - -``` -¿Repositorio privado? (s/N): -Descripción (opcional): -``` - -### 6. Resumen y confirmación - -``` -Resumen: - Fuente: https://... - Destino: gitea.example.com/... - Tipo: importar desde URL remota - -¿Importar? (s/N): -``` - -### 7. Ejecutar importación - -### 8. Mostrar resultado - -``` -Repositorio importado exitosamente. - -Workspace: workspaces/nombre -Gitea URL: https://... -``` - -## Convenciones - -- Confirmación obligatoria -- Rollback automático si falla -- Historia Git siempre preservada diff --git a/.claude/skills/init-frontend/SKILL.md b/.claude/skills/init-frontend/SKILL.md deleted file mode 100644 index 21875ac..0000000 --- a/.claude/skills/init-frontend/SKILL.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -name: init-frontend -description: Inicializa proyecto frontend (React/Vite) o desktop (Wails) con Frontend_Library -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit ---- - -# init-frontend - -Inicializa un proyecto frontend (webapp React/Vite) o desktop (Wails + Go + React). Coherente con Frontend_Library y el stack del frontend-lib/build-wails agents. - -## Sintaxis - -```bash -/init-frontend [nombre] [--wails] [--path /ruta/destino] -``` - -- `nombre`: nombre del proyecto (kebab-case). Si no se da, se pregunta. -- `--wails`: modo desktop con Wails (Go backend + React frontend). Sin flag = webapp pura. -- `--path`: directorio destino. Default: directorio actual. - -## Flujo - -### 1. Ejecutar script de setup - -```bash -bash "${CLAUDE_SKILL_DIR}/setup-frontend.sh" [nombre] [--wails] [path] -``` - -### 2. Si el script reporta STATUS: CONFIGURED - -Informar al usuario que el proyecto ya existe. - -### 3. Si el script reporta STATUS: READY - -Mostrar resumen según modo: - -**Webapp:** -- `pnpm dev` para desarrollo -- `pnpm build` para producción -- Frontend_Library linkeada via pnpm - -**Wails:** -- `make dev` para desarrollo con hot reload -- `make build` para compilar -- Frontend_Library + DevFactory integrados -- Bindings Go→TS auto-generados - -### 4. Si el script reporta STATUS: ERROR - -Mostrar el error y sugerir corrección. - -## Convenciones - -- pnpm exclusivamente (no npm ni yarn) -- React 19 + TypeScript + Vite + Tailwind CSS 4 -- @anthropic/frontend-lib via pnpm link -- Temas OKLCH con semantic tokens -- Phosphor Icons -- Vite dedupe obligatorio para react/react-dom -- En modo Wails: go.work con DevFactory, patrón pure core / impure shell diff --git a/.claude/skills/init-frontend/setup-frontend.sh b/.claude/skills/init-frontend/setup-frontend.sh deleted file mode 100755 index c102acc..0000000 --- a/.claude/skills/init-frontend/setup-frontend.sh +++ /dev/null @@ -1,438 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# ============================================================================= -# setup-frontend.sh — Inicializa proyecto React/Vite o Wails desktop -# Coherente con Frontend_Library + DevFactory + build-wails agent -# ============================================================================= - -# --- Colores --- -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' - -log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } -log_ok() { echo -e "${GREEN}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } -log_step() { echo -e "${CYAN}[STEP]${NC} $1"; } - -# --- Parámetros --- -PROJECT_NAME="" -WAILS_MODE=false -TARGET_PATH="." - -while [[ $# -gt 0 ]]; do - case "$1" in - --wails) WAILS_MODE=true; shift ;; - --path) TARGET_PATH="$2"; shift 2 ;; - -*) log_error "Flag desconocido: $1"; echo "STATUS: ERROR"; exit 1 ;; - *) PROJECT_NAME="$1"; shift ;; - esac -done - -# --- Rutas de librerías --- -FRONTEND_LIB="$HOME/.local_agentes/frontend/frontend" -DEVFACTORY_PATH="$HOME/.local_agentes/backend" -TEMPLATES_DIR="$HOME/.local_agentes/frontend/templates/base" -WAILS_TEMPLATES="$HOME/.claude/agents/build-wails/templates" - -# --- Validar nombre --- -if [[ -z "$PROJECT_NAME" ]]; then - log_error "Uso: setup-frontend.sh [--wails] [--path /ruta]" - echo "STATUS: ERROR" - exit 1 -fi - -# Normalizar -PROJECT_NAME=$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g') -PROJECT_DIR="$TARGET_PATH/$PROJECT_NAME" - -# --- Check estado existente --- -if [[ -f "$PROJECT_DIR/package.json" ]] || [[ -f "$PROJECT_DIR/wails.json" ]]; then - log_warn "El proyecto $PROJECT_NAME ya existe en $PROJECT_DIR" - echo "STATUS: CONFIGURED" - exit 0 -fi - -# --- Verificar dependencias --- -log_step "Verificando dependencias..." - -if ! command -v pnpm &>/dev/null; then - log_error "pnpm no está instalado. Instala con: npm install -g pnpm" - echo "STATUS: ERROR" - exit 1 -fi -log_ok "pnpm $(pnpm --version) encontrado" - -if ! command -v node &>/dev/null; then - log_error "Node.js no encontrado" - echo "STATUS: ERROR" - exit 1 -fi -log_ok "Node $(node --version) encontrado" - -if [[ "$WAILS_MODE" == true ]]; then - if ! command -v wails &>/dev/null; then - log_error "Wails no está instalado. Instala con: go install github.com/wailsapp/wails/v2/cmd/wails@latest" - echo "STATUS: ERROR" - exit 1 - fi - log_ok "Wails $(wails version 2>/dev/null | head -1 || echo 'v2.x') encontrado" - - if ! command -v go &>/dev/null; then - log_error "Go no encontrado (requerido para Wails)" - echo "STATUS: ERROR" - exit 1 - fi - log_ok "Go $(go version | grep -oP '\d+\.\d+' | head -1) encontrado" -fi - -if [[ ! -d "$FRONTEND_LIB" ]]; then - log_warn "Frontend_Library no encontrada en $FRONTEND_LIB — se creará sin link" - HAS_FRONTEND_LIB=false -else - log_ok "Frontend_Library encontrada" - HAS_FRONTEND_LIB=true -fi - -# ============================================================================ -# MODO WAILS — Desktop app (Go + React) -# ============================================================================ -if [[ "$WAILS_MODE" == true ]]; then - log_step "Creando proyecto Wails '$PROJECT_NAME'..." - - # Usar wails init con template react-ts - wails init -n "$PROJECT_NAME" -t react-ts -d "$TARGET_PATH" 2>/dev/null - - cd "$PROJECT_DIR" - - # --- go.work con DevFactory --- - if [[ -d "$DEVFACTORY_PATH" ]]; then - log_step "Configurando go.work con DevFactory..." - cat > go.work << EOF -go 1.22 - -use ( - . - $DEVFACTORY_PATH -) -EOF - log_ok "DevFactory enlazado via go.work" - fi - - # --- Configurar frontend con pnpm --- - log_step "Configurando frontend con pnpm..." - cd frontend - - # Reemplazar npm por pnpm en wails.json - cd .. - if [[ -f "wails.json" ]]; then - sed -i 's/"npm install"/"pnpm install"/g' wails.json - sed -i 's/"npm run dev"/"pnpm dev"/g' wails.json - sed -i 's/"npm run build"/"pnpm build"/g' wails.json - fi - cd frontend - - # Instalar con pnpm - rm -f package-lock.json 2>/dev/null || true - pnpm install - - # --- Linkear Frontend_Library --- - if [[ "$HAS_FRONTEND_LIB" == true ]]; then - log_step "Linkeando Frontend_Library..." - pnpm add "@anthropic/frontend-lib@link:$FRONTEND_LIB" - log_ok "@anthropic/frontend-lib linkeada" - fi - - # --- Instalar Tailwind CSS 4 --- - log_step "Instalando Tailwind CSS 4..." - pnpm add -D tailwindcss @tailwindcss/vite - - # --- Configurar vite.config.ts con dedupe y tailwind --- - log_step "Configurando Vite (dedupe + tailwind)..." - cat > vite.config.ts << 'VEOF' -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' -import tailwindcss from '@tailwindcss/vite' -import { resolve } from 'path' - -export default defineConfig({ - plugins: [react(), tailwindcss()], - resolve: { - alias: { - '@': resolve(__dirname, './src'), - '@wails': resolve(__dirname, './wailsjs'), - }, - dedupe: ['react', 'react-dom'], - }, -}) -VEOF - - # --- CSS base con Tailwind --- - cat > src/style.css << 'CSSEOF' -@import "tailwindcss"; -CSSEOF - - # --- Instalar Phosphor Icons --- - pnpm add @phosphor-icons/react - - cd .. - - # --- Makefile (basado en build-wails agent) --- - log_step "Generando Makefile..." - cat > Makefile << 'MKEOF' -.PHONY: dev dev-debug build build-prod build-linux build-windows build-all clean generate doctor - -APP_NAME := $(shell basename $(CURDIR)) - -## dev: Desarrollo con hot reload -dev: - wails dev - -## dev-debug: Desarrollo con DevTools -dev-debug: - wails dev -devtools - -## build: Build para plataforma actual -build: - wails build - -## build-prod: Build optimizado para producción -build-prod: - wails build -clean -trimpath -ldflags="-s -w" - -## build-linux: Build para Linux AMD64 -build-linux: - wails build -platform linux/amd64 - -## build-windows: Cross-compile para Windows -build-windows: - wails build -platform windows/amd64 - -## build-all: Linux + Windows -build-all: build-linux build-windows - -## generate: Regenerar bindings TypeScript -generate: - wails generate module - -## clean: Limpiar artefactos -clean: - rm -rf build/bin frontend/dist - -## doctor: Verificar instalación -doctor: - wails doctor - -## help: Muestra esta ayuda -help: - @grep -E '^## ' Makefile | sed 's/## //' | column -t -s ':' -MKEOF - - # --- .gitignore --- - cat >> .gitignore << 'EOF' -node_modules/ -frontend/dist/ -build/bin/ -*.exe -EOF - - # --- Resumen Wails --- - echo "" - log_ok "Proyecto Wails '$PROJECT_NAME' creado en $PROJECT_DIR" - echo "" - echo -e "${CYAN}Estructura:${NC}" - echo " $PROJECT_NAME/" - echo " ├── main.go, app.go — Backend Go" - echo " ├── go.work — Enlace a DevFactory" - echo " ├── frontend/ — React + TypeScript + Vite" - echo " │ ├── src/ — Componentes React" - echo " │ └── wailsjs/ — Bindings auto-generados" - echo " ├── Makefile — dev, build, build-all" - echo " └── wails.json — Configuración Wails" - echo "" - echo -e "${CYAN}Comandos:${NC}" - echo " make dev — Desarrollo con hot reload" - echo " make build — Compilar app desktop" - echo " make build-all — Linux + Windows" - echo " make generate — Regenerar bindings TS" - echo "" - if [[ "$HAS_FRONTEND_LIB" == true ]]; then - echo -e "${CYAN}Frontend_Library:${NC}" - echo " import { Button, Card } from '@anthropic/frontend-lib'" - echo " import { useTheme } from '@anthropic/frontend-lib/hooks'" - echo "" - fi - echo "STATUS: READY" - exit 0 -fi - -# ============================================================================ -# MODO WEBAPP — React + Vite (sin Wails) -# ============================================================================ -log_step "Creando proyecto webapp '$PROJECT_NAME'..." - -mkdir -p "$PROJECT_DIR" -cd "$PROJECT_DIR" - -# --- Usar template de Frontend_Library si existe --- -if [[ -d "$TEMPLATES_DIR" ]]; then - log_step "Usando template de Frontend_Library..." - cp -r "$TEMPLATES_DIR"/* . - cp -r "$TEMPLATES_DIR"/.[!.]* . 2>/dev/null || true -else - log_step "Creando desde cero con Vite..." - - # package.json - cat > package.json << PKGEOF -{ - "name": "$PROJECT_NAME", - "private": true, - "version": "0.1.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "preview": "vite preview" - } -} -PKGEOF - - # Instalar dependencias base - pnpm add react react-dom - pnpm add -D typescript @types/react @types/react-dom - pnpm add -D vite @vitejs/plugin-react - pnpm add -D tailwindcss @tailwindcss/vite - - # tsconfig.json - cat > tsconfig.json << 'TSEOF' -{ - "compilerOptions": { - "target": "ES2023", - "lib": ["ES2023", "DOM", "DOM.Iterable"], - "module": "ESNext", - "moduleResolution": "bundler", - "jsx": "react-jsx", - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "paths": { "@/*": ["./src/*"] }, - "skipLibCheck": true - }, - "include": ["src"] -} -TSEOF - - # vite.config.ts - cat > vite.config.ts << 'VEOF' -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' -import tailwindcss from '@tailwindcss/vite' -import { resolve } from 'path' - -export default defineConfig({ - plugins: [react(), tailwindcss()], - resolve: { - alias: { '@': resolve(__dirname, './src') }, - dedupe: ['react', 'react-dom'], - }, -}) -VEOF - - # index.html - cat > index.html << HTMLEOF - - - - - - $PROJECT_NAME - - -
- - - -HTMLEOF - - # src/ - mkdir -p src - - cat > src/main.tsx << 'TSXEOF' -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import App from './App' -import './app.css' - -createRoot(document.getElementById('root')!).render( - - - , -) -TSXEOF - - cat > src/App.tsx << 'TSXEOF' -function App() { - return ( -
-

Ready

-
- ) -} - -export default App -TSXEOF - - cat > src/app.css << 'CSSEOF' -@import "tailwindcss"; -CSSEOF -fi - -# --- Linkear Frontend_Library --- -if [[ "$HAS_FRONTEND_LIB" == true ]]; then - log_step "Linkeando Frontend_Library..." - pnpm add "@anthropic/frontend-lib@link:$FRONTEND_LIB" - log_ok "@anthropic/frontend-lib linkeada" -fi - -# --- Phosphor Icons --- -pnpm add @phosphor-icons/react - -# --- .gitignore --- -cat > .gitignore << 'EOF' -node_modules/ -dist/ -.vite/ -*.local -EOF - -# --- Resumen Webapp --- -echo "" -log_ok "Proyecto webapp '$PROJECT_NAME' creado en $PROJECT_DIR" -echo "" -echo -e "${CYAN}Estructura:${NC}" -echo " $PROJECT_NAME/" -echo " ├── src/" -echo " │ ├── App.tsx — Componente principal" -echo " │ ├── main.tsx — Entry point" -echo " │ └── app.css — Tailwind CSS" -echo " ├── vite.config.ts — Vite + Tailwind + dedupe" -echo " ├── tsconfig.json — TypeScript strict" -echo " └── package.json — pnpm" -echo "" -echo -e "${CYAN}Comandos:${NC}" -echo " pnpm dev — Servidor de desarrollo" -echo " pnpm build — Build de producción" -echo " pnpm preview — Preview del build" -echo "" -if [[ "$HAS_FRONTEND_LIB" == true ]]; then - echo -e "${CYAN}Frontend_Library:${NC}" - echo " import { Button, Card } from '@anthropic/frontend-lib'" - echo " import { useTheme } from '@anthropic/frontend-lib/hooks'" - echo "" -fi -echo "STATUS: READY" diff --git a/.claude/skills/init-go-module/SKILL.md b/.claude/skills/init-go-module/SKILL.md deleted file mode 100644 index 4228712..0000000 --- a/.claude/skills/init-go-module/SKILL.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -name: init-go-module -description: Inicializa un módulo Go funcional con bindings Python (CGO c-shared + ctypes) -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit ---- - -# init-go-module - -Inicializa un módulo Go con arquitectura funcional (pure core / impure shell) y bindings Python automáticos via CGO c-shared + ctypes. Coherente con DevFactory y el stack del backend-lib agent. - -## Sintaxis - -```bash -/init-go-module [nombre] [--path /ruta/destino] -``` - -- `nombre`: nombre del módulo (kebab-case). Si no se da, se pregunta. -- `--path`: directorio destino. Default: directorio actual. - -## Flujo - -### 1. Ejecutar script de setup - -```bash -bash "${CLAUDE_SKILL_DIR}/setup-go-module.sh" [nombre] [path] -``` - -### 2. Si el script reporta STATUS: CONFIGURED - -Informar al usuario que el módulo ya está configurado. - -### 3. Si el script reporta STATUS: READY - -Mostrar resumen: -- Estructura creada -- Cómo compilar: `make build` -- Cómo generar bindings Python: `make python` -- Cómo testear: `make test` -- Cómo usar desde Python: `from bindings.modulo import *` - -### 4. Si el script reporta STATUS: ERROR - -Mostrar el error y sugerir corrección. - -## Convenciones - -- Usa DevFactory como dependencia via `go.work` (igual que build-wails) -- Patrón pure core / impure shell de DevFactory -- `Result[T]` y `Option[T]` del core de DevFactory -- Funciones exportadas a Python son thin wrappers en `export/` -- El wrapper Python se auto-genera desde los `//export` comments diff --git a/.claude/skills/init-go-module/setup-go-module.sh b/.claude/skills/init-go-module/setup-go-module.sh deleted file mode 100755 index f80f21b..0000000 --- a/.claude/skills/init-go-module/setup-go-module.sh +++ /dev/null @@ -1,466 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# ============================================================================= -# setup-go-module.sh — Inicializa módulo Go funcional con bindings Python -# Coherente con DevFactory (pure core / impure shell) + CGO c-shared + ctypes -# ============================================================================= - -# --- Colores --- -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' - -log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } -log_ok() { echo -e "${GREEN}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } -log_step() { echo -e "${CYAN}[STEP]${NC} $1"; } - -# --- Parámetros --- -MODULE_NAME="${1:-}" -TARGET_PATH="${2:-.}" -DEVFACTORY_PATH="$HOME/.local_agentes/backend" -DEVFACTORY_MODULE="github.com/lucasdataproyects/devfactory" - -# --- Validar nombre --- -if [[ -z "$MODULE_NAME" ]]; then - log_error "Uso: setup-go-module.sh [path]" - echo "STATUS: ERROR" - exit 1 -fi - -# Normalizar nombre a kebab-case -MODULE_NAME=$(echo "$MODULE_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g') -PROJECT_DIR="$TARGET_PATH/$MODULE_NAME" - -# --- Check estado existente --- -if [[ -f "$PROJECT_DIR/go.mod" ]]; then - log_warn "El módulo $MODULE_NAME ya existe en $PROJECT_DIR" - if [[ -f "$PROJECT_DIR/export/exports.go" ]]; then - log_ok "Bindings Python ya configurados" - else - log_warn "Falta directorio export/ — ejecuta de nuevo para completar" - fi - echo "STATUS: CONFIGURED" - exit 0 -fi - -# --- Verificar dependencias --- -log_step "Verificando dependencias..." - -if ! command -v go &>/dev/null; then - log_error "Go no está instalado. Instala Go 1.22+" - echo "STATUS: ERROR" - exit 1 -fi - -GO_VERSION=$(go version | grep -oP '\d+\.\d+' | head -1) -log_ok "Go $GO_VERSION encontrado" - -if ! command -v python3 &>/dev/null; then - log_warn "Python3 no encontrado — los bindings se generarán pero no se podrán testear" -fi - -if [[ ! -d "$DEVFACTORY_PATH" ]]; then - log_warn "DevFactory no encontrado en $DEVFACTORY_PATH — se creará go.mod sin go.work" -fi - -# --- Crear estructura --- -log_step "Creando estructura del módulo '$MODULE_NAME'..." - -mkdir -p "$PROJECT_DIR"/{core,shell,export,python/bindings,cmd,internal} - -# --- go.mod --- -log_step "Generando go.mod..." -cat > "$PROJECT_DIR/go.mod" << EOF -module github.com/lucasdataproyects/$MODULE_NAME - -go 1.22 - -require $DEVFACTORY_MODULE v0.0.0 -EOF - -# --- go.work (si DevFactory existe localmente) --- -if [[ -d "$DEVFACTORY_PATH" ]]; then - log_step "Generando go.work con DevFactory local..." - cat > "$PROJECT_DIR/go.work" << EOF -go 1.22 - -use ( - . - $DEVFACTORY_PATH -) -EOF - log_ok "go.work enlazado a DevFactory" -fi - -# --- core/transform.go — Funciones puras de ejemplo --- -log_step "Generando core/ (funciones puras)..." -cat > "$PROJECT_DIR/core/transform.go" << 'GOEOF' -// Package core contiene funciones puras sin side effects. -// Todas las funciones son deterministas y composables. -package core - -import ( - "strings" - - "errors" - - df "github.com/lucasdataproyects/devfactory/core" -) - -// ToUpper transforma texto a mayúsculas (función pura). -func ToUpper(s string) string { - return strings.ToUpper(s) -} - -// ProcessItems aplica una transformación a cada elemento usando MapSlice de DevFactory. -func ProcessItems(items []string, transform func(string) string) []string { - return df.MapSlice(items, transform) -} - -// FilterNonEmpty filtra elementos vacíos usando FilterSlice de DevFactory. -func FilterNonEmpty(items []string) []string { - return df.FilterSlice(items, func(s string) bool { - return len(strings.TrimSpace(s)) > 0 - }) -} - -// SafeDivide retorna Result[float64] para evitar panic en división por cero. -func SafeDivide(a, b float64) df.Result[float64] { - if b == 0 { - return df.Err[float64](errors.New("division by zero")) - } - return df.Ok(a / b) -} -GOEOF - -# --- core/types.go — Tipos exportables a Python --- -cat > "$PROJECT_DIR/core/types.go" << 'GOEOF' -package core - -// DataPoint representa un punto de datos exportable a Python. -// Los campos usan tipos C-compatible para facilitar el binding. -type DataPoint struct { - Label string - Value float64 -} - -// Summary es el resultado de un procesamiento, exportable a Python. -type Summary struct { - Count int - Total float64 - Items []string -} -GOEOF - -# --- shell/io.go — Operaciones I/O con Result[T] --- -log_step "Generando shell/ (operaciones I/O)..." -cat > "$PROJECT_DIR/shell/io.go" << 'GOEOF' -// Package shell contiene operaciones con side effects, wrapeadas en Result[T]. -package shell - -import ( - df "github.com/lucasdataproyects/devfactory/core" - "github.com/lucasdataproyects/devfactory/shell" -) - -// ReadDataFile lee un archivo y retorna su contenido como Result. -func ReadDataFile(path string) df.Result[string] { - return shell.ReadString(path) -} - -// WriteResult escribe un resultado a archivo. -func WriteResult(path string, content string) df.Result[struct{}] { - return shell.WriteString(path, content) -} -GOEOF - -# --- export/exports.go — Funciones exportadas via CGO --- -log_step "Generando export/ (bindings CGO)..." -cat > "$PROJECT_DIR/export/exports.go" << GOEOF -// Package main exporta funciones Go como C shared library. -// Cada función con //export se expone como símbolo C callable desde Python. -package main - -import "C" -import ( - "encoding/json" - "unsafe" - - "github.com/lucasdataproyects/$MODULE_NAME/core" -) - -//export GoToUpper -func GoToUpper(input *C.char) *C.char { - result := core.ToUpper(C.GoString(input)) - return C.CString(result) -} - -//export GoProcessItems -func GoProcessItems(jsonInput *C.char) *C.char { - var items []string - if err := json.Unmarshal([]byte(C.GoString(jsonInput)), &items); err != nil { - return C.CString("[]") - } - result := core.ProcessItems(items, core.ToUpper) - out, _ := json.Marshal(result) - return C.CString(string(out)) -} - -//export GoFilterNonEmpty -func GoFilterNonEmpty(jsonInput *C.char) *C.char { - var items []string - if err := json.Unmarshal([]byte(C.GoString(jsonInput)), &items); err != nil { - return C.CString("[]") - } - result := core.FilterNonEmpty(items) - out, _ := json.Marshal(result) - return C.CString(string(out)) -} - -//export GoSafeDivide -func GoSafeDivide(a, b C.double) *C.char { - result := core.SafeDivide(float64(a), float64(b)) - if result.IsErr() { - return C.CString(`{"error":"` + result.Error().Error() + `"}`) - } - out, _ := json.Marshal(map[string]float64{"value": result.Unwrap()}) - return C.CString(string(out)) -} - -//export GoFree -func GoFree(ptr *C.char) { - C.free(unsafe.Pointer(ptr)) -} - -func main() {} -GOEOF - -# --- python/bindings/__init__.py — Wrapper ctypes auto-generado --- -log_step "Generando python/bindings/ (ctypes wrapper)..." - -# Nombre de la shared library según OS -SO_NAME="lib${MODULE_NAME}.so" - -cat > "$PROJECT_DIR/python/bindings/__init__.py" << PYEOF -""" -Auto-generated Python bindings for $MODULE_NAME. -Uses ctypes to call Go functions compiled as C shared library. - -Usage: - from bindings import to_upper, process_items, filter_non_empty, safe_divide -""" -import ctypes -import json -import os -from pathlib import Path - -# Localizar la shared library -_LIB_DIR = Path(__file__).parent.parent.parent / "build" -_LIB_NAME = "$SO_NAME" -_LIB_PATH = _LIB_DIR / _LIB_NAME - -if not _LIB_PATH.exists(): - raise FileNotFoundError( - f"Shared library not found at {_LIB_PATH}. " - f"Run 'make build' in the project root first." - ) - -_lib = ctypes.CDLL(str(_LIB_PATH)) - -# --- Configurar tipos de retorno --- -_lib.GoToUpper.argtypes = [ctypes.c_char_p] -_lib.GoToUpper.restype = ctypes.c_char_p - -_lib.GoProcessItems.argtypes = [ctypes.c_char_p] -_lib.GoProcessItems.restype = ctypes.c_char_p - -_lib.GoFilterNonEmpty.argtypes = [ctypes.c_char_p] -_lib.GoFilterNonEmpty.restype = ctypes.c_char_p - -_lib.GoSafeDivide.argtypes = [ctypes.c_double, ctypes.c_double] -_lib.GoSafeDivide.restype = ctypes.c_char_p - -_lib.GoFree.argtypes = [ctypes.c_char_p] -_lib.GoFree.restype = None - - -def to_upper(text: str) -> str: - """Convert text to uppercase using Go core.""" - result = _lib.GoToUpper(text.encode("utf-8")) - return result.decode("utf-8") - - -def process_items(items: list[str]) -> list[str]: - """Process items through Go pipeline (ToUpper transformation).""" - input_json = json.dumps(items).encode("utf-8") - result = _lib.GoProcessItems(input_json) - return json.loads(result.decode("utf-8")) - - -def filter_non_empty(items: list[str]) -> list[str]: - """Filter empty strings using Go core.""" - input_json = json.dumps(items).encode("utf-8") - result = _lib.GoFilterNonEmpty(input_json) - return json.loads(result.decode("utf-8")) - - -def safe_divide(a: float, b: float) -> float: - """Safe division using Go Result type. Raises ValueError on division by zero.""" - result = _lib.GoSafeDivide(ctypes.c_double(a), ctypes.c_double(b)) - data = json.loads(result.decode("utf-8")) - if "error" in data: - raise ValueError(data["error"]) - return data["value"] -PYEOF - -# --- python/example.py --- -cat > "$PROJECT_DIR/python/example.py" << PYEOF -"""Example usage of $MODULE_NAME Go bindings from Python.""" -from bindings import to_upper, process_items, filter_non_empty, safe_divide - -# String transformation -print(to_upper("hello from go")) # HELLO FROM GO - -# Batch processing via Go's MapSlice -items = ["hello", "world", "from", "go"] -print(process_items(items)) # ["HELLO", "WORLD", "FROM", "GO"] - -# Filtering via Go's FilterSlice -mixed = ["hello", "", "world", " ", "go"] -print(filter_non_empty(mixed)) # ["hello", "world", "go"] - -# Safe division with Result[T] error handling -print(safe_divide(10.0, 3.0)) # 3.333... -try: - safe_divide(10.0, 0.0) -except ValueError as e: - print(f"Caught: {e}") # Caught: division by zero -PYEOF - -# --- core/transform_test.go --- -log_step "Generando tests..." -cat > "$PROJECT_DIR/core/transform_test.go" << 'GOEOF' -package core - -import ( - "testing" -) - -func TestToUpper(t *testing.T) { - if got := ToUpper("hello"); got != "HELLO" { - t.Errorf("ToUpper(\"hello\") = %q, want %q", got, "HELLO") - } -} - -func TestFilterNonEmpty(t *testing.T) { - items := []string{"hello", "", "world", " ", "go"} - result := FilterNonEmpty(items) - if len(result) != 3 { - t.Errorf("FilterNonEmpty got %d items, want 3", len(result)) - } -} - -func TestSafeDivide(t *testing.T) { - ok := SafeDivide(10, 2) - if ok.IsErr() { - t.Error("SafeDivide(10, 2) should not error") - } - if ok.Unwrap() != 5.0 { - t.Errorf("SafeDivide(10, 2) = %f, want 5.0", ok.Unwrap()) - } - - err := SafeDivide(10, 0) - if !err.IsErr() { - t.Error("SafeDivide(10, 0) should error") - } -} -GOEOF - -# --- Makefile --- -log_step "Generando Makefile..." -cat > "$PROJECT_DIR/Makefile" << MKEOF -.PHONY: build test clean python dev - -MODULE_NAME := $MODULE_NAME -BUILD_DIR := build -SO_NAME := $SO_NAME - -## build: Compila la shared library (.so) para Python -build: - @mkdir -p \$(BUILD_DIR) - cd export && CGO_ENABLED=1 go build -buildmode=c-shared -o ../\$(BUILD_DIR)/\$(SO_NAME) . - @echo "✓ Built \$(BUILD_DIR)/\$(SO_NAME)" - -## test: Ejecuta tests de Go -test: - go test ./core/... ./shell/... -v - -## python: Compila y ejecuta ejemplo Python -python: build - cd python && python3 example.py - -## clean: Limpia artefactos -clean: - rm -rf \$(BUILD_DIR) - find . -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true - -## dev: Tests + build en un paso -dev: test build - @echo "✓ Ready — run 'make python' to test bindings" - -## tidy: go mod tidy -tidy: - go mod tidy - -## help: Muestra esta ayuda -help: - @grep -E '^## ' Makefile | sed 's/## //' | column -t -s ':' -MKEOF - -# --- .gitignore --- -cat > "$PROJECT_DIR/.gitignore" << 'EOF' -build/ -*.so -*.h -*.dylib -*.dll -__pycache__/ -*.pyc -.pytest_cache/ -EOF - -# --- go mod tidy --- -log_step "Ejecutando go mod tidy..." -cd "$PROJECT_DIR" -if [[ -f "go.work" ]]; then - go mod tidy 2>/dev/null || log_warn "go mod tidy falló — revisa el go.work" -else - go mod tidy 2>/dev/null || log_warn "go mod tidy falló — DevFactory no está disponible" -fi - -# --- Resumen --- -echo "" -log_ok "Módulo '$MODULE_NAME' creado en $PROJECT_DIR" -echo "" -echo -e "${CYAN}Estructura:${NC}" -echo " $MODULE_NAME/" -echo " ├── core/ — Funciones puras (sin side effects)" -echo " ├── shell/ — Operaciones I/O con Result[T]" -echo " ├── export/ — Funciones exportadas via CGO" -echo " ├── python/bindings — Wrapper ctypes auto-generado" -echo " ├── Makefile — build, test, python, clean" -echo " └── go.work — Enlace a DevFactory" -echo "" -echo -e "${CYAN}Comandos:${NC}" -echo " make test — Ejecutar tests Go" -echo " make build — Compilar shared library" -echo " make python — Testear bindings Python" -echo " make dev — Test + build en un paso" -echo "" -echo "STATUS: READY" diff --git a/.claude/skills/issues-status/SKILL.md b/.claude/skills/issues-status/SKILL.md deleted file mode 100644 index a993f05..0000000 --- a/.claude/skills/issues-status/SKILL.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: issues-status -description: Dashboard global de issues en todos los workspaces con métricas y filtros -argument-hint: [workspace] [--status pending] [--tag tag] [--export json|csv] -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read ---- - -# issues-status - -Muestra dashboard global de todas las issues con métricas, filtros y sugerencias. - -## Sintaxis - -```bash -/issues-status # Dashboard global -/issues-status # Detalle de workspace -/issues-status --status pending # Filtrar por estado -/issues-status --tag backend # Filtrar por tag -/issues-status --export json # Exportar -``` - -## Flujo - -### 1. Parsear argumentos - -- Primer arg (sin --): `filterWorkspace` -- `--status `: pending | in_progress | completed -- `--tag `: filtrar por tag -- `--export `: json | csv - -### 2. Ejecutar dashboard - -Llama `app.IssuesDashboardCommand(config, filterWorkspace, filterStatus, filterTag, exportFormat)` - -### 3. Modo interactivo (dashboard global) - -Si no hay filtros: -1. Mostrar dashboard con sugerencias -2. Preguntar: "¿Ver detalle de un workspace? (nombre o 'n')" -3. Si responde nombre: mostrar detalle -4. Si responde 'n': terminar - -### Comandos sugeridos - -``` -Commands: - /issues-status - /issues-status --status pending - /fix-issue -``` - -## Manejo de errores - -- Si no hay workspaces: sugerir crear o sincronizar -- Si no hay issues: mostrar dashboard vacío con sugerencias diff --git a/.claude/skills/parallel-issues/SKILL.md b/.claude/skills/parallel-issues/SKILL.md deleted file mode 100644 index 5eec335..0000000 --- a/.claude/skills/parallel-issues/SKILL.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -name: parallel-issues -description: Analiza issues y genera plan de ejecución paralela en PARALLEL_EXECUTION_ORDER.md -argument-hint: [--dry-run] -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write ---- - -# parallel-issues - -Analiza issues pendientes y genera plan de ejecución paralela agrupando issues independientes. - -## Sintaxis - -```bash -/parallel-issues # Genera archivo -/parallel-issues --dry-run # Solo muestra análisis -``` - -## Cuándo usar - -- Identificar issues paralelizables sin conflictos -- Planificar desarrollo con múltiples worktrees -- Antes de sesiones intensivas de desarrollo - -## Flujo - -### 1. Detectar contexto - -```bash -# Proyecto padre o hijo? -if [[ "$PWD" == *"/workspaces/"* ]]; then - PROJECT_TYPE="child" -else - PROJECT_TYPE="parent" -fi -``` - -### 2. Listar issues pendientes - -```bash -ls -1 dev/issues/*.md | grep -E '[0-9]{4}-.*\.md$' | sort -``` - -Para cada issue extraer: -- Número, título, estado -- Archivos mencionados -- Dependencias explícitas (#NNNN) - -### 3. Analizar conflictos - -**Criterios de conflicto (NO paralelizables):** -- Archivos compartidos -- Dependencias explícitas -- Dependencias transitivas - -### 4. Agrupar por independencia - -Algoritmo de grafos: -- Grupo 1: Issues sin dependencias -- Grupo 2: Issues que dependen solo de Grupo 1 -- etc. - -### 5. Estimar tiempos - -Factores: -- Cantidad de archivos -- Capa afectada (core/shell/app) -- Palabras clave (refactor, fix, nuevo) - -### 6. Generar PARALLEL_EXECUTION_ORDER.md - -```markdown -# Plan de Ejecución Paralela - -## Grupo 1: Issues Independientes -- Issue #0003 - ... -- Issue #0006 - ... - -## Grupo 2: Dependientes de Grupo 1 -- Issue #0004 - depende de #0003 - -## Resumen -| Métrica | Valor | -|---------|-------| -| Ahorro tiempo | 60% | -``` - -### 7. Mostrar resultado - -``` -Plan generado: PARALLEL_EXECUTION_ORDER.md - -Issues analizadas: N -Grupos paralelos: M -Ahorro estimado: X% -``` - -## Convenciones - -- Nombres de grupo: "Grupo N" -- Worktrees: `worktrees/issue-NNNN` -- Estimación en horas (redondeado a .5) diff --git a/.claude/skills/quick-issue/SKILL.md b/.claude/skills/quick-issue/SKILL.md deleted file mode 100644 index 228af3b..0000000 --- a/.claude/skills/quick-issue/SKILL.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -name: quick-issue -description: Crea un issue automáticamente desde TUI con detección automática de número -argument-hint: --text "descripción" -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write, Edit ---- - -# quick-issue - -Crea un issue rápido desde TUI. **No invocar manualmente** - es para uso automático. - -## Sintaxis - -```bash -/quick-issue --text "descripción del issue" -``` - -## Precondiciones - -- [ ] Directorio `dev/issues/` existe -- [ ] Parámetro `--text` proporcionado -- [ ] Working tree limpio - -## Flujo - -### 1. Determinar número - -```bash -ls -1 dev/issues/*.md | grep -E '^dev/issues/[0-9]{4}[a-z]?-' | sort -V -``` - -Siguiente = último número base + 1 (ignorar letras). - -### 2. Generar título y slug - -- Título: usar `--text` directamente -- Slug: convertir a kebab-case - -### 3. Crear archivo de issue - -Template minimalista con: -- Metadata básica -- Objetivo = texto del parámetro -- Tareas a completar con /fix-issue - -### 4. Actualizar índice - -Agregar línea en `dev/issues/README.md`. - -### 5. Crear commits y mergear (sin confirmación) - -```bash -git checkout -b quick/quick-issue-NNNN -git add dev/issues/NNNN-slug.md dev/issues/README.md -git commit -m "docs: crear issue NNNN-slug" -git checkout master -git merge --no-ff quick/quick-issue-NNNN -git push -git branch -d quick/quick-issue-NNNN -``` - -### 6. Reportar resultado - -``` -Issue NNNN-slug creado e integrado - -Para implementar: - /fix-issue NNNN -``` - -## Convenciones - -- Auto-detección de número -- Sin confirmación (flujo automático) -- Template minimalista diff --git a/.claude/skills/sort-issues/SKILL.md b/.claude/skills/sort-issues/SKILL.md deleted file mode 100644 index 4b60c57..0000000 --- a/.claude/skills/sort-issues/SKILL.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -name: sort-issues -description: Analiza dependencias y genera orden de ejecución óptimo de issues -disable-model-invocation: true -user-invocable: true -allowed-tools: Bash, Read, Write ---- - -# sort-issues - -Analiza issues, construye grafo de dependencias y muestra/genera orden de ejecución recomendado. - -## Sintaxis - -```bash -/sort-issues -``` - -## Flujo - -### 1. Listar issues pendientes - -```bash -ls dev/issues/*.md | grep -E '^dev/issues/[0-9]{4}[a-z]?-.*\.md$' | sort -``` - -### 2. Extraer dependencias de cada issue - -Buscar: -- Tabla "## Dependencias" -- Línea "Bloqueada por" -- Referencias #NNNN - -### 3. Construir grafo y detectar ciclos - -Si hay ciclos: -``` -Dependencias circulares detectadas: - 0010 → 0011 → 0012 → 0010 - -Revisar: -- dev/issues/0010-*.md -- dev/issues/0011-*.md -``` - -### 4. Calcular orden topológico - -Algoritmo Kahn o DFS post-order. - -Desempate: -1. Número menor primero -2. Issues sin deps primero - -### 5. Generar EXECUTION_ORDER.md - -```markdown -# Execution Order - -## Recommended Order -1. #0001 - titulo — razón -2. #0002 - titulo — razón - -## Critical Path -- #0001 → #0002, #0003 - -## Parallelizable Groups -### Group 1 (after #0001) -- #0002 -- #0003 -``` - -### 6. Mostrar resultado - -``` -Orden generado: dev/EXECUTION_ORDER.md - -Issues: N -Camino crítico: #X → #Y → #Z -Grupos paralelos: M - -Próxima issue: #0001 - titulo -``` - -## Convenciones - -- Solo leer issues (no modificar) -- Detectar ambos formatos de dependencias -- Reportar ciclos claramente