Agent skill
scaffold-rene-kuhm-opencode-ohmyopencod
Crear componentes, páginas, hooks y servicios con estructura enterprise. Scaffolding automático.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/scaffold-rene-kuhm-opencode-ohmyopencod
SKILL.md
Scaffold Skill
Genera código boilerplate siguiendo las mejores prácticas y la estructura del proyecto.
Tipos de Scaffold
1. Component
/scaffold component Button
/scaffold component UserCard --path src/components/features/
Genera:
src/components/ui/Button/
├── Button.tsx
├── Button.test.tsx
├── Button.types.ts
└── index.ts
Template Component:
// Button.tsx
import { type ButtonProps } from './Button.types';
import { cn } from '@/lib/utils';
export function Button({
variant = 'primary',
size = 'md',
disabled = false,
className,
children,
...props
}: ButtonProps) {
return (
<button
className={cn(
'inline-flex items-center justify-center rounded-md font-medium',
variants[variant],
sizes[size],
disabled && 'opacity-50 cursor-not-allowed',
className
)}
disabled={disabled}
{...props}
>
{children}
</button>
);
}
Template Types:
// Button.types.ts
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
}
Template Test:
// Button.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Button } from './Button';
describe('Button', () => {
it('should render children', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('should handle click events', async () => {
const onClick = vi.fn();
render(<Button onClick={onClick}>Click</Button>);
await userEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
it('should be disabled when disabled prop is true', () => {
render(<Button disabled>Click</Button>);
expect(screen.getByRole('button')).toBeDisabled();
});
});
2. Page (Next.js App Router)
/scaffold page dashboard
/scaffold page settings/profile
Genera:
src/app/dashboard/
├── page.tsx
├── loading.tsx
├── error.tsx
└── layout.tsx (opcional)
Template Page:
// page.tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Dashboard',
description: 'User dashboard',
};
export default async function DashboardPage() {
return (
<main className="container mx-auto py-8">
<h1 className="text-3xl font-bold">Dashboard</h1>
{/* Content */}
</main>
);
}
3. Hook
/scaffold hook useAuth
/scaffold hook useProducts
Genera:
src/hooks/
├── use-auth.ts
└── use-auth.test.ts
Template Hook:
// use-auth.ts
import { useState, useEffect, useCallback } from 'react';
interface UseAuthOptions {
redirectTo?: string;
}
interface UseAuthReturn {
user: User | null;
isLoading: boolean;
isAuthenticated: boolean;
login: (credentials: Credentials) => Promise<void>;
logout: () => Promise<void>;
}
export function useAuth(options: UseAuthOptions = {}): UseAuthReturn {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// Check auth status on mount
checkAuth().then(setUser).finally(() => setIsLoading(false));
}, []);
const login = useCallback(async (credentials: Credentials) => {
const user = await authService.login(credentials);
setUser(user);
}, []);
const logout = useCallback(async () => {
await authService.logout();
setUser(null);
}, []);
return {
user,
isLoading,
isAuthenticated: !!user,
login,
logout,
};
}
4. Service
/scaffold service user
/scaffold service payment
Genera:
src/services/
├── user.service.ts
└── user.service.test.ts
Template Service:
// user.service.ts
import { prisma } from '@/lib/prisma';
import { z } from 'zod';
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
});
type CreateUserInput = z.infer<typeof CreateUserSchema>;
export class UserService {
async findById(id: string) {
return prisma.user.findUnique({ where: { id } });
}
async findByEmail(email: string) {
return prisma.user.findUnique({ where: { email } });
}
async create(input: CreateUserInput) {
const data = CreateUserSchema.parse(input);
return prisma.user.create({ data });
}
async update(id: string, input: Partial<CreateUserInput>) {
return prisma.user.update({
where: { id },
data: input,
});
}
async delete(id: string) {
return prisma.user.delete({ where: { id } });
}
}
export const userService = new UserService();
5. API Route
/scaffold api users
/scaffold api products/[id]
Genera:
src/app/api/users/
└── route.ts
Template API:
// route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { userService } from '@/services/user.service';
const CreateSchema = z.object({
email: z.string().email(),
name: z.string().min(2),
});
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get('page') || '1');
const limit = parseInt(searchParams.get('limit') || '20');
const users = await userService.findMany({ page, limit });
return NextResponse.json({ data: users });
} catch (error) {
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const data = CreateSchema.parse(body);
const user = await userService.create(data);
return NextResponse.json({ data: user }, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ error: 'Validation failed', details: error.errors },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
Proceso
- Detectar estructura del proyecto
- Verificar si ya existe el archivo
- Crear archivos con templates
- Actualizar barrel exports (index.ts)
- Mostrar archivos creados
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?