Files
repo_Claude/.claude/skills/init-frontend/setup-frontend.sh
T
egutierrez c36aa18c67 feat: añadir skills create-tui, init-frontend, init-go-module y utilidades
Nuevas skills para crear TUIs, inicializar frontends React y módulos Go.
Incluye binario parallel-executor y utilidades de soporte.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 02:15:34 +01:00

439 lines
12 KiB
Bash
Executable File

#!/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 <nombre> [--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
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>$PROJECT_NAME</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
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(
<StrictMode>
<App />
</StrictMode>,
)
TSXEOF
cat > src/App.tsx << 'TSXEOF'
function App() {
return (
<div className="min-h-screen bg-surface text-foreground flex items-center justify-center">
<h1 className="text-3xl font-bold">Ready</h1>
</div>
)
}
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"